uri.go raw
1 package nwc
2
3 import (
4 "errors"
5 "net/url"
6
7 "next.orly.dev/pkg/lol/chk"
8 "next.orly.dev/pkg/nostr/crypto/encryption"
9 "next.orly.dev/pkg/nostr/interfaces/signer/p8k"
10 "next.orly.dev/pkg/nostr/encoders/hex"
11 "next.orly.dev/pkg/nostr/interfaces/signer"
12 )
13
14 type ConnectionParams struct {
15 clientSecretKey signer.I
16 walletPublicKey []byte
17 conversationKey []byte
18 relay string
19 }
20
21 // GetWalletPublicKey returns the wallet public key from the ConnectionParams.
22 func (c *ConnectionParams) GetWalletPublicKey() []byte {
23 return c.walletPublicKey
24 }
25
26 // GetConversationKey returns the conversation key from the ConnectionParams.
27 func (c *ConnectionParams) GetConversationKey() []byte {
28 return c.conversationKey
29 }
30
31 func ParseConnectionURI(nwcUri string) (parts *ConnectionParams, err error) {
32 var p *url.URL
33 if p, err = url.Parse(nwcUri); chk.E(err) {
34 return
35 }
36 if p == nil {
37 err = errors.New("invalid uri")
38 return
39 }
40 parts = &ConnectionParams{}
41 if p.Scheme != "nostr+walletconnect" {
42 err = errors.New("incorrect scheme")
43 return
44 }
45 if parts.walletPublicKey, err = hex.Dec(p.Host); chk.E(err) {
46 err = errors.New("invalid public key")
47 return
48 }
49 query := p.Query()
50 var ok bool
51 var relay []string
52 if relay, ok = query["relay"]; !ok {
53 err = errors.New("missing relay parameter")
54 return
55 }
56 if len(relay) == 0 {
57 return nil, errors.New("no relays")
58 }
59 parts.relay = relay[0]
60 var secret string
61 if secret = query.Get("secret"); secret == "" {
62 err = errors.New("missing secret parameter")
63 return
64 }
65 var secretBytes []byte
66 if secretBytes, err = hex.Dec(secret); chk.E(err) {
67 err = errors.New("invalid secret")
68 return
69 }
70 var clientKey *p8k.Signer
71 if clientKey, err = p8k.New(); chk.E(err) {
72 return
73 }
74 if err = clientKey.InitSec(secretBytes); chk.E(err) {
75 return
76 }
77 parts.clientSecretKey = clientKey
78 if parts.conversationKey, err = encryption.GenerateConversationKey(
79 clientKey.Sec(),
80 parts.walletPublicKey,
81 ); chk.E(err) {
82 return
83 }
84 return
85 }
86