PHPackages                             swentel/nostr-php - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. swentel/nostr-php

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

swentel/nostr-php
=================

Nostr helper library for PHP

1.9.4(3mo ago)6725.9k↑14.1%17[3 issues](https://github.com/nostrver-se/nostr-php/issues)3MITPHPPHP &gt;=8.2 &lt;8.6CI failing

Since Feb 26Pushed 3mo ago7 watchersCompare

[ Source](https://github.com/nostrver-se/nostr-php)[ Packagist](https://packagist.org/packages/swentel/nostr-php)[ Docs](https://nostr-php.dev)[ RSS](/packages/swentel-nostr-php/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (7)Versions (46)Used By (3)

nostr-php
=========

[](#nostr-php)

[![CI](https://github.com/nostrver-se/nostr-php/actions/workflows/ci.yml/badge.svg)](https://github.com/nostrver-se/nostr-php/actions/workflows/ci.yml/badge.svg)[![Packagist PHP Version](https://camo.githubusercontent.com/c543dee34f133fe77c905b002096fa5928dcd507a24d0ee1229f2fdd75386ecc/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646570656e64656e63792d762f7377656e74656c2f6e6f7374722d7068702f706870)](https://camo.githubusercontent.com/c543dee34f133fe77c905b002096fa5928dcd507a24d0ee1229f2fdd75386ecc/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646570656e64656e63792d762f7377656e74656c2f6e6f7374722d7068702f706870)[![GitHub contributors](https://camo.githubusercontent.com/ea9326d80df1d5f3808ea49dc2a68a2c12a414bec0a315eeb63ccf71a796fefc/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6e7472696275746f72732f6e6f7374727665722d73652f6e6f7374722d706870)](https://camo.githubusercontent.com/ea9326d80df1d5f3808ea49dc2a68a2c12a414bec0a315eeb63ccf71a796fefc/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6e7472696275746f72732f6e6f7374727665722d73652f6e6f7374722d706870)[![GitHub issues](https://camo.githubusercontent.com/48f86109ac14189d17e929a4b704ff0cc3c9e064578dc8047f4f1e11fd62d7c1/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f6e6f7374727665722d73652f6e6f7374722d706870)](https://camo.githubusercontent.com/48f86109ac14189d17e929a4b704ff0cc3c9e064578dc8047f4f1e11fd62d7c1/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f6e6f7374727665722d73652f6e6f7374722d706870)[![GitHub last commit (branch)](https://camo.githubusercontent.com/05df0b1a9edfa23b3e572b7dba6a77789b4c3d0afcaf1fd1ef8694125bf83bf1/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f6e6f7374727665722d73652f6e6f7374722d7068702f6d61696e)](https://camo.githubusercontent.com/05df0b1a9edfa23b3e572b7dba6a77789b4c3d0afcaf1fd1ef8694125bf83bf1/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f6e6f7374727665722d73652f6e6f7374722d7068702f6d61696e)

This is a PHP Helper library for Nostr. More info about Nostr: .

Installation
------------

[](#installation)

To use the library as a package in your PHP project, you can add it via Composer:

```
$ composer require swentel/nostr-php
```

Install dependencies if you would like to test / code some things out for yourself with the code example snippets below.

```
$ composer install
```

Create an event
---------------

[](#create-an-event)

This will create an event object with a short text message (kind 1).

```
use swentel\nostr\Event\Event;

$note = new Event();
$note->setKind(1);
$note->setContent('Hello world!');
$note->setTags([
  ['e', $relayUrl],
  ['p', $public_key, $relayUrl],
  ['r', $relayUrl],
]);
// or use addTag()
$note->addTag(['p', $public_key, $relayUrl]);
```

Signing an event
----------------

[](#signing-an-event)

Generates the id and signature for an event. The 'pubkey', 'id' and 'sig' properties are added to the event object.

```
use swentel\nostr\Event\Event;
use swentel\nostr\Sign\Sign;

$note = new Event();
$note->setContent('Hello world!');
$note->setKind(1);

$signer = new Sign();
$signer->signEvent($note, $private_key);
```

Generating a message
--------------------

[](#generating-a-message)

Generate an event message : `["EVENT", ]`

```
use swentel\nostr\Sign\Sign;
use swentel\nostr\Message\EventMessage;

$signer = new Sign();
$signer->signEvent($note, $private_key);

$eventMessage = new EventMessage($note);
$message_string = $eventMessage->generate();
```

Publish an event to a relay
---------------------------

[](#publish-an-event-to-a-relay)

Publish an event with a note that has been prepared for sending to a relay.

```
use swentel\nostr\Event\Event;
use swentel\nostr\Message\EventMessage;
use swentel\nostr\Relay\Relay;

$note = new Event();
$note->setContent('Hello world');
$note->setKind(1);

$signer = new Sign();
$signer->signEvent($note, $private_key);

$eventMessage = new EventMessage($note);

$relayUrl = 'wss://nostr-websocket.tld';
$relay = new Relay($relayUrl);
$relay->setMessage($eventMessage);
$result = $relay->send();
```

If you would like to publish the event to multiple relays, you can use the `RelaySet` class.

```
$relay1 = new Relay(''wss://nostr-websocket1.tld'');
$relay2 = new Relay(''wss://nostr-websocket2.tld'');
$relay3 = new Relay(''wss://nostr-websocket3.tld'');
$relay4 = new Relay(''wss://nostr-websocket4.tld'');
$relaySet = new RelaySet();
$relaySet->setRelays([$relay1, $relay2, $relay3, $relay4]);
$relaySet->setMessage($eventMessage);
$result = $relaySet->send();
```

Read events from a relay
------------------------

[](#read-events-from-a-relay)

Fetch events from a relay.

```
$filter1 = new Filter();
$filter1->setKinds([1, 3]); // You can add multiple kind numbers
$filter1->setLimit(25); // Limit to fetch only a maximum of 25 events
$filters = [$filter1]; // You can add multiple filters.

$subscription = new Subscription();
$requestMessage = new RequestMessage($subscription->getid(), $filters);

$relayUrl = 'wss://nostr-websocket.tld';
$relay = new Relay($relayUrl);
$relay->setMessage($requestMessage);

$request = new Request($relay, $requestMessage);
$response = $request->send();
```

`$response` is a multidimensional array with elements containing each a response message (JSON string) decoded to an array from the relay and sorted by the relay. Output example:

```
[
  'wss://nostr-websocket.tld' => [
    0 => [
      "EVENT",
      "A8kWzjCVUHSD1rmuwGqyK2PxsolZMO9YXditbg05fch6p3Q4eT7vRFLEJINBna",
      [
        'id' => '1e8534623845629d40f7761c0577edf10f778c490e7b95a524845d9280c7c25a',
        'kind' => 1,
        'pubkey' => '06639a386c9c1014217622ccbcf40908c4f1a0c33e23f8d6d68f4abf655f8f71',
        'created_at' => 1718723787,
        'content' => 'Losing your social graph can feel the same for some I think 😮 ',
        'tags' => [
          ['e', 'f754a238947b7f32168f872650a8dd0b9376493e58005d7e0b8be52f6f229364', 'wss://nos.lol/', 'root'],
          ['e', 'fe7dd6ba22fa0aa39370aa160226b8bc2413460621c8d67ce862205ad5a02c24', 'wss://nos.lol/', 'reply'],
          ['p', 'fb1366abd5e4c92a8a950791bc72d51bde291a83555cb2c629a92fedd78068ac', '', 'mention']
        ],
        'sig' => '888c9b5d9e0b69eba3510dd2b5d03eddcf0a680ab0e7673820fb36a56448ad80701042a669c7ef9918593c5a41c8b3ccc1d82ade50f32b62dd843144f32df403'
    ],
    1 => [
      "EVENT",
      "A8kWzjCVUHSD1rmuwGqyK2PxsolZMO9YXditbg05fch6p3Q4eT7vRFLEJINBna",
      [
        ...Nostr event
      ]
    ],
    2 => [
      ...
    ],
    3 => [
      ...
    ],
    4 => [
      ...
    ]
  ]
]
```

Read events from a set of relays
--------------------------------

[](#read-events-from-a-set-of-relays)

Read events from a set of relays with the `RelaySet` class. It's basically the same snippet as above with the difference you create a `RelaySet` class and pass it through the `Request` object.

```
$filter1 = new Filter();
$filter1->setKinds([1]);
$filter1->setLimit(5);
$filters = [$filter1];
$subscription = new Subscription();
$requestMessage = new RequestMessage($subscription->getId(), $filters);
$relays = [
    new Relay('wss://nostr-websocket-1.tld'),
    new Relay('wss://nostr-websocket-2.tld'),
    new Relay('wss://nostr-websocket-3.tld'),
];
$relaySet = new RelaySet();
$relaySet->setRelays($relays);

$request = new Request($relaySet, $requestMessage);
$response = $request->send();
```

Generating a private key and a public key
-----------------------------------------

[](#generating-a-private-key-and-a-public-key)

```
use swentel\nostr\Key\Key;

$key = new Key();

$private_key = $key->generatePrivateKey();
$public_key  = $key->getPublicKey($private_key);
```

Converting keys
---------------

[](#converting-keys)

Convert bech32 encoded keys (npub, nsec) to hex.

```
use swentel\nostr\Key\Key;

$public_key = 'npub10elfcs4fr0l0r8af98jlmgdh9c8tcxjvz9qkw038js35mp4dma8qzvjptg';
$key = new Key();
$hex = $key->convertToHex($public_key);
```

Convert hex keys to bech32 (npub, nsec).

```
use swentel\nostr\Key\Key;

$public_key = '7e7e9c42a91bfef19fa929e5fda1b72e0ebc1a4c1141673e2794234d86addf4e';
$private_key = '67dea2ed018072d675f5415ecfaed7d2597555e202d85b3d65ea4e58d2d92ffa';
$key = new Key();
$bech32_public = $key->convertPublicKeyToBech32($public_key);
$bech32_private = $key->convertPrivateKeyToBech32($private_key);
```

Run tests with debug output
---------------------------

[](#run-tests-with-debug-output)

All tests can be found in `tests`.

```
$ php vendor/bin/phpunit --debug
```

Documentation
-------------

[](#documentation)

There is a comprehensive documentation website for the library:

Also, this website is published with nsite on several Blossom servers which can be accessed on the following hosts:

-
-

Repository:

phpDocumentor documentation
---------------------------

[](#phpdocumentor-documentation)

Generate documentation with [phpDocumentor](https://phpdoc.org/).

```
$ phpdoc
```

All documentation is saved in the `phpdoc.nostr-php.dev` directory where the `index.html` can be opened in any browser. This directory also serves as the root directory for .

The documentation of phpDocumentor can be found at .

Roadmap / features
------------------

[](#roadmap--features)

- Keypair generation and validation
    - Convert from hex to bech32-encoded keys
- Event signing with Schnorr signatures (`secp256k1`)
- Event string validation (issue [\#17](https://github.com/nostrver-se/nostr-php/issues/17)) + Event object validation (issue [\#85](https://github.com/nostrver-se/nostr-php/issues/85))
- NIP-01 basic protocol flow description
    - Publish events
    - Request events (issue [\#55](https://github.com/nostrver-se/nostr-php/pull/55) credits to [kriptonix](https://github.com/kriptonix))
    - Fetch event with a persistent connection (pr [\#99](https://github.com/nostrver-se/nostr-php/pull/99))
    - Implement all types of relay responses
        - `EVENT` - sends events requested by the client
        - `OK` - indicate an acceptance or denial of an EVENT message
        - `EOSE` - end of stored events
        - `CLOSED` - subscription is ended on the server side
        - `NOTICE` - used to send human-readable messages (like errors) to clients
- NIP-04 encrypted direct messages (pr [\#84](https://github.com/nostrver-se/nostr-php/pull/84) credits to [dsbaars](https://github.com/dsbaars))
- NIP-05 mapping Nostr keys to DNS-based internet identifiers (pr [89](https://github.com/nostrver-se/nostr-php/pull/89) credits to [dsbaars](https://github.com/dsbaars))
- NIP-17 private direct messages (pr [\#90](https://github.com/nostrver-se/nostr-php/pull/90) credits to [dsbaars](https://github.com/dsbaars))
- NIP-19 bech32-encoded identifiers (pr [\#68](https://github.com/nostrver-se/nostr-php/pull/68))
- NIP-24 extra metadata fields and tags (pr [94](https://github.com/nostrver-se/nostr-php/pull/94) credits to [dsbaars](https://github.com/dsbaars))
- NIP-42 authentication of clients to relays
- NIP-44 encrypted payloads (pr [\#84](https://github.com/nostrver-se/nostr-php/pull/84) credits to [dsbaars](https://github.com/dsbaars))
- NIP-65 relay list metadata (pr [\#100](https://github.com/nostrver-se/nostr-php/pull/100))
- Support multi-threading (async concurrency) for handling requests simultaneously
- Support NIP-29 relay-based groups (communities)
- Support NIP-52 calendar events
- Support NIP-46 remote signing initiated by the client (issue [\#87](https://github.com/nostrver-se/nostr-php/issues/87))
- Support NIP-45 event counts
- Support NIP-50 search capability
- Support NIP-03 openTimestamps attestations for events
- Support NIP-14 subject tag in text events
- Support NIP-40 expiration timestamp
- Support NIP-47 Nostr Wallet Connect
- Support NIP-49 private key encryption
- Support NIP-77 Negentropy syncing

Community
---------

[](#community)

If you need any help, please join this Telegram group: [https://t.me/nostr\_php](https://t.me/nostr_php)

Funding
-------

[](#funding)

In May 2024 OpenSats granted Sebastian Hagens for further development of this library for one year. If you would like to support this project with a donation, you could send some lightning sats to `sebastian@lnd.sebastix.com` or on-chain to `bc1p3p6jq2sxsf650lgllv57st9h97xj37fflg5t8d265saz6yqzcdyqd7pzun`.

Maintainers
-----------

[](#maintainers)

- [@sebastix](https://github.com/Sebastix) `npub1qe3e5wrvnsgpggtkytxteaqfprz0rgxr8c3l34kk3a9t7e2l3acslezefe`
- [@swentel](https://github.com/swentel) (original author, inactive) `npub1z8n2zt0vzkefhrhpf60face4wwq2nx87sz7wlgcvuk4adddkkycqknzjk5`

Contributors
------------

[](#contributors)

See

###  Health Score

59

—

FairBetter than 99% of packages

Maintenance79

Regular maintenance activity

Popularity43

Moderate usage in the ecosystem

Community28

Small or concentrated contributor base

Maturity75

Established project with proven stability

 Bus Factor1

Top contributor holds 77.4% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~30 days

Recently: every ~61 days

Total

36

Last Release

105d ago

Major Versions

1.4.2 → 2.0.0-alpha12024-10-18

PHP version history (6 changes)1.0.0PHP &gt;=8.0

1.1.0PHP ^8.1

1.2.4PHP &gt;=8.1 &lt;8.4

2.0.0-alpha1PHP &gt;=8.2 &lt;8.4

1.5.1PHP &gt;=8.1 &lt;8.5

1.9.3PHP &gt;=8.2 &lt;8.6

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/168466?v=4)[Kristof De Jaeger](/maintainers/swentel)[@swentel](https://github.com/swentel)

---

Top Contributors

[![Sebastix](https://avatars.githubusercontent.com/u/582669?v=4)](https://github.com/Sebastix "Sebastix (226 commits)")[![swentel](https://avatars.githubusercontent.com/u/168466?v=4)](https://github.com/swentel "swentel (24 commits)")[![dsbaars](https://avatars.githubusercontent.com/u/480514?v=4)](https://github.com/dsbaars "dsbaars (20 commits)")[![1ma](https://avatars.githubusercontent.com/u/1456708?v=4)](https://github.com/1ma "1ma (8 commits)")[![eko2one](https://avatars.githubusercontent.com/u/92563141?v=4)](https://github.com/eko2one "eko2one (3 commits)")[![kriptonix](https://avatars.githubusercontent.com/u/7550807?v=4)](https://github.com/kriptonix "kriptonix (3 commits)")[![thevikas](https://avatars.githubusercontent.com/u/94922?v=4)](https://github.com/thevikas "thevikas (2 commits)")[![pjv](https://avatars.githubusercontent.com/u/327716?v=4)](https://github.com/pjv "pjv (1 commits)")[![pj8912](https://avatars.githubusercontent.com/u/59218902?v=4)](https://github.com/pj8912 "pj8912 (1 commits)")[![shawndearmond](https://avatars.githubusercontent.com/u/254933?v=4)](https://github.com/shawndearmond "shawndearmond (1 commits)")[![svemir](https://avatars.githubusercontent.com/u/154453?v=4)](https://github.com/svemir "svemir (1 commits)")[![pedromvpg](https://avatars.githubusercontent.com/u/807505?v=4)](https://github.com/pedromvpg "pedromvpg (1 commits)")[![atrifat](https://avatars.githubusercontent.com/u/10791791?v=4)](https://github.com/atrifat "atrifat (1 commits)")

---

Tags

nostrphplibrarynostr

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/swentel-nostr-php/health.svg)

```
[![Health](https://phpackages.com/badges/swentel-nostr-php/health.svg)](https://phpackages.com/packages/swentel-nostr-php)
```

###  Alternatives

[league/iso3166

ISO 3166-1 PHP Library

70036.3M116](/packages/league-iso3166)[league/statsd

A simple library for working with StatsD in PHP.

3514.3M12](/packages/league-statsd)[payum/iso4217

ISO 4217 PHP Library

16312.1M5](/packages/payum-iso4217)[lambdish/phunctional

λ PHP functional library

3612.0M23](/packages/lambdish-phunctional)[dekor/php-array-table

PHP Library for printing associative arrays as text table (similar to mysql terminal console)

296.6M2](/packages/dekor-php-array-table)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
