-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
api.go
92 lines (78 loc) · 2.59 KB
/
api.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
package handcash
import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"github.com/bitcoinsv/bsvd/bsvec"
"github.com/libsv/go-bk/bec"
)
// getRequestSignature will return the request signature
//
// Specs: https://github.com/HandCash/handcash-connect-sdk-js/blob/00300de6d225fa37fe2f4a5efe315dd08dd4beb9/src/api/http_request_factory.js#L16
func getRequestSignature(method, endpoint string, body interface{}, timestamp string,
privateKey *bec.PrivateKey) ([]byte, error) {
// Create the signature hash
signatureHash, err := getRequestSignatureHash(method, endpoint, body, timestamp)
if err != nil {
return nil, err
}
// Sign using private key
var sig *bec.Signature
if sig, err = privateKey.Sign(signatureHash); err != nil {
return nil, err
}
// Return the serialized signature string
return sig.Serialise(), nil
}
// getRequestSignatureHash will return the signature hash
//
// Specs: https://github.com/HandCash/handcash-connect-sdk-js/blob/00300de6d225fa37fe2f4a5efe315dd08dd4beb9/src/api/http_request_factory.js#L34
func getRequestSignatureHash(method, endpoint string, body interface{},
timestamp string) ([]byte, error) {
// Default if not set
bodyString := emptyBody
if body != nil {
bodyBytes, err := json.Marshal(body)
if err != nil {
return nil, fmt.Errorf("failed to marshal body %w", err)
}
bodyString = string(bodyBytes)
}
// Set the signature string
signatureString := fmt.Sprintf("%s\n%s\n%s\n%s", method, endpoint, timestamp, bodyString)
hash := sha256.Sum256([]byte(signatureString))
return hash[:], nil
}
// getSignedRequest returns the request with signature
//
// Specs: https://github.com/HandCash/handcash-connect-sdk-js/blob/00300de6d225fa37fe2f4a5efe315dd08dd4beb9/src/api/http_request_factory.js#L34
func (c *Client) getSignedRequest(method, endpoint, authToken string,
body interface{}, timestamp string) (*signedRequest, error) {
// Decode token
tokenBytes, err := hex.DecodeString(authToken)
if err != nil {
return nil, err
}
// Get key pairs
privateKey, publicKey := bec.PrivKeyFromBytes(bsvec.S256(), tokenBytes)
// Get the request signature
var requestSignature []byte
if requestSignature, err = getRequestSignature(
method, endpoint, body, timestamp, privateKey,
); err != nil {
return nil, err
}
// Return the signed request
return &signedRequest{
Body: body,
Headers: oAuthHeaders{
OauthPublicKey: hex.EncodeToString(publicKey.SerialiseCompressed()),
OauthSignature: hex.EncodeToString(requestSignature),
OauthTimestamp: timestamp,
},
JSON: true,
Method: method,
URI: c.Environment.APIURL + endpoint,
}, nil
}