Skip to content
Merged
Show file tree
Hide file tree
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
103 changes: 16 additions & 87 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,126 +1,55 @@
# nostr-java
[![](https://jitpack.io/v/xyz.tcheeric/nostr-java.svg)](https://jitpack.io/#xyz.tcheeric/nostr-java)

Nostr-java is a library for generating, signing, and publishing nostr events to relays.
It provides helper methods such as `requireTag` and `requireTagInstance` on `GenericEvent` to assert required tags are present.
`nostr-java` is a Java SDK for the [Nostr](https://github.com/nostr-protocol/nips) protocol. It provides utilities for creating, signing and publishing Nostr events to relays.

## Requirements
- Maven
- Java 21+

## Usage
### To use nostr-java in your project, two options:

#### Option 1 - add release version and jitpack.io repository to your pom.xml file
## Getting Started
### Using JitPack
Add the dependency and repository to your `pom.xml`:

```xml
<properties>
<nostr-java.version>v0.007.2-alpha</nostr-java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
```

```xml
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
```
#### Option 2 - Check out and build project directly from source

```bash
$ cd <your_git_home_dir>
$ git clone git@github.com:tcheeric/nostr-java.git
$ cd nostr-java
$ git checkout <your_chosen_branch>
```

<details>
<summary>unit-tested build (does not require a nostr-relay for testing)</summary>

###### maven
(unix)
$ ./mvnw clean test
$ ./mvnw install -Dmaven.test.skip=true

(windows)
$ ./mvnw.cmd clean test
$ ./mvnw.cmd install -Dmaven.test.skip=true


###### gradle

(unix)
$ ./gradlew clean test
$ ./gradlew publishToMavenLocal

(windows)
$ ./gradlew.bat clean test
$ ./gradlew.bat publishToMavenLocal
</details>

<details>
<summary>integration-tested build (requires Docker)</summary>

Integration tests automatically start a `nostr-rs-relay` container using [Testcontainers](https://testcontainers.com/). Ensure Docker is installed and running before executing the build. The relay image can be overridden in `src/test/resources/relay-container.properties`.
Specify your own container image by setting `relay.container.image=<image>` in that file.

###### maven
(unix)
$ ./mvnw clean install

(windows)
$ ./mvnw.cmd clean install

###### gradle
(unix)
$ ./gradlew clean check
$ ./gradlew publishToMavenLocal

(windows)
$ ./gradlew.bat clean check
$ ./gradlew.bat publishToMavenLocal
</details>

#### add dependency to your pom.xml

```xml
<dependencies>
<dependency>
<dependency>
<groupId>nostr-java</groupId>
<artifactId>nostr-java-api</artifactId>
<version>${nostr-java.version}</version>
</dependency>
</dependencies>
```

### Configuring WebSocket client
`StandardWebSocketClient` awaits responses from the relay when sending messages.
The wait duration and polling interval can be customized using the following
properties (values in milliseconds):
### Building from source
Clone the repository and build the modules:

```bash
$ git clone https://github.com/tcheeric/nostr-java.git
$ cd nostr-java
$ ./mvnw clean install
```
nostr.websocket.await-timeout-ms=60000
nostr.websocket.poll-interval-ms=500
```
By default the client waits up to 60 seconds with a poll interval of 500&nbsp;ms.

## Examples
I recommend having a look at these repositories/module for examples:
- [nostr-example](https://github.com/tcheeric/nostr-java/tree/main/nostr-java-examples) module
- [nostr-client](https://github.com/tcheeric/nostr-client) github repository
- [SuperConductor](https://github.com/avlo/superconductor) nostr relay
See [`docs/CODEBASE_OVERVIEW.md`](docs/CODEBASE_OVERVIEW.md) for details about running tests and contributing.

### Event validation
Every concrete event now verifies that its `kind` matches the expected value from
the `Kind` enum. Calling `validate()` on an event with an incorrect `kind` will
throw an `AssertionError`.
## Examples
Example usages are located in the [`nostr-java-examples`](./nostr-java-examples) module. Additional demonstrations can be found in [nostr-client](https://github.com/tcheeric/nostr-client) and [SuperConductor](https://github.com/avlo/superconductor).

Each concrete event verifies that its `kind` matches the expected value from the `Kind` enum. Calling `validate()` on an event with an incorrect kind throws an `AssertionError`.

## Supported NIPs
The following NIPs are supported by the API out-of-the-box:
The API currently implements the following [NIPs](https://github.com/nostr-protocol/nips):
- [NIP-1](https://github.com/nostr-protocol/nips/blob/master/01.md)
- [NIP-2](https://github.com/nostr-protocol/nips/blob/master/02.md)
- [NIP-3](https://github.com/nostr-protocol/nips/blob/master/03.md)
Expand Down
65 changes: 65 additions & 0 deletions docs/CODEBASE_OVERVIEW.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Codebase Overview

This document provides an overview of the project structure and instructions for building and testing the modules.

## Module layout
- **nostr-java-base** – common model classes and utilities used across the project.
- **nostr-java-crypto** – pure Java implementation of BIP340 Schnorr signature test vectors.
- **nostr-java-event** – definitions of Nostr events and tags.
- **nostr-java-id** – identity generation and handling of keys.
- **nostr-java-util** – helper utilities used by other modules.
- **nostr-java-client** – WebSocket client used to communicate with relays.
- **nostr-java-api** – high level API wrapping event creation and relay communication.
- **nostr-java-encryption** – optional encryption support for messages.
- **nostr-java-examples** – sample applications demonstrating how to use the API.

## Building and testing
The project can be built with Maven or Gradle. Unit tests do not require a running relay, while integration tests use Testcontainers to start a relay in Docker.

### Unit-tested build
```bash
# Maven
./mvnw clean test
./mvnw install -Dmaven.test.skip=true

# Gradle
./gradlew clean test
./gradlew publishToMavenLocal
```

### Integration-tested build (requires Docker)
```bash
# Maven
./mvnw clean install

# Gradle
./gradlew clean check
./gradlew publishToMavenLocal
```
Integration tests start a `nostr-rs-relay` container automatically. The image used can be overridden in `src/test/resources/relay-container.properties` by setting `relay.container.image=<image>`.

## WebSocket configuration
`StandardWebSocketClient` waits for relay responses when sending messages. The timeout and polling interval are configured with the following properties (values in milliseconds):
```
nostr.websocket.await-timeout-ms=60000
nostr.websocket.poll-interval-ms=500
```

## Creating and sending events
The examples module shows how to create built-in and custom events. Below is an excerpt from the examples illustrating the creation of a `TextNoteEvent`:
```java
private static final Identity SENDER = Identity.generateRandomIdentity();
private final static Map<String, String> RELAYS = Map.of(
"lol", "nos.lol",
"damus", "relay.damus.io",
"ZBD", "nostr.zebedee.cloud",
"taxi", "relay.taxi",
"mom", "nostr.mom");

List<BaseTag> tags = List.of(new PubKeyTag(RECIPIENT.getPublicKey()));
var nip01 = new NIP01<TextNoteEvent>(SENDER);
nip01.createTextNoteEvent(tags, "Hello world, I'm here on nostr-java API!")
.sign()
.send(RELAYS);
```
Custom events can be created using `GenericEventNostr.createGenericEvent(kind, content)` and custom tags with `TagFactory`.