Zum Hauptinhalt springen

Übersicht

revolution/laravel-nostr ist ein Paket, mit dem Sie das Nostr-Protokoll aus Laravel heraus nutzen können. Es bietet Key-Generierung und -Umwandlung, Abrufen und Veröffentlichen von Events, Pool-Unterstützung (mehrere Relays), NIP-05-Profile, NIP-17 Private Direct Messages sowie eine Integration mit Laravel Notifications.
Da sich die Nostr-Spezifikation noch weiterentwickelt, wird auch dieses Paket kontinuierlich weiterentwickelt. Die Benachrichtigungsfunktion ist bereits produktiv nutzbar.

Driver

Dieses Paket verfügt über zwei Driver.
DriverBeschreibung
nativeReine PHP-Implementierung. Verwendet nostr-php. Reicht derzeit aus.
nodeImplementierung, die auf eine externe WebAPI (Node.js) angewiesen ist.
Das Besondere am native-Driver ist die Implementierung von WebSocketHttpMixin. Er stellt über den Laravel-HTTP-Client eine WebSocket-Verbindung her und trennt sie sofort nach dem Senden und Empfangen von Daten wieder. Ein dauerhaft laufender WebSocket-Server ist nicht erforderlich – das Design ist so ausgelegt, dass es jeder Laravel-Nutzer verwenden kann.
Der native-Driver unterstützt NIP-04 nicht.

Standard-Driver konfigurieren

Konfigurieren Sie ihn in config/nostr.php oder .env.
// config/nostr.php

'driver' => env('NOSTR_DRIVER', 'node'),
NOSTR_DRIVER=native
Wenn Sie keinen Driver angeben, wird der Standard-Driver verwendet.
use Revolution\Nostr\Facades\Nostr;

Nostr::event()->list();
Sie können den Driver auch explizit angeben.
use Revolution\Nostr\Facades\Nostr;

Nostr::driver('node')->event()->list();
Nostr::node()->event()->list();

Nostr::driver('native')->event()->list();
Nostr::native()->event()->list();

Installation

1

Paket installieren

composer require revolution/laravel-nostr
2

Konfigurationsdatei veröffentlichen

php artisan vendor:publish --tag=nostr-config

Key-Verwaltung

Key erzeugen

use Revolution\Nostr\Facades\Nostr;
use Illuminate\Http\Client\Response;

/** @var Response $response */
$response = Nostr::key()->generate();
$keys = $response->json();
// [
//     'sk'   => 'sk...',
//     'nsec' => 'nsec...',
//     'pk'   => 'pk...',
//     'npub' => 'npub...',
// ]

Key konvertieren

Aus nsec konvertieren.
use Revolution\Nostr\Facades\Nostr;

$response = Nostr::key()->fromNsec(nsec: 'nsec');
$keys = $response->json();
// ['sk' => '...', 'nsec' => '...', 'pk' => '...', 'npub' => '...']
Aus Secret Key konvertieren.
$response = Nostr::key()->fromSecretKey(sk: 'sk');
Aus npub konvertieren (nur öffentlicher Schlüssel).
$response = Nostr::key()->fromNpub(npub: 'npub');
$keys = $response->json();
// ['pk' => '...', 'npub' => '...']
Aus Public Key konvertieren.
$response = Nostr::key()->fromPublicKey(pk: 'pk');

Events abrufen

Mehrere Events abrufen

use Illuminate\Http\Client\Response;
use Revolution\Nostr\Facades\Nostr;
use Revolution\Nostr\Filter;
use Revolution\Nostr\Kind;

$filter = Filter::make(
    authors: ['my pk'],
    kinds: [Kind::Text],
    limit: 10,
);

/** @var Response $response */
$response = Nostr::event()->list(filter: $filter);
$events = $response->json('events');
// [
//     ['id' => '...1', 'kind' => 1, 'content' => '...'],
//     ['id' => '...2', 'kind' => 1, 'content' => '...'],
// ]

Ein einzelnes Event abrufen

use Revolution\Nostr\Facades\Nostr;
use Revolution\Nostr\Filter;
use Revolution\Nostr\Kind;

$filter = Filter::make(
    authors: ['my pk'],
    kinds: [Kind::Metadata],
);

$response = Nostr::event()->get(filter: $filter);
$event = $response->json('event');
// ['id' => '...', 'kind' => 0, 'content' => '{name: ""}']

Events veröffentlichen

An ein einzelnes Relay veröffentlichen

