Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 184 additions & 0 deletions docs/reference/nostr-java-api.md
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)
Copy link

Copilot AI Aug 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sign method documentation suggests it returns a NostrIF but 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.

Copilot uses AI. Check for mistakes.
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
Copy link

Copilot AI Aug 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example uses pubKey variable that is not defined in the code block. This will cause a compilation error. Either define the variable or use a placeholder like somePublicKey.

Suggested change
```java
```java
PublicKey pubKey = id.getPublicKey();

Copilot uses AI. Check for mistakes.
Filters filters = new Filters(new AuthorFilter(pubKey));
NostrIF client = NostrSpringWebSocketClient.getInstance(id);
List<String> events = client.sendRequest(filters, "sub-id");
Copy link

Copilot AI Aug 19, 2025

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'.

Suggested change
List<String> events = client.sendRequest(filters, "sub-id");
List<String> requestIds = client.sendRequest(filters, "sub-id");

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Aug 19, 2025

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).

Suggested change
List<String> events = client.sendRequest(filters, "sub-id");
List<String> events = client.sendRequest(List.of(filters), "sub-id");

Copilot uses AI. Check for mistakes.
```

---
This reference is a starting point; consult the source for complete details and additional NIP helpers.