fix(buzz): restore relay-driven NIP-42 subscription
This commit is contained in:
parent
02961af54f
commit
b8bf0ab34f
1 changed files with 56 additions and 0 deletions
|
|
@ -24,6 +24,8 @@ import (
|
|||
// kindStreamMessage is the Buzz chat message kind (NIP-29 style).
|
||||
const kindStreamMessage = 9
|
||||
|
||||
const subscribeTimeout = 15 * time.Second
|
||||
|
||||
// BuzzChannel implements the Channel interface for a Buzz relay.
|
||||
type BuzzChannel struct {
|
||||
*channels.BaseChannel
|
||||
|
|
@ -169,6 +171,60 @@ func (c *BuzzChannel) Start(ctx context.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// subscribeAuthed subscribes, performing the NIP-42 handshake if the relay
|
||||
// demands it. The relay rejection establishes that its challenge has been
|
||||
// received by go-nostr before Auth signs the response.
|
||||
func (c *BuzzChannel) subscribeAuthed(
|
||||
ctx context.Context,
|
||||
filters nostr.Filters,
|
||||
) (*nostr.Subscription, error) {
|
||||
sub, err := c.relay.Subscribe(ctx, filters)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("buzz subscribe failed: %w", err)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
case <-sub.EndOfStoredEvents:
|
||||
return sub, nil
|
||||
case reason := <-sub.ClosedReason:
|
||||
if !strings.HasPrefix(reason, "auth-required") {
|
||||
return nil, fmt.Errorf("buzz relay closed subscription: %s", reason)
|
||||
}
|
||||
sub.Unsub()
|
||||
if err := c.relay.Auth(ctx, func(evt *nostr.Event) error {
|
||||
return evt.Sign(c.secretKey)
|
||||
}); err != nil {
|
||||
return nil, fmt.Errorf("buzz NIP-42 auth failed: %w", err)
|
||||
}
|
||||
logger.InfoCF("buzz", "Authenticated to relay", map[string]any{
|
||||
"relay": c.config.RelayURL, "pubkey": c.publicKey,
|
||||
})
|
||||
|
||||
authed, err := c.relay.Subscribe(ctx, filters)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("buzz subscribe after auth failed: %w", err)
|
||||
}
|
||||
const postAuthGrace = 3 * time.Second
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
case <-authed.EndOfStoredEvents:
|
||||
return authed, nil
|
||||
case reason := <-authed.ClosedReason:
|
||||
return nil, fmt.Errorf("buzz relay rejected subscription after auth: %s", reason)
|
||||
case <-time.After(postAuthGrace):
|
||||
logger.InfoCF("buzz", "Subscription accepted after auth (no EOSE)", map[string]any{
|
||||
"relay": c.config.RelayURL,
|
||||
})
|
||||
return authed, nil
|
||||
}
|
||||
case <-time.After(subscribeTimeout):
|
||||
return nil, fmt.Errorf("buzz timed out waiting for relay to accept subscription")
|
||||
}
|
||||
}
|
||||
|
||||
// Stop closes the subscription and disconnects from the relay.
|
||||
func (c *BuzzChannel) Stop(ctx context.Context) error {
|
||||
logger.InfoC("buzz", "Stopping Buzz channel")
|
||||
|
|
|
|||
Loading…
Reference in a new issue