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).
|
// kindStreamMessage is the Buzz chat message kind (NIP-29 style).
|
||||||
const kindStreamMessage = 9
|
const kindStreamMessage = 9
|
||||||
|
|
||||||
|
const subscribeTimeout = 15 * time.Second
|
||||||
|
|
||||||
// BuzzChannel implements the Channel interface for a Buzz relay.
|
// BuzzChannel implements the Channel interface for a Buzz relay.
|
||||||
type BuzzChannel struct {
|
type BuzzChannel struct {
|
||||||
*channels.BaseChannel
|
*channels.BaseChannel
|
||||||
|
|
@ -169,6 +171,60 @@ func (c *BuzzChannel) Start(ctx context.Context) error {
|
||||||
return nil
|
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.
|
// Stop closes the subscription and disconnects from the relay.
|
||||||
func (c *BuzzChannel) Stop(ctx context.Context) error {
|
func (c *BuzzChannel) Stop(ctx context.Context) error {
|
||||||
logger.InfoC("buzz", "Stopping Buzz channel")
|
logger.InfoC("buzz", "Stopping Buzz channel")
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue