Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/codytseng/nostr-relay
Easily build your customized Nostr Relay. (WIP)
https://github.com/codytseng/nostr-relay
nostr nostr-relay relay
Last synced: 20 days ago
JSON representation
Easily build your customized Nostr Relay. (WIP)
- Host: GitHub
- URL: https://github.com/codytseng/nostr-relay
- Owner: CodyTseng
- License: mit
- Created: 2023-12-03T15:03:47.000Z (about 1 year ago)
- Default Branch: master
- Last Pushed: 2024-04-20T13:32:56.000Z (8 months ago)
- Last Synced: 2024-05-02T05:20:41.033Z (8 months ago)
- Topics: nostr, nostr-relay, relay
- Language: TypeScript
- Homepage:
- Size: 1.72 MB
- Stars: 8
- Watchers: 1
- Forks: 2
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# nostr-relay
[![codecov](https://codecov.io/gh/CodyTseng/nostr-relay/graph/badge.svg?token=9YG4V34301)](https://codecov.io/gh/CodyTseng/nostr-relay)
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FCodyTseng%2Fnostr-relay.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2FCodyTseng%2Fnostr-relay?ref=badge_shield)> Easily build your customized Nostr Relay.
## Used By
- [nostr-relay-nestjs](https://github.com/CodyTseng/nostr-relay-nestjs)
- [nostr-relay-tray](https://github.com/CodyTseng/nostr-relay-tray)
- [nostr-relay-sqlite](https://github.com/CodyTseng/nostr-relay-sqlite)## Usage
I think examples are the best way to explain how to use this library.
```typescript
import { NostrRelay, createOutgoingNoticeMessage } from '@nostr-relay/core';
import { EventRepositorySqlite } from '@nostr-relay/event-repository-sqlite';
import { Validator } from '@nostr-relay/validator';
import { WebSocketServer } from 'ws';async function bootstrap() {
const wss = new WebSocketServer({ port: 4869 });// You can implement your own event repository. It just needs to implement a few methods.
const eventRepository = new EventRepositorySqlite();
await eventRepository.init();
const relay = new NostrRelay(eventRepository);
const validator = new Validator();wss.on('connection', ws => {
// Handle a new client connection. This method should be called when a new client connects to the Nostr Relay server.
relay.handleConnection(ws);ws.on('message', async data => {
try {
// Validate the incoming message.
const message = await validator.validateIncomingMessage(data);
// Handle the incoming message.
await relay.handleMessage(ws, message);
} catch (error) {
if (error instanceof Error) {
ws.send(JSON.stringify(createOutgoingNoticeMessage(error.message)));
}
}
});// Handle a client disconnection. This method should be called when a client disconnects from the Nostr Relay server.
ws.on('close', () => relay.handleDisconnect(ws));ws.on('error', error => {
ws.send(JSON.stringify(createOutgoingNoticeMessage(error.message)));
});
});
}
bootstrap();
```Full API documentation can be found [here](https://codytseng.github.io/nostr-relay/)
## Plugin
[Official plugins](https://github.com/CodyTseng/nostr-relay-plugin)
You can create your own plugin to extend the functionality of the Nostr Relay. A plugin is just an object containing some of the following methods:
### handleMessage
This method functions like Koa middleware and is called when a new message is received from a client.
Params:
- `ctx`: The context object of the client.
- `message`: The incoming message.
- `next`: The next function to call the next plugin.Example:
```typescript
import { HandleMessagePlugin } from '@nostr-relay/common';class MessageLoggerPlugin implements HandleMessagePlugin {
async handleMessage(ctx, message, next) {
const startTime = Date.now();
console.log('Received message:', message);
const result = await next();
console.log('Message processed in', Date.now() - startTime, 'ms');
return result;
}
}relay.register(new MessageLoggerPlugin());
```### beforeHandleEvent
This method will be called before handling an event. If the method returns false, the event will be ignored.
params:
- `event`: The incoming event.
Example:
```typescript
import { HandleMessagePlugin } from '@nostr-relay/common';class BlacklistGuardPlugin implements BeforeHandleEventPlugin {
private blacklist = [
// ...
];beforeHandleEvent(event) {
const canHandle = !this.blacklist.includes(event.pubkey);
return {
canHandle,
message: canHandle ? undefined : 'block: you are blacklisted',
};
}
}relay.register(new BlacklistGuardPlugin());
```### broadcast
This method functions like Koa middleware and is called when an event is broadcast.
Params:
- `event`: The event to broadcast.
- `next`: The next function to call the next plugin.Example:
```typescript
import { BroadcastPlugin } from '@nostr-relay/common';class RedisBroadcastPlugin implements BroadcastPlugin {
async broadcast(event, next) {
await redis.publish('events', JSON.stringify(event));
return next();
}
}relay.register(new RedisBroadcastPlugin());
```### More to come...
## Donate
If you like this project, you can buy me a coffee :) ⚡️ [email protected] ⚡️
## License
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FCodyTseng%2Fnostr-relay.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2FCodyTseng%2Fnostr-relay?ref=badge_large)