Skip to content

Commit a26ccb6

Browse files
authored
Merge branch 'main' into fix/dead-connections-with-subscriptions
2 parents 89a0b4c + 3f278f6 commit a26ccb6

112 files changed

Lines changed: 18141 additions & 20097 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# --- REQUIRED ---
2+
SECRET=change_me_to_something_long_and_random # Generate: openssl rand -hex 128
3+
4+
# --- POSTGRESQL ---
5+
DB_HOST=localhost
6+
DB_PORT=5432
7+
DB_NAME=nostr_ts_relay
8+
DB_USER=nostr_ts_relay
9+
DB_PASSWORD=nostr_ts_relay
10+
# Alternatively, use a URI:
11+
# DB_URI=postgresql://nostr_ts_relay:nostr_ts_relay@localhost:5432/nostr_ts_relay
12+
13+
# --- DB POOL TUNING (Optional) ---
14+
# DB_MIN_POOL_SIZE=0
15+
# DB_MAX_POOL_SIZE=3
16+
# DB_ACQUIRE_CONNECTION_TIMEOUT=60000
17+
18+
# --- REDIS (Required for Rate Limiting) ---
19+
REDIS_HOST=localhost
20+
REDIS_PORT=6379
21+
# REDIS_USER=default
22+
# REDIS_PASSWORD=
23+
# Alternatively, use a URI:
24+
# REDIS_URI=redis://localhost:6379
25+
26+
# --- SERVER CONFIG ---
27+
RELAY_PORT=8008
28+
WORKER_COUNT=2 # Defaults to CPU count. Use 1 or 2 for local testing.
29+
# NOSTR_CONFIG_DIR=.nostr # Where settings.yaml lives
30+
31+
# --- DEBUGGING ---
32+
# Useful namespaces: maintenance-worker, database-client:*, cache-client, etc.
33+
# DEBUG=maintenance-worker
34+
35+
# --- RELAY PRIVATE KEY (Optional) ---
36+
# RELAY_PRIVATE_KEY=your_hex_private_key
37+
38+
# --- PAYMENTS (Only if enabled in settings.yaml) ---
39+
# ZEBEDEE_API_KEY=
40+
# NODELESS_API_KEY=
41+
# NODELESS_WEBHOOK_SECRET=
42+
# OPENNODE_API_KEY=
43+
# LNBITS_API_KEY=
44+
45+
# --- READ REPLICAS (Optional) ---
46+
# READ_REPLICA_ENABLED=false
47+
# READ_REPLICAS=2
48+
# RR0_DB_HOST=localhost
49+
# RR0_DB_PORT=5432
50+
# RR0_DB_NAME=nostr_ts_relay
51+
# RR0_DB_USER=your_psql_username
52+
# RR0_DB_PASSWORD=your_psql_password
53+
# RR0_DB_MIN_POOL_SIZE=0
54+
# RR0_DB_MAX_POOL_SIZE=3
55+
# RR0_DB_ACQUIRE_CONNECTION_TIMEOUT=60000
56+
# RR1_DB_HOST=localhost
57+
# RR1_DB_PORT=5432
58+
# RR1_DB_NAME=nostr_ts_relay
59+
# RR1_DB_USER=your_psql_username
60+
# RR1_DB_PASSWORD=your_psql_password
61+
# RR1_DB_MIN_POOL_SIZE=0
62+
# RR1_DB_MAX_POOL_SIZE=3
63+
# RR1_DB_ACQUIRE_CONNECTION_TIMEOUT=60000
64+
65+
# --- TOR (Optional) ---
66+
# TOR_HOST=localhost
67+
# TOR_CONTROL_PORT=9051
68+
# TOR_PASSWORD=
69+
# HIDDEN_SERVICE_PORT=80

