/
sign.go
119 lines (102 loc) · 2.66 KB
/
sign.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
package api
import (
"encoding/json"
"io/ioutil"
"net/http"
"strconv"
"github.com/cosmos/cosmos-sdk/client/keys"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
)
// SignBody is the body for a sign request
type SignBody struct {
Tx json.RawMessage `json:"tx"`
Name string `json:"name"`
Passphrase string `json:"passphrase"`
ChainID string `json:"chain_id"`
AccountNumber string `json:"account_number"`
Sequence string `json:"sequence"`
}
// Marshal returns the json byte representation of the sign body
func (sb SignBody) Marshal() []byte {
out, err := json.Marshal(sb)
if err != nil {
panic(err)
}
return out
}
// StdSignMsg returns a StdSignMsg from a SignBody request
func (sb SignBody) StdSignMsg() (stdSign auth.StdSignMsg, stdTx auth.StdTx, err error) {
err = cdc.UnmarshalJSON(sb.Tx, &stdTx)
if err != nil {
return
}
acc, err := strconv.ParseInt(sb.AccountNumber, 10, 64)
if err != nil {
return
}
seq, err := strconv.ParseInt(sb.Sequence, 10, 64)
if err != nil {
return
}
stdSign = auth.StdSignMsg{
Memo: stdTx.Memo,
Msgs: stdTx.Msgs,
ChainID: sb.ChainID,
AccountNumber: uint64(acc),
Sequence: uint64(seq),
Fee: auth.StdFee{
Amount: stdTx.Fee.Amount,
Gas: uint64(stdTx.Fee.Gas),
},
}
return
}
// Sign handles the /tx/sign route
func (s *Server) Sign(w http.ResponseWriter, r *http.Request) {
var m SignBody
kb, err := keys.NewKeyBaseFromDir(s.KeyDir)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write(newError(err).marshal())
return
}
body, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write(newError(err).marshal())
return
}
err = cdc.UnmarshalJSON(body, &m)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write(newError(err).marshal())
return
}
stdSign, stdTx, err := m.StdSignMsg()
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write(newError(err).marshal())
return
}
sigBytes, pubkey, err := kb.Sign(m.Name, m.Passphrase, sdk.MustSortJSON(cdc.MustMarshalJSON(stdSign)))
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write(newError(err).marshal())
return
}
sigs := append(stdTx.GetSignatures(), auth.StdSignature{
PubKey: pubkey,
Signature: sigBytes,
})
signedStdTx := auth.NewStdTx(stdTx.GetMsgs(), stdTx.Fee, sigs, stdTx.GetMemo())
out, err := cdc.MarshalJSON(signedStdTx)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write(newError(err).marshal())
return
}
w.WriteHeader(http.StatusOK)
w.Write(out)
return
}