Skip to content

Commit

Permalink
Merge branch 'nostr'
Browse files Browse the repository at this point in the history
  • Loading branch information
macterra committed Oct 24, 2023
2 parents 59656a7 + 77d83cf commit 7579c5d
Show file tree
Hide file tree
Showing 8 changed files with 446 additions and 28 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Custom ignores
data/
frontend/build/
nostr/strfry-db

# Logs
logs
Expand Down
1 change: 1 addition & 0 deletions config.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const config = {
ln_wallet: process.env.LN_WALLET,
ln_api_key: process.env.LN_API_KEY,
ln_admin_key: process.env.LN_ADMIN_KEY,
nostr_key: process.env.NOSTR_KEY,
data: 'data',
uploads: 'data/uploads',
assets: 'data/assets',
Expand Down
8 changes: 8 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,11 @@ services:
- ./data:/data
depends_on:
- ipfs

nostr:
image: dockurr/strfry:latest
ports:
- 7777:7777
volumes:
- ./nostr/strfry-db:/app/strfry-db
- ./nostr/strfry.conf:/etc/strfry.conf
134 changes: 134 additions & 0 deletions nostr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@

const WebSocket = require('ws');
const config = require('./config');

const {
finishEvent,
validateEvent,
verifySignature,
getPublicKey
} = require('nostr-tools');

const RELAYS = {};

function createMessage(message) {
let event = {
kind: 1,
created_at: Math.floor(Date.now() / 1000),
tags: [],
content: message,
pubkey: getPublicKey(config.nostr_key),
};

finishEvent(event, config.nostr_key);

const valid = validateEvent(event);
const verified = verifySignature(event);

if (valid && verified) {
return event;
}
};

function openRelay(wsurl) {
const ws = new WebSocket(wsurl);

ws.on('open', () => {
console.log(`ws open ${wsurl}`);
RELAYS[wsurl] = ws;
});

ws.on('error', (error) => {
console.log(`ws error from ${wsurl}: ${error}`);
});

ws.on('message', (event) => {
console.log(`ws message from ${wsurl}: ${event} `);
});

ws.on('close', () => {
console.log(`ws close ${wsurl}`);
delete RELAYS[wsurl];
});
}

function closeRelays() {
for (let key in RELAYS) {
const ws = RELAYS[key];
ws.close();
}
}

function countOpenRelays() {
let count = 0;

for (let key in RELAYS) {
const ws = RELAYS[key];

if (ws.readyState === WebSocket.OPEN) {
count++;
}
}

return count;
}

function subscribeToRelays() {
const filters = {
kinds: [1],
limit: 1000,
};

sendRequest(filters);
}

function sendEvent(event) {
const message = JSON.stringify(["EVENT", event]);

for (let key in RELAYS) {
const ws = RELAYS[key];

if (ws.readyState === WebSocket.OPEN) {
ws.send(message);
console.log(`ws event sent to ${key}`);
}
else {
console.log(`ws ${key} not open`);
}
}
}

function sendMessage(message) {
const event = createMessage(message);

if (event) {
sendEvent(event);
}
}

function sendRequest(filters) {
const sub = "foo";
const message = JSON.stringify(["REQ", sub, filters]);

for (let key in RELAYS) {
const ws = RELAYS[key];

if (ws.readyState === WebSocket.OPEN) {
ws.send(message);
console.log(`ws req sent to ${key}`);
}
else {
console.log(`ws ${key} not open`);
}
}
}

module.exports = {
closeRelays,
countOpenRelays,
createMessage,
openRelay,
sendEvent,
sendMessage,
subscribeToRelays,
};
139 changes: 139 additions & 0 deletions nostr/strfry.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
##
## Default strfry config
##

# Directory that contains the strfry LMDB database (restart required)
db = "./strfry-db/"

dbParams {
# Maximum number of threads/processes that can simultaneously have LMDB transactions open (restart required)
maxreaders = 256

# Size of mmap() to use when loading LMDB (default is 10TB, does *not* correspond to disk-space used) (restart required)
mapsize = 10995116277760

# Disables read-ahead when accessing the LMDB mapping. Reduces IO activity when DB size is larger than RAM. (restart required)
noReadAhead = false
}

events {
# Maximum size of normalised JSON, in bytes
maxEventSize = 65536

# Events newer than this will be rejected
rejectEventsNewerThanSeconds = 900

# Events older than this will be rejected
rejectEventsOlderThanSeconds = 94608000

# Ephemeral events older than this will be rejected
rejectEphemeralEventsOlderThanSeconds = 60

# Ephemeral events will be deleted from the DB when older than this
ephemeralEventsLifetimeSeconds = 300

# Maximum number of tags allowed
maxNumTags = 2000

# Maximum size for tag values, in bytes
maxTagValSize = 1024
}

relay {
# Interface to listen on. Use 0.0.0.0 to listen on all interfaces (restart required)
#bind = "127.0.0.1"
bind = "0.0.0.0"

# Port to open for the nostr websocket protocol (restart required)
port = 7777

# Set OS-limit on maximum number of open files/sockets (if 0, don't attempt to set) (restart required)
nofiles = 1000000

# HTTP header that contains the client's real IP, before reverse proxying (ie x-real-ip) (MUST be all lower-case)
realIpHeader = ""

info {
# NIP-11: Name of this server. Short/descriptive (< 30 characters)
name = "artx.market nostr-relay"

# NIP-11: Detailed information about relay, free-form
description = "This is a strfry instance."

# NIP-11: Administrative nostr pubkey, for contact purposes
pubkey = "e8d667dd0c571ba799390a392b690dd7b5491f484690ba922ab3f17965fb2139"

# NIP-11: Alternative administrative contact (email, website, etc)
contact = "[email protected]"
}

# Maximum accepted incoming websocket frame size (should be larger than max event) (restart required)
maxWebsocketPayloadSize = 131072

# Websocket-level PING message frequency (should be less than any reverse proxy idle timeouts) (restart required)
autoPingSeconds = 55

# If TCP keep-alive should be enabled (detect dropped connections to upstream reverse proxy)
enableTcpKeepalive = false

# How much uninterrupted CPU time a REQ query should get during its DB scan
queryTimesliceBudgetMicroseconds = 10000

# Maximum records that can be returned per filter
maxFilterLimit = 500

# Maximum number of subscriptions (concurrent REQs) a connection can have open at any time
maxSubsPerConnection = 20

writePolicy {
# If non-empty, path to an executable script that implements the writePolicy plugin logic
plugin = ""
}

compression {
# Use permessage-deflate compression if supported by client. Reduces bandwidth, but slight increase in CPU (restart required)
enabled = true

# Maintain a sliding window buffer for each connection. Improves compression, but uses more memory (restart required)
slidingWindow = true
}

logging {
# Dump all incoming messages
dumpInAll = false

# Dump all incoming EVENT messages
dumpInEvents = false

# Dump all incoming REQ/CLOSE messages
dumpInReqs = false

# Log performance metrics for initial REQ database scans
dbScanPerf = false

# Log reason for invalid event rejection? Can be disabled to silence excessive logging
invalidEvents = true
}

numThreads {
# Ingester threads: route incoming requests, validate events/sigs (restart required)
ingester = 3

# reqWorker threads: Handle initial DB scan for events (restart required)
reqWorker = 3

# reqMonitor threads: Handle filtering of new events (restart required)
reqMonitor = 3

# negentropy threads: Handle negentropy protocol messages (restart required)
negentropy = 2
}

negentropy {
# Support negentropy protocol messages
enabled = true

# Maximum records that sync will process before returning an error
maxSyncEvents = 1000000
}
}
Loading

0 comments on commit 7579c5d

Please sign in to comment.