.eslintrc.js

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,33 @@ module.exports = {
33
parserOptions: {
44
sourceType: 'module',
55
},
6-
plugins: ['@typescript-eslint/eslint-plugin'],
6+
plugins: ['@typescript-eslint'],
77
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
88
root: true,
99
env: {
1010
node: true,
1111
},
1212
ignorePatterns: ['dist', 'tslint.json', 'node_modules'],
1313
rules: {
14-
'@typescript-eslint/interface-name-prefix': 'off',
1514
'@typescript-eslint/no-explicit-any': 'off',
16-
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
15+
'@typescript-eslint/no-unused-vars': [
16+
'error',
17+
{
18+
argsIgnorePattern: '^_',
19+
caughtErrors: 'none',
20+
},
21+
],
22+
'@typescript-eslint/no-require-imports': 'off',
23+
1724
semi: ['error', 'never'],
1825
quotes: ['error', 'single', { avoidEscape: true }],
19-
'sort-imports': ['error', {
20-
ignoreCase: true,
21-
allowSeparatedGroups: true,
22-
}],
26+
'sort-imports': [
27+
'error',
28+
{
29+
ignoreCase: true,
30+
allowSeparatedGroups: true,
31+
},
32+
],
2333
curly: [2, 'multi-line'],
2434
'max-len': [
2535
'error',
@@ -32,4 +42,12 @@ module.exports = {
3242
],
3343
'comma-dangle': ['error', 'always-multiline'],
3444
},
35-
}
45+
overrides: [
46+
{
47+
files: ['test/**/*.ts', '**/*.spec.ts'],
48+
rules: {
49+
'@typescript-eslint/no-unused-expressions': 'off',
50+
},
51+
},
52+
],
53+
}

.github/workflows/checks.yml

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ jobs:
4242
run: npm ci
4343
- name: Run ESLint
4444
run: npm run lint
45+
- name: Run Knip
46+
run: npm run knip
4547
build-check:
4648
name: Build check
4749
runs-on: ubuntu-latest
@@ -77,11 +79,12 @@ jobs:
7779
- name: Run coverage for unit tests
7880
run: npm run cover:unit
7981
if: ${{ always() }}
80-
- uses: actions/upload-artifact@v3
82+
- uses: actions/upload-artifact@v4
8183
name: Upload coverage report for unit tests
8284
if: ${{ always() }}
8385
with:
84-
path: .coverage/*/lcov.info
86+
name: unit-coverage-lcov
87+
path: .coverage/unit/lcov.info
8588
- name: Coveralls
8689
uses: coverallsapp/github-action@master
8790
if: ${{ always() }}
@@ -122,29 +125,12 @@ jobs:
122125
flag-name: Integration
123126
parallel: true
124127
github-token: ${{ secrets.GITHUB_TOKEN }}
125-
- uses: actions/upload-artifact@v3
128+
- uses: actions/upload-artifact@v4
126129
name: Upload coverage report for integration tests
127130
if: ${{ always() }}
128131
with:
129-
path: .coverage/*/lcov.info
130-
sonarcloud:
131-
name: Sonarcloud
132-
needs: [test-units-and-cover, test-integrations-and-cover]
133-
runs-on: ubuntu-latest
134-
steps:
135-
- name: Checkout
136-
uses: actions/checkout@v3
137-
with:
138-
fetch-depth: 0
139-
- uses: actions/download-artifact@v3
140-
name: Download unit & integration coverage reports
141-
with:
142-
path: .coverage
143-
- name: SonarCloud Scan
144-
uses: sonarsource/sonarcloud-github-action@master
145-
env:
146-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
147-
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
132+
name: integration-coverage-lcov
133+
path: .coverage/integration/lcov.info
148134
post-tests:
149135
name: Post Tests
150136
needs: [test-units-and-cover, test-integrations-and-cover]

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ node_modules/
2525
.dccache
2626
.DS_Store
2727

28+
# Local Setup
29+
redis.conf
30+
users.acl
31+
postgresql.local.conf
32+
2833
# generate output
2934
dist
3035

.knip.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"$schema": "https://unpkg.com/knip@2/schema.json",
3+
"entry": [
4+
"src/index.ts",
5+
"src/import-events.ts",
6+
"knexfile.js"
7+
],
8+
"project": [
9+
"src/**/*.ts"
10+
],
11+
"ignoreFiles": [],
12+
"commitlint": false,
13+
"eslint": false,
14+
"github-actions": false,
15+
"husky": false,
16+
"mocha": false,
17+
"nyc": false,
18+
"semantic-release": false
19+
}

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v18.8.0
1+
v24.14.1

