/
accounts.go
173 lines (151 loc) · 4.54 KB
/
accounts.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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package api
import (
"context"
"encoding/hex"
"sort"
log "github.com/sirupsen/logrus"
"github.com/bytom/account"
"github.com/bytom/common"
"github.com/bytom/consensus"
"github.com/bytom/crypto/ed25519/chainkd"
"github.com/bytom/protocol/vm/vmutil"
)
// POST /create-account
func (a *API) createAccount(ctx context.Context, ins struct {
RootXPubs []chainkd.XPub `json:"root_xpubs"`
Quorum int `json:"quorum"`
Alias string `json:"alias"`
}) Response {
acc, err := a.wallet.AccountMgr.Create(ins.RootXPubs, ins.Quorum, ins.Alias)
if err != nil {
return NewErrorResponse(err)
}
annotatedAccount := account.Annotated(acc)
log.WithField("account ID", annotatedAccount.ID).Info("Created account")
return NewSuccessResponse(annotatedAccount)
}
// AccountInfo is request struct for deleteAccount
type AccountInfo struct {
Info string `json:"account_info"`
}
// POST /delete-account
func (a *API) deleteAccount(ctx context.Context, in AccountInfo) Response {
if err := a.wallet.AccountMgr.DeleteAccount(in.Info); err != nil {
return NewErrorResponse(err)
}
return NewSuccessResponse(nil)
}
type validateAddressResp struct {
Valid bool `json:"valid"`
IsLocal bool `json:"is_local"`
}
// POST /validate-address
func (a *API) validateAddress(ctx context.Context, ins struct {
Address string `json:"address"`
}) Response {
resp := &validateAddressResp{
Valid: false,
IsLocal: false,
}
address, err := common.DecodeAddress(ins.Address, &consensus.ActiveNetParams)
if err != nil {
return NewSuccessResponse(resp)
}
redeemContract := address.ScriptAddress()
program := []byte{}
switch address.(type) {
case *common.AddressWitnessPubKeyHash:
program, err = vmutil.P2WPKHProgram(redeemContract)
case *common.AddressWitnessScriptHash:
program, err = vmutil.P2WSHProgram(redeemContract)
default:
return NewSuccessResponse(resp)
}
if err != nil {
return NewSuccessResponse(resp)
}
resp.Valid = true
resp.IsLocal = a.wallet.AccountMgr.IsLocalControlProgram(program)
return NewSuccessResponse(resp)
}
type addressResp struct {
AccountAlias string `json:"account_alias"`
AccountID string `json:"account_id"`
Address string `json:"address"`
ControlProgram string `json:"control_program"`
Change bool `json:"change"`
KeyIndex uint64 `json:"-"`
}
// SortByIndex implements sort.Interface for addressResp slices
type SortByIndex []addressResp
func (a SortByIndex) Len() int { return len(a) }
func (a SortByIndex) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a SortByIndex) Less(i, j int) bool { return a[i].KeyIndex < a[j].KeyIndex }
func (a *API) listAddresses(ctx context.Context, ins struct {
AccountID string `json:"account_id"`
AccountAlias string `json:"account_alias"`
From uint `json:"from"`
Count uint `json:"count"`
}) Response {
accountID := ins.AccountID
var target *account.Account
if ins.AccountAlias != "" {
acc, err := a.wallet.AccountMgr.FindByAlias(ins.AccountAlias)
if err != nil {
return NewErrorResponse(err)
}
target = acc
} else {
acc, err := a.wallet.AccountMgr.FindByID(accountID)
if err != nil {
return NewErrorResponse(err)
}
target = acc
}
cps, err := a.wallet.AccountMgr.ListControlProgram()
if err != nil {
return NewErrorResponse(err)
}
addresses := []addressResp{}
for _, cp := range cps {
if cp.Address == "" || cp.AccountID != target.ID {
continue
}
addresses = append(addresses, addressResp{
AccountAlias: target.Alias,
AccountID: cp.AccountID,
Address: cp.Address,
ControlProgram: hex.EncodeToString(cp.ControlProgram),
Change: cp.Change,
KeyIndex: cp.KeyIndex,
})
}
// sort AddressResp by KeyIndex
sort.Sort(SortByIndex(addresses))
start, end := getPageRange(len(addresses), ins.From, ins.Count)
return NewSuccessResponse(addresses[start:end])
}
type minigAddressResp struct {
MiningAddress string `json:"mining_address"`
}
func (a *API) getMiningAddress(ctx context.Context) Response {
miningAddress, err := a.wallet.AccountMgr.GetMiningAddress()
if err != nil {
return NewErrorResponse(err)
}
return NewSuccessResponse(minigAddressResp{
MiningAddress: miningAddress,
})
}
// POST /set-mining-address
func (a *API) setMiningAddress(ctx context.Context, in struct {
MiningAddress string `json:"mining_address"`
}) Response {
miningAddress, err := a.wallet.AccountMgr.SetMiningAddress(in.MiningAddress)
if err != nil {
return NewErrorResponse(err)
}
return NewSuccessResponse(minigAddressResp{
MiningAddress: miningAddress,
})
}