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 time
from typing import Any, Awaitable, Callable, List, Optional
from typing import Any, Awaitable, Callable, List, Optional, Tuple
from fastapi import WebSocket
from loguru import logger
@ -167,6 +167,12 @@ class NostrClientConnection:
await self._send_msg(resp_nip20)
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:
if e.is_replaceable_event():
await delete_events(
@ -186,6 +192,7 @@ class NostrClientConnection:
resp_nip20 += [event != None, message]
await self._send_msg(resp_nip20)
@property
def client_config(self) -> ClientConfig:
@ -241,3 +248,13 @@ class NostrClientConnection:
self._event_count_per_timestamp = 0
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")
limit_per_filter = Field(1000, alias="limitPerFilter")
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")
blocked_public_keys = Field([], alias="blockedPublicKeys")
@ -23,7 +34,15 @@ class ClientConfig(BaseModel):
return True
# todo: check payment
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:
allow_population_by_field_name = True
class RelayConfig(ClientConfig):
@ -55,7 +74,7 @@ class NostrRelay(BaseModel):
def info(cls,) -> dict:
return {
"contact": "https://t.me/lnbits",
"supported_nips": [1, 9, 11, 15, 20],
"supported_nips": [1, 9, 11, 15, 20, 22],
"software": "LNbits",
"version": "",
}

View file

@ -156,6 +156,108 @@
</q-tab-panel>
<q-tab-panel name="config">
<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="col-3 q-pr-lg">Limit per filter:</div>
<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: {
satBtc(val, showUnit = true) {
return satOrBtc(val, showUnit, this.satsDenominated)