Skip to content

Commit 14bc96f

Browse files
committed
feat: allow lightning zap receipts on paid relays (#303)
* chore: add event_kinds whitelist for fee schedules * chore: fix identation in default-settings.yml * chore: waive admission fee for specific event kinds * docs: add payment settings to CONFIGURATION.md * docs: improve read replica docs
1 parent 565f67c commit 14bc96f

File tree

7 files changed

+300
-105
lines changed

7 files changed

+300
-105
lines changed

CONFIGURATION.md

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,31 @@ The following environment variables can be set:
2020
| DB_MAX_POOL_SIZE | Max. connections per worker | 32 |
2121
| DB_ACQUIRE_CONNECTION_TIMEOUT | New connection timeout (ms) | 60000 |
2222
| READ_REPLICA_ENABLED | Read Replica (RR) Toggle | 'false' |
23-
| RR_DB_HOST | PostgresSQL Hostname (RR) | |
24-
| RR_DB_PORT | PostgreSQL Port (RR) | 5432 |
25-
| RR_DB_USER | PostgreSQL Username (RR) | nostr_ts_relay |
26-
| RR_DB_PASSWORD | PostgreSQL Password (RR) | nostr_ts_relay |
27-
| RR_DB_NAME | PostgreSQL Database name (RR) | nostr_ts_relay |
28-
| RR_DB_MIN_POOL_SIZE | Min. connections per worker (RR) | 16 |
29-
| RR_DB_MAX_POOL_SIZE | Max. connections per worker (RR) | 32 |
30-
| RR_DB_ACQUIRE_CONNECTION_TIMEOUT | New connection timeout (ms) (RR) | 60000 |
23+
| READ_REPLICAS | Number of read replicas (RR0, RR1, ..., RRn) | 2 |
24+
| RR0_DB_HOST | PostgresSQL Hostname (RR) | |
25+
| RR0_DB_PORT | PostgreSQL Port (RR) | 5432 |
26+
| RR0_DB_USER | PostgreSQL Username (RR) | nostr_ts_relay |
27+
| RR0_DB_PASSWORD | PostgreSQL Password (RR) | nostr_ts_relay |
28+
| RR0_DB_NAME | PostgreSQL Database name (RR) | nostr_ts_relay |
29+
| RR0_DB_MIN_POOL_SIZE | Min. connections per worker (RR) | 16 |
30+
| RR0_DB_MAX_POOL_SIZE | Max. connections per worker (RR) | 32 |
31+
| RR0_DB_ACQUIRE_CONNECTION_TIMEOUT| New connection timeout (ms) (RR) | 60000 |
32+
| RR1_DB_HOST | PostgresSQL Hostname (RR) | |
33+
| RR1_DB_PORT | PostgreSQL Port (RR) | 5432 |
34+
| RR1_DB_USER | PostgreSQL Username (RR) | nostr_ts_relay |
35+
| RR1_DB_PASSWORD | PostgreSQL Password (RR) | nostr_ts_relay |
36+
| RR1_DB_NAME | PostgreSQL Database name (RR) | nostr_ts_relay |
37+
| RR1_DB_MIN_POOL_SIZE | Min. connections per worker (RR) | 16 |
38+
| RR1_DB_MAX_POOL_SIZE | Max. connections per worker (RR) | 32 |
39+
| RR1_DB_ACQUIRE_CONNECTION_TIMEOUT| New connection timeout (ms) (RR) | 60000 |
40+
| RRn_DB_HOST | PostgresSQL Hostname (RR) | |
41+
| RRn_DB_PORT | PostgreSQL Port (RR) | 5432 |
42+
| RRn_DB_USER | PostgreSQL Username (RR) | nostr_ts_relay |
43+
| RRn_DB_PASSWORD | PostgreSQL Password (RR) | nostr_ts_relay |
44+
| RRn_DB_NAME | PostgreSQL Database name (RR) | nostr_ts_relay |
45+
| RRn_DB_MIN_POOL_SIZE | Min. connections per worker (RR) | 16 |
46+
| RRn_DB_MAX_POOL_SIZE | Max. connections per worker (RR) | 32 |
47+
| RRn_DB_ACQUIRE_CONNECTION_TIMEOUT| New connection timeout (ms) (RR) | 60000 |
3148
| TOR_HOST | Tor Hostname | |
3249
| TOR_CONTROL_PORT | Tor control Port | 9051 |
3350
| TOR_PASSWORD | Tor control password | nostr_ts_relay |
@@ -41,6 +58,8 @@ The following environment variables can be set:
4158
| DEBUG | Debugging filter | |
4259
| ZEBEDEE_API_KEY | Zebedee Project API Key | |
4360

61+
If you've set READ_REPLICAS to 4, you should configure RR0_ through RR3_.
62+
4463
# Settings
4564

4665
Running `nostream` for the first time creates the settings file in `<project_root>/.nostr/settings.yaml`. If the file is not created and an error is thrown ensure that the `<project_root>/.nostr` folder exists. The configuration directory can be changed by setting the `NOSTR_CONFIG_DIR` environment variable.
@@ -54,6 +73,18 @@ Running `nostream` for the first time creates the settings file in `<project_roo
5473
| info.contact | Relay operator's contact. (e.g. mailto:[email protected]) |
5574
| network.maxPayloadSize | Maximum number of bytes accepted per WebSocket frame |
5675
| network.remoteIpHeader | HTTP header from proxy containing IP address from client. |
76+
| payments.enabled | Enabled payments. Defaults to false. |
77+
| payments.processor | Either `zebedee`, `lnbits`, `lnurl`. |
78+
| payments.feeSchedules.admission[].enabled | Enables admission fee. Defaults to false. |
79+
| payments.feeSchedules.admission[].amount | Admission fee amount in msats. |
80+
| payments.feeSchedules.admission[].whitelists.pubkeys | List of pubkeys to waive admission fee. |
81+
| payments.feeSchedules.admission[].whitelists.event_kinds | List of event kinds to waive admission fee. Use `[min, max]` for ranges. |
82+
| paymentProcessors.zebedee.baseURL | Zebedee's API base URL. |
83+
| paymentProcessors.zebedee.callbackBaseURL | Public-facing Nostream's Zebedee Callback URL (e.g. https://relay.your-domain.com/callbacks/zebedee) |
84+
| paymentProcessors.zebedee.ipWhitelist | List with Zebedee's API Production IPs. See [ZBD API Documentation](https://api-reference.zebedee.io/#c7e18276-6935-4cca-89ae-ad949efe9a6a) for more info. |
85+
| paymentProcessors.lnbits.baseURL | Base URL of your Lnbits instance. |
86+
| paymentProcessors.lnbits.callbackBaseURL | Public-facing Nostream's Lnbits Callback URL. (e.g. https://relay.your-domain.com/callbacks/lnbits) |
87+
| paymentProcessors.lnurl.invoiceURL | [LUD-06 Pay Request](https://github.com/lnurl/luds/blob/luds/06.md) provider URL. (e.g. https://getalby.com/lnurlp/your-username) |
5788
| mirroring.static[].address | Address of mirrored relay. (e.g. ws://100.100.100.100:8008) |
5889
| mirroring.static[].filters | Subscription filters used to mirror. |
5990
| mirroring.static[].secret | Secret to pass to relays. Nostream relays only. Optional. |

docker-compose.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ services:
1616
DB_MAX_POOL_SIZE: 64
1717
DB_ACQUIRE_CONNECTION_TIMEOUT: 60000
1818
# Read Replica
19-
READ_REPLICAS: 1
19+
READ_REPLICAS: 2
2020
READ_REPLICA_ENABLED: 'false'
2121
# Read Replica No. 1
2222
RR0_DB_HOST: db
@@ -36,6 +36,7 @@ services:
3636
RR1_DB_MIN_POOL_SIZE: 16
3737
RR1_DB_MAX_POOL_SIZE: 64
3838
RR1_DB_ACQUIRE_CONNECTION_TIMEOUT: 10000
39+
# Add RR2, RR3, etc. to configure more read replicas
3940
# Redis
4041
REDIS_HOST: nostream-cache
4142
REDIS_PORT: 6379

resources/default-settings.yaml

Lines changed: 87 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,14 @@ payments:
99
processor: zebedee
1010
feeSchedules:
1111
admission:
12-
- enabled: false
13-
description: Admission fee charged per public key in msats (1000 msats = 1 satoshi)
14-
amount: 1000000
15-
whitelists:
16-
pubkeys:
17-
- replace-with-your-pubkey-in-hex
18-
# Allow the following Zap providers:
19-
# LightningTipBot by Calle
20-
- "fcd720c38d9ee337188f47aac845dcd8f590ccdb4a928b76dde18187b4c9d37d"
12+
- enabled: false
13+
description: Admission fee charged per public key in msats (1000 msats = 1 satoshi)
14+
amount: 1000000
15+
whitelists:
16+
pubkeys:
17+
- replace-with-your-pubkey-in-hex
18+
event_kinds:
19+
- 9735 # Nip-57 Lightning Zap Receipts
2120
paymentsProcessors:
2221
zebedee:
2322
baseURL: https://api.zebedee.io/
@@ -43,24 +42,24 @@ mirroring:
4342
limits:
4443
invoice:
4544
rateLimits:
46-
- period: 60000
47-
rate: 12
48-
- period: 3600000
49-
rate: 30
45+
- period: 60000
46+
rate: 12
47+
- period: 3600000
48+
rate: 30
5049
ipWhitelist:
51-
- "::1"
52-
- "10.10.10.1"
53-
- "::ffff:10.10.10.1"
50+
- "::1"
51+
- "10.10.10.1"
52+
- "::ffff:10.10.10.1"
5453
connection:
5554
rateLimits:
56-
- period: 1000
57-
rate: 12
58-
- period: 60000
59-
rate: 48
55+
- period: 1000
56+
rate: 12
57+
- period: 60000
58+
rate: 48
6059
ipWhitelist:
61-
- "::1"
62-
- "10.10.10.1"
63-
- "::ffff:10.10.10.1"
60+
- "::1"
61+
- "10.10.10.1"
62+
- "::ffff:10.10.10.1"
6463
event:
6564
eventId:
6665
minLeadingZeroBits: 0
@@ -76,69 +75,69 @@ limits:
7675
maxPositiveDelta: 900
7776
maxNegativeDelta: 0
7877
content:
79-
- description: 64 KB for event kind ranges 0-10 and 40-49
80-
kinds:
81-
- - 0
82-
- 10
83-
- - 40
84-
- 49
85-
maxLength: 102400
86-
- description: 96 KB for event kind ranges 11-39 and 50-max
87-
kinds:
88-
- - 11
89-
- 39
90-
- - 50
91-
- 9007199254740991
92-
maxLength: 102400
78+
- description: 64 KB for event kind ranges 0-10 and 40-49
79+
maxLength: 102400
80+
kinds:
81+
- - 0
82+
- 10
83+
- - 40
84+
- 49
85+
- description: 96 KB for event kind ranges 11-39 and 50-max
86+
maxLength: 102400
87+
kinds:
88+
- - 11
89+
- 39
90+
- - 50
91+
- 9007199254740991
9392
rateLimits:
94-
- description: 6 events/min for event kinds 0, 3, 40 and 41
95-
kinds:
96-
- 0
97-
- 3
98-
- 40
99-
- 41
100-
period: 60000
101-
rate: 6
102-
- description: 12 events/min for event kinds 1, 2, 4 and 42
103-
kinds:
104-
- 1
105-
- 2
106-
- 4
107-
- 42
108-
period: 60000
109-
rate: 12
110-
- description: 30 events/min for event kind ranges 5-7 and 43-49
111-
kinds:
112-
- - 5
113-
- 7
114-
- - 43
115-
- 49
116-
period: 60000
117-
rate: 30
118-
- description: 24 events/min for replaceable events and parameterized replaceable
119-
events
120-
kinds:
121-
- - 10000
122-
- 19999
123-
- - 30000
124-
- 39999
125-
period: 60000
126-
rate: 24
127-
- description: 60 events/min for ephemeral events
128-
kinds:
129-
- - 20000
130-
- 29999
131-
period: 60000
132-
rate: 60
133-
- description: 720 events/hour for all events
134-
period: 3600000
135-
rate: 720
93+
- description: 6 events/min for event kinds 0, 3, 40 and 41
94+
kinds:
95+
- 0
96+
- 3
97+
- 40
98+
- 41
99+
period: 60000
100+
rate: 6
101+
- description: 12 events/min for event kinds 1, 2, 4 and 42
102+
kinds:
103+
- 1
104+
- 2
105+
- 4
106+
- 42
107+
period: 60000
108+
rate: 12
109+
- description: 30 events/min for event kind ranges 5-7 and 43-49
110+
kinds:
111+
- - 5
112+
- 7
113+
- - 43
114+
- 49
115+
period: 60000
116+
rate: 30
117+
- description: 24 events/min for replaceable events and parameterized replaceable
118+
events
119+
kinds:
120+
- - 10000
121+
- 19999
122+
- - 30000
123+
- 39999
124+
period: 60000
125+
rate: 24
126+
- description: 60 events/min for ephemeral events
127+
kinds:
128+
- - 20000
129+
- 29999
130+
period: 60000
131+
rate: 60
132+
- description: 720 events/hour for all events
133+
period: 3600000
134+
rate: 720
136135
whitelists:
137136
pubkeys: []
138137
ipAddresses:
139-
- "::1"
140-
- "10.10.10.1"
141-
- "::ffff:10.10.10.1"
138+
- "::1"
139+
- "10.10.10.1"
140+
- "::ffff:10.10.10.1"
142141
client:
143142
subscription:
144143
maxSubscriptions: 10
@@ -149,10 +148,10 @@ limits:
149148
minPrefixLength: 4
150149
message:
151150
rateLimits:
152-
- description: 240 raw messages/min
153-
period: 60000
154-
rate: 240
151+
- description: 240 raw messages/min
152+
period: 60000
153+
rate: 240
155154
ipWhitelist:
156-
- "::1"
157-
- "10.10.10.1"
158-
- "::ffff:10.10.10.1"
155+
- "::1"
156+
- "10.10.10.1"
157+
- "::ffff:10.10.10.1"

src/@types/settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ export interface Worker {
126126

127127
export interface FeeScheduleWhitelists {
128128
pubkeys?: Pubkey[]
129+
event_kinds?: (EventKinds | [EventKinds, EventKinds])[]
129130
}
130131

131132
export interface FeeSchedule {

src/constants/base.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export enum EventKinds {
55
CONTACT_LIST = 3,
66
ENCRYPTED_DIRECT_MESSAGE = 4,
77
DELETE = 5,
8+
REPOST = 6,
89
REACTION = 7,
910
// Channels
1011
CHANNEL_CREATION = 40,
@@ -17,6 +18,9 @@ export enum EventKinds {
1718
// Relay-only
1819
RELAY_INVITE = 50,
1920
INVOICE_UPDATE = 402,
21+
// Lightning zaps
22+
ZAP_REQUEST = 9734,
23+
ZAP_RECEIPT = 9735,
2024
// Replaceable events
2125
REPLACEABLE_FIRST = 10000,
2226
REPLACEABLE_LAST = 19999,

src/handlers/event-message-handler.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ export class EventMessageHandler implements IMessageHandler {
268268
const isApplicableFee = (feeSchedule: FeeSchedule) =>
269269
feeSchedule.enabled
270270
&& !feeSchedule.whitelists?.pubkeys?.some((prefix) => event.pubkey.startsWith(prefix))
271+
&& !feeSchedule.whitelists?.event_kinds?.some(isEventKindOrRangeMatch(event))
271272

272273
const feeSchedules = currentSettings.payments?.feeSchedules?.admission?.filter(isApplicableFee)
273274
if (!Array.isArray(feeSchedules) || !feeSchedules.length) {

0 commit comments

Comments
 (0)