use Revolution\Nostr\Facades\Nostr;
use Revolution\Nostr\Event;
use Revolution\Nostr\Kind;

$event = Event::make(
    kind: Kind::Text,
    content: 'hello',
    created_at: now()->timestamp,
    tags: [],
);

$sk = 'my sk';

$response = Nostr::event()->publish(event: $event, sk: $sk);

if ($response->successful()) {
    $event = $response->json('event');
}

An mehrere Relays veröffentlichen (Pool)

use Revolution\Nostr\Facades\Nostr;
use Revolution\Nostr\Event;
use Revolution\Nostr\Kind;

$event = Event::make(
    kind: Kind::Text,
    content: 'test',
    created_at: now()->timestamp,
    tags: [],
);

$responses = Nostr::pool()->publish(event: $event, sk: 'my sk');
// $responses ist array<string, Response>
// ['wss://relay1' => $response, 'wss://relay2' => $response]

foreach ($responses as $relay => $response) {
    if ($response->failed()) {
        dump($relay . ' : ' . $response->body());
    }
}

Relay-Server konfigurieren

Verwendete Relay-Server

Wenn Sie nur Nostr::event() verwenden, wird das erste Relay aus config/nostr.php verwendet. Bei Nostr::pool() werden alle in der Konfiguration angegebenen Relays einbezogen.

Relays zur Laufzeit ändern

use Revolution\Nostr\Facades\Nostr;

$response = Nostr::event()->withRelay('wss://')->...;
use Revolution\Nostr\Facades\Nostr;

$response = Nostr::pool()->withRelays(['wss://', 'wss://'])->...;

NIP-05-Profile

use Revolution\Nostr\Facades\Nostr;

$profile = Nostr::nip05()->profile('user@localhost');
// [
//     'user'   => 'user@localhost',
//     'pubkey' => 'pk',
//     'relays' => [],
// ]

NIP-17 Private Direct Messages

NIP-17 wird nur vom native-Driver unterstützt.

Private Nachricht senden

use Revolution\Nostr\Facades\Nostr;

$response = Nostr::driver('native')
    ->nip17()
    ->sendDirectMessage(
        sk: 'sender-secret-key',
        pk: 'receiver-public-key',
        message: 'Hello, this is a private message!'
    );

Private Nachricht entschlüsseln

use Revolution\Nostr\Facades\Nostr;

$response = Nostr::driver('native')
    ->nip17()
    ->decryptDirectMessage(
        giftWrap: $receivedGiftWrap,
        sk: 'receiver-secret-key'
    );

$decryptedMessage = $response->json();

Laravel Notifications

Mit dem NostrChannel können Sie Nachrichten aus Laravel Notifications an Nostr senden.

Notification-Klasse

use Illuminate\Notifications\Notification;
use Revolution\Nostr\Notifications\NostrChannel;
use Revolution\Nostr\Notifications\NostrMessage;
use Revolution\Nostr\Tags\HashTag;

class TestNotification extends Notification
{
    public function via(object $notifiable): array
    {
        return [
            'mail',
            NostrChannel::class,
        ];
    }

    public function toNostr(object $notifiable): NostrMessage
    {
        return new NostrMessage(
            // #laravel im Content dient der Anzeige, HashTag in tags der Klassifizierung auf Protokollebene.
            content: 'hello #laravel',
            tags: [
                HashTag::make(t: 'laravel'),
            ],
        );
    }
}

On-Demand-Benachrichtigungen

use Illuminate\Support\Facades\Notification;
use Revolution\Nostr\Notifications\NostrRoute;

Notification::route('nostr', NostrRoute::to(sk: 'sk'))
    ->notify(new TestNotification());

Integration in das User-Modell

use Illuminate\Notifications\Notifiable;
use Revolution\Nostr\Notifications\NostrRoute;

class User
{
    use Notifiable;

    public function routeNotificationForNostr($notification): NostrRoute
    {
        return NostrRoute::to(sk: $this->sk, relays: ['wss://']);
    }
}
$user->notify(new TestNotification());

Für Benachrichtigungen verwendete Relay-Server

Standardmäßig werden alle in config/nostr.php angegebenen Relays verwendet. Wenn Sie in NostrRoute Relays angeben, können Sie sie zur Laufzeit ändern.
use Revolution\Nostr\Notifications\NostrRoute;

return NostrRoute::to(sk: 'sk', relays: ['wss://', 'wss://']);
Die aktuellsten Informationen finden Sie im GitHub-Repository.
Zuletzt geändert am 13. Juli 2026