nip46: switch_relays on the client side.
This commit is contained in:
@@ -16,11 +16,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type BunkerClient struct {
|
type BunkerClient struct {
|
||||||
|
Relays []string
|
||||||
|
|
||||||
serial atomic.Uint64
|
serial atomic.Uint64
|
||||||
clientSecretKey [32]byte
|
clientSecretKey [32]byte
|
||||||
pool *nostr.Pool
|
pool *nostr.Pool
|
||||||
target nostr.PubKey
|
target nostr.PubKey
|
||||||
relays []string
|
|
||||||
conversationKey [32]byte // nip44
|
conversationKey [32]byte // nip44
|
||||||
listeners *xsync.MapOf[string, chan Response]
|
listeners *xsync.MapOf[string, chan Response]
|
||||||
idPrefix string
|
idPrefix string
|
||||||
@@ -116,23 +117,27 @@ func NewBunker(
|
|||||||
|
|
||||||
clientPublicKey := nostr.GetPublicKey(clientSecretKey)
|
clientPublicKey := nostr.GetPublicKey(clientSecretKey)
|
||||||
conversationKey, _ := nip44.GenerateConversationKey(targetPublicKey, clientSecretKey)
|
conversationKey, _ := nip44.GenerateConversationKey(targetPublicKey, clientSecretKey)
|
||||||
|
now := nostr.Now()
|
||||||
|
|
||||||
bunker := &BunkerClient{
|
bunker := &BunkerClient{
|
||||||
pool: pool,
|
pool: pool,
|
||||||
clientSecretKey: clientSecretKey,
|
clientSecretKey: clientSecretKey,
|
||||||
target: targetPublicKey,
|
target: targetPublicKey,
|
||||||
relays: relays,
|
Relays: relays,
|
||||||
conversationKey: conversationKey,
|
conversationKey: conversationKey,
|
||||||
listeners: xsync.NewMapOf[string, chan Response](),
|
listeners: xsync.NewMapOf[string, chan Response](),
|
||||||
onAuth: onAuth,
|
onAuth: onAuth,
|
||||||
idPrefix: "nl-" + strconv.Itoa(rand.Intn(65536)),
|
idPrefix: "nl-" + strconv.Itoa(rand.Intn(65536)),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cancellableCtx, cancel := context.WithCancel(ctx)
|
||||||
|
_ = cancel
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
events := pool.SubscribeMany(ctx, relays, nostr.Filter{
|
events := pool.SubscribeMany(cancellableCtx, relays, nostr.Filter{
|
||||||
Tags: nostr.TagMap{"p": []string{clientPublicKey.Hex()}},
|
Tags: nostr.TagMap{"p": []string{clientPublicKey.Hex()}},
|
||||||
Kinds: []nostr.Kind{nostr.KindNostrConnect},
|
Kinds: []nostr.Kind{nostr.KindNostrConnect},
|
||||||
Since: nostr.Now(),
|
Since: now,
|
||||||
LimitZero: true,
|
LimitZero: true,
|
||||||
}, nostr.SubscriptionOptions{
|
}, nostr.SubscriptionOptions{
|
||||||
Label: "bunker46client",
|
Label: "bunker46client",
|
||||||
@@ -167,6 +172,14 @@ func NewBunker(
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
// attempt switch_relays once every 10 times
|
||||||
|
if now%10 == 0 {
|
||||||
|
if newRelays, _ := bunker.SwitchRelays(ctx); newRelays != nil {
|
||||||
|
cancel()
|
||||||
|
bunker = NewBunker(ctx, clientSecretKey, targetPublicKey, newRelays, pool, func(string) {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return bunker
|
return bunker
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,6 +191,15 @@ func (bunker *BunkerClient) Ping(ctx context.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (bunker *BunkerClient) SwitchRelays(ctx context.Context) ([]string, error) {
|
||||||
|
var res []string
|
||||||
|
_, err := bunker.RPC(ctx, "switch_relays", res)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (bunker *BunkerClient) GetPublicKey(ctx context.Context) (nostr.PubKey, error) {
|
func (bunker *BunkerClient) GetPublicKey(ctx context.Context) (nostr.PubKey, error) {
|
||||||
if bunker.getPublicKeyResponse != nostr.ZeroPK {
|
if bunker.getPublicKeyResponse != nostr.ZeroPK {
|
||||||
return bunker.getPublicKeyResponse, nil
|
return bunker.getPublicKeyResponse, nil
|
||||||
@@ -283,7 +305,7 @@ func (bunker *BunkerClient) RPC(ctx context.Context, method string, params []str
|
|||||||
relayConnectionWorked := make(chan struct{})
|
relayConnectionWorked := make(chan struct{})
|
||||||
bunkerConnectionWorked := make(chan struct{})
|
bunkerConnectionWorked := make(chan struct{})
|
||||||
|
|
||||||
for _, url := range bunker.relays {
|
for _, url := range bunker.Relays {
|
||||||
go func(url string) {
|
go func(url string) {
|
||||||
relay, err := bunker.pool.EnsureRelay(url)
|
relay, err := bunker.pool.EnsureRelay(url)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|||||||
@@ -5,14 +5,11 @@ import (
|
|||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
mrand "math/rand"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"fiatjaf.com/nostr"
|
"fiatjaf.com/nostr"
|
||||||
"fiatjaf.com/nostr/nip44"
|
"fiatjaf.com/nostr/nip44"
|
||||||
"github.com/puzpuzpuz/xsync/v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var NoConnectionReceived = errors.New("relay connections ended without a bunker connection established")
|
var NoConnectionReceived = errors.New("relay connections ended without a bunker connection established")
|
||||||
@@ -112,16 +109,17 @@ func NewBunkerFromNostrConnect(
|
|||||||
if req.Result != "" {
|
if req.Result != "" {
|
||||||
if req.Result == secret {
|
if req.Result == secret {
|
||||||
// secret validation passed - connection established
|
// secret validation passed - connection established
|
||||||
return &BunkerClient{
|
cancellableCtx, cancel := context.WithCancel(ctx)
|
||||||
pool: pool,
|
_ = cancel
|
||||||
clientSecretKey: clientSecretKey,
|
bunker := NewBunker(cancellableCtx, clientSecretKey, targetPublicKey, relayURLs, pool, func(string) {})
|
||||||
target: targetPublicKey,
|
|
||||||
relays: relayURLs,
|
// attempt switch_relays
|
||||||
conversationKey: conversationKey,
|
if newRelays, _ := bunker.SwitchRelays(ctx); newRelays != nil {
|
||||||
listeners: xsync.NewMapOf[string, chan Response](),
|
cancel()
|
||||||
onAuth: func(string) {},
|
bunker = NewBunker(ctx, clientSecretKey, targetPublicKey, newRelays, pool, func(string) {})
|
||||||
idPrefix: "nl-" + strconv.Itoa(mrand.Intn(65536)),
|
}
|
||||||
}, nil
|
|
||||||
|
return bunker, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user