OSDN Git Service

add dpos consensus
[bytom/vapor.git] / api / hsm.go
1 package api
2
3 import (
4         "context"
5
6         log "github.com/sirupsen/logrus"
7
8         "github.com/vapor/blockchain/txbuilder"
9         "github.com/vapor/common"
10         "github.com/vapor/consensus"
11         "github.com/vapor/crypto"
12         "github.com/vapor/crypto/ed25519/chainkd"
13 )
14
15 type createKeyResp struct {
16         Alias    string       `json:"alias"`
17         XPub     chainkd.XPub `json:"xpub"`
18         File     string       `json:"file"`
19         Mnemonic string       `json:"mnemonic,omitempty"`
20 }
21
22 func (a *API) pseudohsmCreateKey(ctx context.Context, in struct {
23         Alias    string `json:"alias"`
24         Password string `json:"password"`
25         Mnemonic string `json:"mnemonic"`
26         Language string `json:"language"`
27 }) Response {
28         if in.Language == "" {
29                 in.Language = "en"
30         }
31         if len(in.Mnemonic) > 0 {
32                 xpub, err := a.wallet.Hsm.ImportKeyFromMnemonic(in.Alias, in.Password, in.Mnemonic, in.Language)
33                 if err != nil {
34                         return NewErrorResponse(err)
35                 }
36                 return NewSuccessResponse(&createKeyResp{Alias: xpub.Alias, XPub: xpub.XPub, File: xpub.File})
37         }
38         xpub, mnemonic, err := a.wallet.Hsm.XCreate(in.Alias, in.Password, in.Language)
39         if err != nil {
40                 return NewErrorResponse(err)
41         }
42         return NewSuccessResponse(&createKeyResp{Alias: xpub.Alias, XPub: xpub.XPub, File: xpub.File, Mnemonic: *mnemonic})
43 }
44
45 func (a *API) pseudohsmUpdateKeyAlias(ctx context.Context, in struct {
46         XPub     chainkd.XPub `json:"xpub"`
47         NewAlias string       `json:"new_alias"`
48 }) Response {
49         if err := a.wallet.Hsm.UpdateKeyAlias(in.XPub, in.NewAlias); err != nil {
50                 return NewErrorResponse(err)
51         }
52         return NewSuccessResponse(nil)
53 }
54
55 func (a *API) pseudohsmListKeys(ctx context.Context) Response {
56         return NewSuccessResponse(a.wallet.Hsm.ListKeys())
57 }
58
59 func (a *API) pseudohsmDeleteKey(ctx context.Context, x struct {
60         Password string       `json:"password"`
61         XPub     chainkd.XPub `json:"xpub"`
62 }) Response {
63         if err := a.wallet.Hsm.XDelete(x.XPub, x.Password); err != nil {
64                 return NewErrorResponse(err)
65         }
66         return NewSuccessResponse(nil)
67 }
68
69 type signTemplateResp struct {
70         Tx           *txbuilder.Template `json:"transaction"`
71         SignComplete bool                `json:"sign_complete"`
72 }
73
74 func (a *API) signTemplate(ctx context.Context, x struct {
75         Password string             `json:"password"`
76         Txs      txbuilder.Template `json:"transaction"`
77 }) Response {
78         if err := txbuilder.Sign(ctx, &x.Txs, x.Password, a.PseudohsmSignTemplate); err != nil {
79                 log.WithField("build err", err).Error("fail on sign transaction.")
80                 return NewErrorResponse(err)
81         }
82         log.Info("Sign Transaction complete.")
83         return NewSuccessResponse(&signTemplateResp{Tx: &x.Txs, SignComplete: txbuilder.SignProgress(&x.Txs)})
84 }
85
86 type signTemplatesResp struct {
87         Tx           []*txbuilder.Template `json:"transaction"`
88         SignComplete bool                  `json:"sign_complete"`
89 }
90
91 func (a *API) signTemplates(ctx context.Context, x struct {
92         Password string                `json:"password"`
93         Txs      []*txbuilder.Template `json:"transactions"`
94 }) Response {
95         signComplete := true
96         for _, tx := range x.Txs {
97                 if err := txbuilder.Sign(ctx, tx, x.Password, a.PseudohsmSignTemplate); err != nil {
98                         log.WithField("build err", err).Error("fail on sign transaction.")
99                         return NewErrorResponse(err)
100                 }
101                 signComplete = signComplete && txbuilder.SignProgress(tx)
102         }
103
104         log.Info("Sign Chain Tx complete.")
105         return NewSuccessResponse(&signTemplatesResp{Tx: x.Txs, SignComplete: signComplete})
106 }
107
108 func (a *API) PseudohsmSignTemplate(ctx context.Context, xpub chainkd.XPub, path [][]byte, data [32]byte, password string) ([]byte, error) {
109         return a.wallet.Hsm.XSign(xpub, path, data[:], password)
110 }
111
112 // ResetPasswordResp is response for reset key password
113 type ResetPasswordResp struct {
114         Changed bool `json:"changed"`
115 }
116
117 func (a *API) pseudohsmResetPassword(ctx context.Context, ins struct {
118         XPub        chainkd.XPub `json:"xpub"`
119         OldPassword string       `json:"old_password"`
120         NewPassword string       `json:"new_password"`
121 }) Response {
122         resp := &ResetPasswordResp{Changed: false}
123         if err := a.wallet.Hsm.ResetPassword(ins.XPub, ins.OldPassword, ins.NewPassword); err != nil {
124                 return NewSuccessResponse(resp)
125         }
126         resp.Changed = true
127         return NewSuccessResponse(resp)
128 }
129
130 // CheckPasswordResp is response for check key password
131 type CheckPasswordResp struct {
132         CheckResult bool `json:"check_result"`
133 }
134
135 func (a *API) pseudohsmCheckPassword(ctx context.Context, ins struct {
136         XPub     chainkd.XPub `json:"xpub"`
137         Password string       `json:"password"`
138 }) Response {
139         resp := &CheckPasswordResp{CheckResult: false}
140         if _, err := a.wallet.Hsm.LoadChainKDKey(ins.XPub, ins.Password); err != nil {
141                 return NewSuccessResponse(resp)
142         }
143         resp.CheckResult = true
144         return NewSuccessResponse(resp)
145 }
146
147 type keyPair struct {
148         Xpub    chainkd.XPub `json:"xpub"`
149         Xprv    chainkd.XPrv `json:"xprv"`
150         Address string       `json:"address,omitempty"`
151 }
152
153 func (a *API) createXKeys(ctx context.Context) Response {
154         xprv, xpub, err := chainkd.NewXKeys(nil)
155         if err != nil {
156                 return NewErrorResponse(err)
157         }
158
159         pubHash := crypto.Ripemd160(xpub.PublicKey())
160
161         address, err := common.NewAddressWitnessPubKeyHash(pubHash, &consensus.ActiveNetParams)
162         if err != nil {
163                 return NewErrorResponse(err)
164         }
165
166         return NewSuccessResponse(&keyPair{Xprv: xprv, Xpub: xpub, Address: address.EncodeAddress()})
167 }