CONFIGURATION.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ Running `nostream` for the first time creates the settings file in `<project_roo
109109
| limits.event.rateLimits[].rate | Maximum number of events during period. |
110110
| limits.event.whitelists.pubkeys | List of public keys to ignore rate limits. |
111111
| limits.event.whitelists.ipAddresses | List of IPs (IPv4 or IPv6) to ignore rate limits. |
112+
| limits.event.retention.maxDays | Maximum number of days to retain events. Purge deletes events that are expired (`expires_at`), soft-deleted (`deleted_at`), or older than this window (`created_at`). Any non-positive value disables retention purge. |
113+
| limits.event.retention.kind.whitelist | Event kinds excluded from retention purge. NIP-62 `REQUEST_TO_VANISH` is always excluded from retention purge, even if not listed here. |
114+
| limits.event.retention.pubkey.whitelist | Public keys excluded from retention purge. |
112115
| limits.client.subscription.maxSubscriptions | Maximum number of subscriptions per connected client. Defaults to 10. Disabled when set to zero. |
113116
| limits.client.subscription.maxFilters | Maximum number of filters per subscription. Defaults to 10. Disabled when set to zero. |
114117
| limits.message.rateLimits[].period | Rate limit period in milliseconds. |

CONTRIBUTING.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ before making a change.
66

77
Please keep the conversations civil, respectful and focus on the topic being discussed.
88

9+
## Local Quality Checks
10+
11+
Run dead code and dependency analysis before opening a pull request:
12+
13+
```
14+
npm run knip
15+
```
16+
17+
`npm run lint` now runs Knip first, then ESLint.
18+
919
## Pull Request Process
1020

1121
1. Update the relevant documentation with details of changes to the interface, this includes new environment

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM node:18-alpine3.16 AS build
1+
FROM node:24-alpine AS build
22

33
WORKDIR /build
44

@@ -10,7 +10,7 @@ COPY . .
1010

1111
RUN npm run build
1212

13-
FROM node:18-alpine3.16
13+
FROM node:24-alpine
1414

1515
LABEL org.opencontainers.image.title="Nostream"
1616
LABEL org.opencontainers.image.source=https://github.com/cameri/nostream

Dockerfile.railwayapp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
## Author Saransh Sharma @cynsar foundation
2-
FROM node:18-alpine3.16 as build
2+
FROM node:24-alpine as build
33

44
ARG PORT
55
ARG PGHOST
@@ -23,13 +23,14 @@ ADD migrations /build/migrations
2323

2424
RUN npm install -g knex@2.4.0 && npm install --quiet
2525

26-
RUN npm run db:migrate
27-
2826
COPY . .
2927

3028
RUN npm run build
3129

32-
FROM node:18-alpine3.16
30+
FROM node:24-alpine
31+
32+
# Install dumb-init for proper signal handling
33+
RUN apk add --no-cache dumb-init
3334

3435
ARG PORT
3536
ARG PGHOST
@@ -71,12 +72,19 @@ LABEL org.opencontainers.image.licenses=MIT
7172

7273
WORKDIR /app
7374

75+
# Copy runtime artifacts and configuration
7476
COPY --from=build /build/dist .
77+
COPY --from=build /build/package.json /build/package-lock.json ./
78+
COPY --from=build /build/knexfile.js ./
79+
COPY --from=build /build/migrations ./migrations
80+
COPY --from=build /build/seeds ./seeds
7581

76-
RUN npm install --omit=dev --quiet
82+
RUN npm install --omit=dev --quiet && npm install -g knex@2.4.0
7783

7884
USER 1000:1000
7985

8086
RUN mkdir -p $NOSTR_CONFIG_DIR
8187

82-
CMD ["node", "src/index.js"]
88+
ENTRYPOINT ["dumb-init", "--"]
89+
90+
CMD ["sh", "-c", "npm run db:migrate && node src/index.js"]

0 commit comments

Comments
 (0)