-
Notifications
You must be signed in to change notification settings - Fork 26
/
safe_user.go
65 lines (60 loc) · 1.71 KB
/
safe_user.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
package bot
import (
"context"
"crypto/ed25519"
"encoding/base64"
"encoding/hex"
"encoding/json"
"time"
"github.com/MixinNetwork/mixin/crypto"
)
// If you want to register safe user, you need to call UpdateTipPin upgrade TIP PIN first.
func RegisterSafe(ctx context.Context, userId, spendPrivateKeySeed string, su *SafeUser) (*User, error) {
s, err := hex.DecodeString(spendPrivateKeySeed)
if err != nil {
return nil, err
}
private := ed25519.NewKeyFromSeed(s)
h := crypto.Sha256Hash([]byte(userId))
signBytes := ed25519.Sign(private, h[:])
signature := base64.RawURLEncoding.EncodeToString(signBytes[:])
publicKey := hex.EncodeToString(private[32:])
tipBody := TIPBodyForSequencerRegister(userId, publicKey)
pinBuf, err := hex.DecodeString(su.SpendPrivateKey)
if err != nil {
return nil, err
}
if su.SpendPrivateKey != hex.EncodeToString(private) {
panic("please use the same spend private key with tip private key")
}
sigBuf := ed25519.Sign(ed25519.PrivateKey(pinBuf), tipBody)
encryptedPIN, err := EncryptEd25519PIN(hex.EncodeToString(sigBuf), uint64(time.Now().UnixNano()), su)
if err != nil {
return nil, err
}
data, _ := json.Marshal(map[string]string{
"public_key": publicKey,
"signature": signature,
"pin_base64": encryptedPIN,
})
token, err := SignAuthenticationToken("POST", "/safe/users", string(data), su)
if err != nil {
return nil, err
}
body, err := Request(ctx, "POST", "/safe/users", data, token)
if err != nil {
return nil, err
}
var resp struct {
Data *User `json:"data"`
Error *Error `json:"error,omitempty"`
}
err = json.Unmarshal(body, &resp)
if err != nil {
return nil, err
}
if resp.Error != nil {
return nil, resp.Error
}
return resp.Data, nil
}