feat: reply OK to client-published events
nostrclient never answered a client's EVENT with the NIP-01 `["OK", <id>, <accepted>, <message>]` command result. Clients built on nostr-tools and similar libraries wait for that reply before treating a publish as successful, so NWC wallet apps paired through the public endpoint reported "publish failed" even though the request had been fanned out and answered. Relay OKs now flow through the message pool like events and notices. The router tracks each EVENT a client publishes and replies exactly once: `true` as soon as any relay accepts, `false` once every relay connected at publish time has rejected it, after a 10 s timeout, or immediately when no relay is connected. OKs nobody is waiting on are dropped at the pump so the shared result map cannot grow unbounded. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013Tbyw6FwjhEJg3gHfPHxWt
This commit is contained in:
parent
801ce44561
commit
7aa0ce14db
6 changed files with 277 additions and 4 deletions
21
tasks.py
21
tasks.py
|
|
@ -4,8 +4,13 @@ import threading
|
|||
from loguru import logger
|
||||
|
||||
from .crud import get_relays
|
||||
from .nostr.message_pool import EndOfStoredEventsMessage, EventMessage, NoticeMessage
|
||||
from .router import NostrRouter, nostr_client
|
||||
from .nostr.message_pool import (
|
||||
CommandResultMessage,
|
||||
EndOfStoredEventsMessage,
|
||||
EventMessage,
|
||||
NoticeMessage,
|
||||
)
|
||||
from .router import NostrRouter, all_routers, nostr_client
|
||||
|
||||
|
||||
async def init_relays():
|
||||
|
|
@ -55,12 +60,24 @@ async def subscribe_events():
|
|||
|
||||
NostrRouter.received_subscription_eosenotices[sub_id] = event_message
|
||||
|
||||
def callback_command_results(result_message: CommandResultMessage):
|
||||
event_id = result_message.event_id
|
||||
# Only keep OKs some client is still waiting on; the rest would
|
||||
# accumulate forever (events published by other relay users, or
|
||||
# results arriving after the client already got its reply).
|
||||
if not any(event_id in r.pending_publishes for r in all_routers):
|
||||
return
|
||||
NostrRouter.received_command_results.setdefault(event_id, []).append(
|
||||
result_message
|
||||
)
|
||||
|
||||
def wrap_async_subscribe():
|
||||
asyncio.run(
|
||||
nostr_client.subscribe(
|
||||
callback_events,
|
||||
callback_notices,
|
||||
callback_eose_notices,
|
||||
callback_command_results,
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue