8 log "github.com/sirupsen/logrus"
10 "github.com/bytom/account"
11 "github.com/bytom/blockchain/signers"
12 "github.com/bytom/common"
13 "github.com/bytom/consensus"
14 "github.com/bytom/crypto/ed25519/chainkd"
15 "github.com/bytom/protocol/vm/vmutil"
18 // POST /create-account
19 func (a *API) createAccount(ctx context.Context, ins struct {
20 RootXPubs []chainkd.XPub `json:"root_xpubs"`
21 Quorum int `json:"quorum"`
22 Alias string `json:"alias"`
24 acc, err := a.wallet.AccountMgr.Create(ins.RootXPubs, ins.Quorum, ins.Alias, signers.BIP0044)
26 return NewErrorResponse(err)
29 annotatedAccount := account.Annotated(acc)
30 log.WithField("account ID", annotatedAccount.ID).Info("Created account")
32 return NewSuccessResponse(annotatedAccount)
35 // POST update-account-alias
36 func (a *API) updateAccountAlias(ctx context.Context, ins struct {
37 AccountID string `json:"account_id"`
38 AccountAlias string `json:"account_alias"`
39 NewAlias string `json:"new_alias"`
41 accountID := ins.AccountID
42 if ins.AccountAlias != "" {
43 foundAccount, err := a.wallet.AccountMgr.FindByAlias(ins.AccountAlias)
45 return NewErrorResponse(err)
47 accountID = foundAccount.ID
49 if err := a.wallet.UpdateAccountAlias(accountID, ins.NewAlias); err != nil {
50 return NewErrorResponse(err)
52 return NewSuccessResponse(nil)
55 // AccountInfo is request struct for deleteAccount
56 type AccountInfo struct {
57 Info string `json:"account_info"`
60 // POST /delete-account
61 func (a *API) deleteAccount(ctx context.Context, filter struct {
62 AccountID string `json:"account_id"`
63 AccountAlias string `json:"account_alias"`
65 accountID := filter.AccountID
66 if filter.AccountAlias != "" {
67 acc, err := a.wallet.AccountMgr.FindByAlias(filter.AccountAlias)
69 return NewErrorResponse(err)
73 if err := a.wallet.DeleteAccount(accountID); err != nil {
74 return NewErrorResponse(err)
77 return NewSuccessResponse(nil)
80 type validateAddressResp struct {
81 Valid bool `json:"valid"`
82 IsLocal bool `json:"is_local"`
85 // POST /validate-address
86 func (a *API) validateAddress(ctx context.Context, ins struct {
87 Address string `json:"address"`
89 resp := &validateAddressResp{
93 address, err := common.DecodeAddress(ins.Address, &consensus.ActiveNetParams)
95 return NewSuccessResponse(resp)
98 redeemContract := address.ScriptAddress()
100 switch address.(type) {
101 case *common.AddressWitnessPubKeyHash:
102 program, err = vmutil.P2WPKHProgram(redeemContract)
103 case *common.AddressWitnessScriptHash:
104 program, err = vmutil.P2WSHProgram(redeemContract)
106 return NewSuccessResponse(resp)
109 return NewSuccessResponse(resp)
113 resp.IsLocal = a.wallet.AccountMgr.IsLocalControlProgram(program)
114 return NewSuccessResponse(resp)
117 type addressResp struct {
118 AccountAlias string `json:"account_alias"`
119 AccountID string `json:"account_id"`
120 Address string `json:"address"`
121 ControlProgram string `json:"control_program"`
122 Change bool `json:"change"`
123 KeyIndex uint64 `json:"key_index"`
126 // SortByIndex implements sort.Interface for addressResp slices
127 type SortByIndex []addressResp
129 func (a SortByIndex) Len() int { return len(a) }
130 func (a SortByIndex) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
131 func (a SortByIndex) Less(i, j int) bool { return a[i].KeyIndex < a[j].KeyIndex }
133 func (a *API) listAddresses(ctx context.Context, ins struct {
134 AccountID string `json:"account_id"`
135 AccountAlias string `json:"account_alias"`
136 From uint `json:"from"`
137 Count uint `json:"count"`
139 accountID := ins.AccountID
140 var target *account.Account
141 if ins.AccountAlias != "" {
142 acc, err := a.wallet.AccountMgr.FindByAlias(ins.AccountAlias)
144 return NewErrorResponse(err)
148 acc, err := a.wallet.AccountMgr.FindByID(accountID)
150 return NewErrorResponse(err)
155 cps, err := a.wallet.AccountMgr.ListControlProgram()
157 return NewErrorResponse(err)
160 addresses := []addressResp{}
161 for _, cp := range cps {
162 if cp.Address == "" || cp.AccountID != target.ID {
165 addresses = append(addresses, addressResp{
166 AccountAlias: target.Alias,
167 AccountID: cp.AccountID,
169 ControlProgram: hex.EncodeToString(cp.ControlProgram),
171 KeyIndex: cp.KeyIndex,
175 // sort AddressResp by KeyIndex
176 sort.Sort(SortByIndex(addresses))
177 start, end := getPageRange(len(addresses), ins.From, ins.Count)
178 return NewSuccessResponse(addresses[start:end])
181 type minigAddressResp struct {
182 MiningAddress string `json:"mining_address"`
185 func (a *API) getMiningAddress(ctx context.Context) Response {
186 miningAddress, err := a.wallet.AccountMgr.GetMiningAddress()
188 return NewErrorResponse(err)
190 return NewSuccessResponse(minigAddressResp{
191 MiningAddress: miningAddress,
195 // POST /set-mining-address
196 func (a *API) setMiningAddress(ctx context.Context, in struct {
197 MiningAddress string `json:"mining_address"`
199 miningAddress, err := a.wallet.AccountMgr.SetMiningAddress(in.MiningAddress)
201 return NewErrorResponse(err)
203 return NewSuccessResponse(minigAddressResp{
204 MiningAddress: miningAddress,