forked from haven-protocol-org/monero-go-utils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaccount.go
85 lines (69 loc) · 1.99 KB
/
account.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
package monero
import (
"bytes"
"errors"
"io"
"github.com/ehmry/monero/crypto"
)
// Account contains public and private keys for the spend and view
// aspects of a Monero account.
type Account struct {
spendP, spendS [32]byte
viewP, viewS [32]byte
}
// Address returns the address of a given account.
func (a *Account) Address() *Address {
return &Address{spend: a.spendP, view: a.viewP}
}
func (a *Account) String() string {
return a.Address().String()
}
// Secret returns the spend secret key that
// can be used to regenerate the account.
func (a *Account) Secret() [32]byte {
return a.spendS
}
var NonDeterministic = errors.New("account is non-deterministic")
// Mnemonic returns an Electrum style mnemonic representation
// of the account spend secret key.
func (a *Account) Mnemonic() ([]string, error) {
ss := a.spendS[:]
var test [32]byte
crypto.ViewFromSpend(&test, &a.spendS)
if !bytes.Equal(a.viewS[:], test[:]) {
return nil, NonDeterministic
}
return BytesToWords(ss)
}
// Recover recovers an account using a secret key.
func RecoverAccount(secret [32]byte) (*Account, error) {
if !crypto.CheckSecret(&secret) {
return nil, crypto.InvalidSecret
}
a := &Account{spendS: secret}
crypto.PublicFromSecret(&a.spendP, &a.spendS)
crypto.ViewFromSpend(&a.viewS, &a.spendS)
crypto.PublicFromSecret(&a.viewP, &a.viewS)
return a, nil
}
// RecoverAccountWithMnemonic recovers an account
// with an Electrum style word list.
func RecoverAccountWithMnemonic(words []string) (*Account, error) {
var seed [32]byte
if err := WordsToBytes(&seed, words); err != nil {
return nil, err
}
return RecoverAccount(seed)
}
// GenerateAccountGenerates a new account.
func GenerateAccount(random io.Reader) (acc *Account, err error) {
acc = new(Account)
acc.spendS, err = crypto.GenerateSecret(random)
if err != nil {
return nil, err
}
crypto.PublicFromSecret(&acc.spendP, &acc.spendS)
crypto.ViewFromSpend(&acc.viewS, &acc.spendS)
crypto.PublicFromSecret(&acc.viewP, &acc.viewS)
return acc, nil
}