forked from bitcoin-sv/spv-wallet-go-client
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient_options.go
141 lines (115 loc) · 3.25 KB
/
client_options.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package walletclient
import (
"fmt"
"net/http"
"net/url"
"github.com/bitcoinschema/go-bitcoin/v2"
"github.com/libsv/go-bk/bec"
"github.com/libsv/go-bk/wif"
"github.com/pkg/errors"
)
// configurator is the interface for configuring WalletClient
type configurator interface {
Configure(c *WalletClient)
}
// xPrivConf sets the xPrivString field of a WalletClient
type xPrivConf struct {
XPrivString string
}
func (w *xPrivConf) Configure(c *WalletClient) {
var err error
if c.xPriv, err = bitcoin.GenerateHDKeyFromString(w.XPrivString); err != nil {
c.xPriv = nil
}
}
// xPubConf sets the xPubString on the client
type xPubConf struct {
XPubString string
}
func (w *xPubConf) Configure(c *WalletClient) {
var err error
if c.xPub, err = bitcoin.GetHDKeyFromExtendedPublicKey(w.XPubString); err != nil {
c.xPub = nil
}
}
// accessKeyConf sets the accessKeyString on the client
type accessKeyConf struct {
AccessKeyString string
}
func (w *accessKeyConf) Configure(c *WalletClient) {
var err error
if c.accessKey, err = w.initializeAccessKey(); err != nil {
c.accessKey = nil
}
}
// adminKeyConf sets the admin key for creating new xpubs
type adminKeyConf struct {
AdminKeyString string
}
func (w *adminKeyConf) Configure(c *WalletClient) {
var err error
c.adminXPriv, err = bitcoin.GenerateHDKeyFromString(w.AdminKeyString)
if err != nil {
c.adminXPriv = nil
}
}
// httpConf sets the URL and httpConf client of a WalletClient
type httpConf struct {
ServerURL string
HTTPClient *http.Client
}
func (w *httpConf) Configure(c *WalletClient) {
// Ensure the ServerURL ends with a clean base URL
baseURL, err := validateAndCleanURL(w.ServerURL)
if err != nil {
// Handle the error appropriately
fmt.Println("Invalid URL provided:", err)
return
}
const basePath = "/v1"
c.server = fmt.Sprintf("%s%s", baseURL, basePath)
c.httpClient = w.HTTPClient
if w.HTTPClient != nil {
c.httpClient = w.HTTPClient
} else {
c.httpClient = http.DefaultClient
}
}
// signRequest configures whether to sign HTTP requests
type signRequest struct {
Sign bool
}
func (w *signRequest) Configure(c *WalletClient) {
c.signRequest = w.Sign
}
// initializeAccessKey handles the specific initialization of the access key.
func (w *accessKeyConf) initializeAccessKey() (*bec.PrivateKey, error) {
var err error
var privateKey *bec.PrivateKey
var decodedWIF *wif.WIF
if decodedWIF, err = wif.DecodeWIF(w.AccessKeyString); err != nil {
if privateKey, err = bitcoin.PrivateKeyFromString(w.AccessKeyString); err != nil {
return nil, errors.Wrap(err, "failed to decode access key")
}
} else {
privateKey = decodedWIF.PrivKey
}
return privateKey, nil
}
// validateAndCleanURL ensures that the provided URL is valid, and strips it down to just the base URL.
func validateAndCleanURL(rawURL string) (string, error) {
if rawURL == "" {
return "", fmt.Errorf("empty URL")
}
// Parse the URL to validate it
parsedURL, err := url.Parse(rawURL)
if err != nil {
return "", fmt.Errorf("parsing URL failed: %w", err)
}
// Rebuild the URL with only the scheme and host (and port if included)
cleanedURL := fmt.Sprintf("%s://%s", parsedURL.Scheme, parsedURL.Host)
if parsedURL.Path == "" || parsedURL.Path == "/" {
return cleanedURL, nil
}
return cleanedURL, nil
}