node-red-contrib-nostr
Version:
Node-RED nodes for seamless Nostr protocol integration. Features robust WebSocket handling, event filtering, and NPUB-based routing. Built with TypeScript for type safety and extensive testing. Perfect for Nostr automation flows.
87 lines (86 loc) • 2.82 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebSocketManager = exports.NostrWebSocket = void 0;
const ws_1 = __importDefault(require("ws"));
class NostrWebSocket extends ws_1.default {
constructor(url, subscriptionId, filter, onEvent, onError) {
super(url);
this.subscriptionId = subscriptionId;
this.filter = filter;
this.onEvent = onEvent;
this.onError = onError;
this.on('open', () => {
this.send(JSON.stringify(['REQ', this.subscriptionId, this.filter]));
});
this.on('error', (error) => {
this.onError(error);
});
this.on('message', (data) => {
try {
const message = JSON.parse(data.toString());
if (Array.isArray(message) && message[0] === 'EVENT' && message[2]) {
this.onEvent(message[2]);
}
}
catch (err) {
if (err instanceof Error) {
this.onError(err);
}
else {
this.onError(new Error('Unknown error occurred'));
}
}
});
}
close() {
this.send(JSON.stringify(['CLOSE', this.subscriptionId]));
super.close();
}
}
exports.NostrWebSocket = NostrWebSocket;
class WebSocketManager {
constructor(config) {
this.url = config.relayUrl;
this.onConnect = config.onConnect;
this.onDisconnect = config.onDisconnect;
this.onError = config.onError;
}
connect() {
this.ws = new NostrWebSocket(this.url, '', {}, () => { }, this.onError);
this.ws.on('open', () => {
this.onConnect();
});
this.ws.on('close', () => {
this.onDisconnect();
});
}
async disconnect() {
if (this.ws) {
this.ws.close();
}
}
async sendEvent(event) {
if (!this.ws) {
throw new Error('WebSocket not connected');
}
this.ws.send(JSON.stringify(['EVENT', event]));
}
async subscribe(filters) {
if (!this.ws) {
throw new Error('WebSocket not connected');
}
const subscriptionId = Math.random().toString(36).substring(2);
this.ws = new NostrWebSocket(this.url, subscriptionId, filters, (event) => this.sendEvent(event), this.onError);
return subscriptionId;
}
async unsubscribe(subscriptionId) {
if (!this.ws) {
throw new Error('WebSocket not connected');
}
this.ws.close();
}
}
exports.WebSocketManager = WebSocketManager;