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.AccountMgr.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, in AccountInfo) Response {
62 if err := a.wallet.AccountMgr.DeleteAccount(in.Info); err != nil {
63 return NewErrorResponse(err)
65 return NewSuccessResponse(nil)
68 type validateAddressResp struct {
69 Valid bool `json:"valid"`
70 IsLocal bool `json:"is_local"`
73 // POST /validate-address
74 func (a *API) validateAddress(ctx context.Context, ins struct {
75 Address string `json:"address"`
77 resp := &validateAddressResp{
81 address, err := common.DecodeAddress(ins.Address, &consensus.ActiveNetParams)
83 return NewSuccessResponse(resp)
86 redeemContract := address.ScriptAddress()
88 switch address.(type) {
89 case *common.AddressWitnessPubKeyHash:
90 program, err = vmutil.P2WPKHProgram(redeemContract)
91 case *common.AddressWitnessScriptHash:
92 program, err = vmutil.P2WSHProgram(redeemContract)
94 return NewSuccessResponse(resp)
97 return NewSuccessResponse(resp)
101 resp.IsLocal = a.wallet.AccountMgr.IsLocalControlProgram(program)
102 return NewSuccessResponse(resp)
105 type addressResp struct {
106 AccountAlias string `json:"account_alias"`
107 AccountID string `json:"account_id"`
108 Address string `json:"address"`
109 ControlProgram string `json:"control_program"`
110 Change bool `json:"change"`
111 KeyIndex uint64 `json:"key_index"`
114 // SortByIndex implements sort.Interface for addressResp slices
115 type SortByIndex []addressResp
117 func (a SortByIndex) Len() int { return len(a) }
118 func (a SortByIndex) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
119 func (a SortByIndex) Less(i, j int) bool { return a[i].KeyIndex < a[j].KeyIndex }
121 func (a *API) listAddresses(ctx context.Context, ins struct {
122 AccountID string `json:"account_id"`
123 AccountAlias string `json:"account_alias"`
124 From uint `json:"from"`
125 Count uint `json:"count"`
127 accountID := ins.AccountID
128 var target *account.Account
129 if ins.AccountAlias != "" {
130 acc, err := a.wallet.AccountMgr.FindByAlias(ins.AccountAlias)
132 return NewErrorResponse(err)
136 acc, err := a.wallet.AccountMgr.FindByID(accountID)
138 return NewErrorResponse(err)
143 cps, err := a.wallet.AccountMgr.ListControlProgram()
145 return NewErrorResponse(err)
148 addresses := []addressResp{}
149 for _, cp := range cps {
150 if cp.Address == "" || cp.AccountID != target.ID {
153 addresses = append(addresses, addressResp{
154 AccountAlias: target.Alias,
155 AccountID: cp.AccountID,
157 ControlProgram: hex.EncodeToString(cp.ControlProgram),
159 KeyIndex: cp.KeyIndex,
163 // sort AddressResp by KeyIndex
164 sort.Sort(SortByIndex(addresses))
165 start, end := getPageRange(len(addresses), ins.From, ins.Count)
166 return NewSuccessResponse(addresses[start:end])
169 type minigAddressResp struct {
170 MiningAddress string `json:"mining_address"`
173 func (a *API) getMiningAddress(ctx context.Context) Response {
174 miningAddress, err := a.wallet.AccountMgr.GetMiningAddress()
176 return NewErrorResponse(err)
178 return NewSuccessResponse(minigAddressResp{
179 MiningAddress: miningAddress,
183 // POST /set-mining-address
184 func (a *API) setMiningAddress(ctx context.Context, in struct {
185 MiningAddress string `json:"mining_address"`
187 miningAddress, err := a.wallet.AccountMgr.SetMiningAddress(in.MiningAddress)
189 return NewErrorResponse(err)
191 return NewSuccessResponse(minigAddressResp{
192 MiningAddress: miningAddress,