Refactor code with nip47Client struct

This commit is contained in:
ekzyis 2025-07-30 23:02:52 +02:00
parent a610af7bb6
commit 534ff92d5d
1 changed files with 61 additions and 36 deletions

View File

@ -10,6 +10,12 @@ import (
"github.com/urfave/cli/v3"
)
type nip47Client struct {
Relay string
WalletPubkey nostr.PubKey
Secret nostr.SecretKey
}
var nwc = &cli.Command{
Name: "nwc",
Usage: "nip47 stuff",
@ -26,71 +32,90 @@ var nwc = &cli.Command{
Name: "info",
Usage: "get info event (kind 13194)",
Action: func(ctx context.Context, c *cli.Command) error {
walletURL := c.String("url")
url := c.String("url")
relay, walletPubkey, _, err := parseWalletConnectURL(walletURL)
client, err := newNip47ClientFromUrl(url)
if err != nil {
return fmt.Errorf("failed to parse url: %w", err)
}
r, err := nostr.RelayConnect(ctx, relay, nostr.RelayOptions{})
info, err := client.info(ctx)
if err != nil {
return fmt.Errorf("failed to connect to relay %s: %w", relay, err)
return fmt.Errorf("failed to get info: %w", err)
}
defer r.Close()
sub, err := r.Subscribe(ctx, nostr.Filter{
Kinds: []nostr.Kind{13194},
Authors: []nostr.PubKey{walletPubkey},
}, nostr.SubscriptionOptions{})
if err != nil {
return fmt.Errorf("failed to subscribe: %w", err)
}
defer sub.Close()
for {
select {
case ev := <-sub.Events:
stdout(ev)
return nil
case <-ctx.Done():
return fmt.Errorf("timed out waiting for info event")
}
}
stdout(info)
return nil
},
},
},
}
func parseWalletConnectURL(walletURL string) (relay string, walletPubkey nostr.PubKey, secret string, err error) {
if !strings.HasPrefix(walletURL, "nostr+walletconnect://") {
return "", nostr.PubKey{}, "", fmt.Errorf("must start with nostr+walletconnect://")
func newNip47ClientFromUrl(nwcUrl string) (*nip47Client, error) {
if !strings.HasPrefix(nwcUrl, "nostr+walletconnect://") {
return nil, fmt.Errorf("must start with nostr+walletconnect://")
}
parts := strings.SplitN(walletURL, "?", 2)
parts := strings.SplitN(nwcUrl, "?", 2)
if len(parts) != 2 {
return "", nostr.PubKey{}, "", fmt.Errorf("query not found")
return nil, fmt.Errorf("query not found")
}
walletPubkey, err = nostr.PubKeyFromHex(strings.TrimPrefix(parts[0], "nostr+walletconnect://"))
walletPubkey, err := nostr.PubKeyFromHex(strings.TrimPrefix(parts[0], "nostr+walletconnect://"))
if err != nil {
return "", nostr.PubKey{}, "", fmt.Errorf("invalid wallet pubkey: %w", err)
return nil, fmt.Errorf("invalid wallet pubkey: %w", err)
}
params, err := url.ParseQuery(parts[1])
if err != nil {
return "", nostr.PubKey{}, "", fmt.Errorf("invalid query: %w", err)
return nil, fmt.Errorf("invalid query: %w", err)
}
relay = params.Get("relay")
relay := params.Get("relay")
if relay == "" {
return "", nostr.PubKey{}, "", fmt.Errorf("relay missing")
return nil, fmt.Errorf("relay missing")
}
secret = params.Get("secret")
secret := params.Get("secret")
if secret == "" {
return "", nostr.PubKey{}, "", fmt.Errorf("secret missing")
return nil, fmt.Errorf("secret missing")
}
return relay, walletPubkey, secret, nil
sk, err := nostr.SecretKeyFromHex(secret)
if err != nil {
return nil, fmt.Errorf("invalid secret: %w", err)
}
return &nip47Client{
Relay: relay,
WalletPubkey: walletPubkey,
Secret: sk,
}, nil
}
// fetch info event (kind 13194)
func (c *nip47Client) info(ctx context.Context) (*nostr.Event, error) {
r, err := nostr.RelayConnect(ctx, c.Relay, nostr.RelayOptions{})
if err != nil {
return nil, err
}
defer r.Close()
sub, err := r.Subscribe(ctx, nostr.Filter{
Kinds: []nostr.Kind{13194},
Authors: []nostr.PubKey{c.WalletPubkey},
}, nostr.SubscriptionOptions{})
if err != nil {
return nil, err
}
defer sub.Close()
for {
select {
case ev := <-sub.Events:
return &ev, nil
case <-ctx.Done():
return nil, fmt.Errorf("timed out waiting for info event")
}
}
}