feat: add support for NIP22

This commit is contained in:
Vlad Stan 2023-02-09 12:18:54 +02:00
parent 868e02d3c2
commit f5c873ec4d
4 changed files with 158 additions and 3 deletions

View file

@ -1,6 +1,6 @@
import json import json
import time import time
from typing import Any, Awaitable, Callable, List, Optional from typing import Any, Awaitable, Callable, List, Optional, Tuple
from fastapi import WebSocket from fastapi import WebSocket
from loguru import logger from loguru import logger
@ -167,6 +167,12 @@ class NostrClientConnection:
await self._send_msg(resp_nip20) await self._send_msg(resp_nip20)
return None return None
in_range, message = self._created_at_in_range(e.created_at)
if not in_range:
resp_nip20 += [False, message]
await self._send_msg(resp_nip20)
return None
try: try:
if e.is_replaceable_event(): if e.is_replaceable_event():
await delete_events( await delete_events(
@ -186,6 +192,7 @@ class NostrClientConnection:
resp_nip20 += [event != None, message] resp_nip20 += [event != None, message]
await self._send_msg(resp_nip20) await self._send_msg(resp_nip20)
@property @property
def client_config(self) -> ClientConfig: def client_config(self) -> ClientConfig:
@ -241,3 +248,13 @@ class NostrClientConnection:
self._event_count_per_timestamp = 0 self._event_count_per_timestamp = 0
return self._event_count_per_timestamp > self.client_config.max_events_per_second return self._event_count_per_timestamp > self.client_config.max_events_per_second
def _created_at_in_range(self, created_at: int) -> Tuple[bool, str]:
current_time = round(time.time())
if self.client_config.created_at_in_past != 0:
if created_at < (current_time - self.client_config.created_at_in_past):
return False, "created_at is too much into the past"
if self.client_config.created_at_in_future != 0:
if created_at > (current_time + self.client_config.created_at_in_future):
return False, "created_at is too much into the future"
return True, ""

View file

@ -12,6 +12,17 @@ class ClientConfig(BaseModel):
max_client_filters = Field(0, alias="maxClientFilters") max_client_filters = Field(0, alias="maxClientFilters")
limit_per_filter = Field(1000, alias="limitPerFilter") limit_per_filter = Field(1000, alias="limitPerFilter")
max_events_per_second = Field(0, alias="maxEventsPerSecond") max_events_per_second = Field(0, alias="maxEventsPerSecond")
created_at_days_past = Field(0, alias="createdAtDaysPast")
created_at_hours_past = Field(0, alias="createdAtHoursPast")
created_at_minutes_past = Field(0, alias="createdAtMinutesPast")
created_at_seconds_past = Field(0, alias="createdAtSecondsPast")
created_at_days_future = Field(0, alias="createdAtDaysFuture")
created_at_hours_future = Field(0, alias="createdAtHoursFuture")
created_at_minutes_future = Field(0, alias="createdAtMinutesFuture")
created_at_seconds_future = Field(0, alias="createdAtSecondsFuture")
allowed_public_keys = Field([], alias="allowedPublicKeys") allowed_public_keys = Field([], alias="allowedPublicKeys")
blocked_public_keys = Field([], alias="blockedPublicKeys") blocked_public_keys = Field([], alias="blockedPublicKeys")
@ -23,7 +34,15 @@ class ClientConfig(BaseModel):
return True return True
# todo: check payment # todo: check payment
return p in self.allowed_public_keys return p in self.allowed_public_keys
@property
def created_at_in_past(self) -> int:
return self.created_at_days_past * 86400 + self.created_at_hours_past * 3600 + self.created_at_minutes_past * 60 + self.created_at_seconds_past
@property
def created_at_in_future(self) -> int:
return self.created_at_days_future * 86400 + self.created_at_hours_future * 3600 + self.created_at_minutes_future * 60 + self.created_at_seconds_future
class Config: class Config:
allow_population_by_field_name = True allow_population_by_field_name = True
class RelayConfig(ClientConfig): class RelayConfig(ClientConfig):
@ -55,7 +74,7 @@ class NostrRelay(BaseModel):
def info(cls,) -> dict: def info(cls,) -> dict:
return { return {
"contact": "https://t.me/lnbits", "contact": "https://t.me/lnbits",
"supported_nips": [1, 9, 11, 15, 20], "supported_nips": [1, 9, 11, 15, 20, 22],
"software": "LNbits", "software": "LNbits",
"version": "", "version": "",
} }

View file

@ -156,6 +156,108 @@
</q-tab-panel> </q-tab-panel>
<q-tab-panel name="config"> <q-tab-panel name="config">
<div v-if="relay"> <div v-if="relay">
<div class="row items-center no-wrap q-mb-md">
<div class="col-3 q-pr-lg">Created At in Past:</div>
<div class="col-2 q-pr-lg">
<q-input
filled
dense
v-model.trim="relay.config.createdAtDaysPast"
type="number"
min="0"
hint="Days"
></q-input>
</div>
<div class="col-2 q-pr-lg">
<q-select
filled
dense
v-model="relay.config.createdAtHoursPast"
type="number"
hint="Hours"
:options="hours"
></q-select>
</div>
<div class="col-2 q-pr-lg">
<q-select
filled
dense
v-model="relay.config.createdAtMinutesPast"
type="number"
hint="Minutes"
:options="range60"
></q-select>
</div>
<div class="col-2 q-pr-lg">
<q-select
filled
dense
v-model="relay.config.createdAtSecondsPast"
type="number"
hint="Seconds"
:options="range60"
></q-select>
</div>
<div class="col-1 q-pb-md">
<q-icon name="info" class="cursor-pointer">
<q-tooltip>
NIP 22: Lower limit within which a relay will consider an
event's created_at to be acceptable.
</q-tooltip></q-icon
>
</div>
</div>
<div class="row items-center no-wrap q-mb-md">
<div class="col-3 q-pr-lg">Created At in Future:</div>
<div class="col-2 q-pr-lg">
<q-input
filled
dense
v-model.trim="relay.config.createdAtDaysFuture"
type="number"
min="0"
hint="Days"
></q-input>
</div>
<div class="col-2 q-pr-lg">
<q-select
filled
dense
v-model="relay.config.createdAtHoursFuture"
type="number"
hint="Hours"
:options="hours"
></q-select>
</div>
<div class="col-2 q-pr-lg">
<q-select
filled
dense
v-model="relay.config.createdAtMinutesFuture"
type="number"
hint="Minutes"
:options="range60"
></q-select>
</div>
<div class="col-2 q-pr-lg">
<q-select
filled
dense
v-model="relay.config.createdAtSecondsFuture"
type="number"
hint="Seconds"
:options="range60"
></q-select>
</div>
<div class="col-1 q-pb-md">
<q-icon name="info" class="cursor-pointer">
<q-tooltip>
NIP 22: Upper limit within which a relay will consider an
event's created_at to be acceptable.
</q-tooltip></q-icon
>
</div>
</div>
<div class="row items-center no-wrap q-mb-md"> <div class="row items-center no-wrap q-mb-md">
<div class="col-3 q-pr-lg">Limit per filter:</div> <div class="col-3 q-pr-lg">Limit per filter:</div>
<div class="col-3 q-pr-lg"> <div class="col-3 q-pr-lg">

View file

@ -21,6 +21,23 @@ async function relayDetails(path) {
} }
}, },
computed: {
hours: function () {
const y = []
for (let i = 0; i <= 24; i++) {
y.push(i)
}
return y
},
range60: function () {
const y = []
for (let i = 0; i <= 60; i++) {
y.push(i)
}
return y
}
},
methods: { methods: {
satBtc(val, showUnit = true) { satBtc(val, showUnit = true) {
return satOrBtc(val, showUnit, this.satsDenominated) return satOrBtc(val, showUnit, this.satsDenominated)