From ae076a7be27a4e7ecf1a2921e4045e4eaa76d418 Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Mon, 21 Jul 2025 17:21:30 -0300 Subject: [PATCH] nip46: hopefully fix "send on closed channel" cases on client responses. --- nip46/client.go | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/nip46/client.go b/nip46/client.go index aa49805..d7b108a 100644 --- a/nip46/client.go +++ b/nip46/client.go @@ -24,7 +24,6 @@ type BunkerClient struct { relays []string conversationKey [32]byte // nip44 listeners *xsync.MapOf[string, chan Response] - expectingAuth *xsync.MapOf[string, struct{}] idPrefix string onAuth func(string) @@ -126,9 +125,8 @@ func NewBunker( relays: relays, conversationKey: conversationKey, listeners: xsync.NewMapOf[string, chan Response](), - expectingAuth: xsync.NewMapOf[string, struct{}](), onAuth: onAuth, - idPrefix: "gn-" + strconv.Itoa(rand.Intn(65536)), + idPrefix: "nl-" + strconv.Itoa(rand.Intn(65536)), } go func() { @@ -159,13 +157,11 @@ func NewBunker( if resp.Result == "auth_url" { // special case authURL := resp.Error - if _, ok := bunker.expectingAuth.Load(resp.ID); ok { - bunker.onAuth(authURL) - } + bunker.onAuth(authURL) continue } - if dispatcher, ok := bunker.listeners.Load(resp.ID); ok { + if dispatcher, ok := bunker.listeners.LoadAndDelete(resp.ID); ok { dispatcher <- resp continue } @@ -282,12 +278,9 @@ func (bunker *BunkerClient) RPC(ctx context.Context, method string, params []str return "", fmt.Errorf("failed to sign request event: %w", err) } - respWaiter := make(chan Response) - bunker.listeners.Store(id, respWaiter) - defer func() { - bunker.listeners.Delete(id) - close(respWaiter) - }() + dispatcher := make(chan Response) + bunker.listeners.Store(id, dispatcher) + defer bunker.listeners.Delete(id) relayConnectionWorked := make(chan struct{}) bunkerConnectionWorked := make(chan struct{}) @@ -324,7 +317,7 @@ func (bunker *BunkerClient) RPC(ctx context.Context, method string, params []str select { case <-ctx.Done(): return "", fmt.Errorf("context canceled") - case resp := <-respWaiter: + case resp := <-dispatcher: if resp.Error != "" { return "", fmt.Errorf("response error: %s", resp.Error) }