7 crypto "github.com/tendermint/go-crypto"
8 wire "github.com/tendermint/go-wire"
9 data "github.com/tendermint/go-wire/data"
12 // Storage has many implementation, based on security and sharing requirements
13 // like disk-backed, mem-backed, vault, db, etc.
14 type Storage interface {
15 Put(name string, key []byte, info Info) error
16 Get(name string) (key []byte, info Info, err error)
18 Delete(name string) error
21 // Info is the public information about a key
23 Name string `json:"name"`
24 Address data.Bytes `json:"address"`
25 PubKey crypto.PubKey `json:"pubkey"`
28 func (i *Info) Format() Info {
29 if !i.PubKey.Empty() {
30 i.Address = i.PubKey.Address()
35 // Infos is a wrapper to allows alphabetical sorting of the keys
38 func (k Infos) Len() int { return len(k) }
39 func (k Infos) Less(i, j int) bool { return k[i].Name < k[j].Name }
40 func (k Infos) Swap(i, j int) { k[i], k[j] = k[j], k[i] }
41 func (k Infos) Sort() {
47 // Signable represents any transaction we wish to send to tendermint core
48 // These methods allow us to sign arbitrary Tx with the KeyStore
49 type Signable interface {
50 // SignBytes is the immutable data, which needs to be signed
53 // Sign will add a signature and pubkey.
55 // Depending on the Signable, one may be able to call this multiple times for multisig
56 // Returns error if called with invalid data or too many times
57 Sign(pubkey crypto.PubKey, sig crypto.Signature) error
59 // Signers will return the public key(s) that signed if the signature
60 // is valid, or an error if there is any issue with the signature,
61 // including if there are no signatures
62 Signers() ([]crypto.PubKey, error)
64 // TxBytes returns the transaction data as well as all signatures
65 // It should return an error if Sign was never called
66 TxBytes() ([]byte, error)
69 // Signer allows one to use a keystore to sign transactions
70 type Signer interface {
71 Sign(name, passphrase string, tx Signable) error
74 // Manager allows simple CRUD on a keystore, as an aid to signing
75 type Manager interface {
77 // Create also returns a seed phrase for cold-storage
78 Create(name, passphrase, algo string) (Info, string, error)
79 // Recover takes a seedphrase and loads in the private key
80 Recover(name, passphrase, seedphrase string) (Info, error)
82 Get(name string) (Info, error)
83 Update(name, oldpass, newpass string) error
84 Delete(name, passphrase string) error
87 /**** MockSignable allows us to view data ***/
89 // MockSignable lets us wrap arbitrary data with a go-crypto signature
90 type MockSignable struct {
93 Signature crypto.Signature
96 var _ Signable = &MockSignable{}
98 // NewMockSignable sets the data to sign
99 func NewMockSignable(data []byte) *MockSignable {
100 return &MockSignable{Data: data}
103 // TxBytes returns the full data with signatures
104 func (s *MockSignable) TxBytes() ([]byte, error) {
105 return wire.BinaryBytes(s), nil
108 // SignBytes returns the original data passed into `NewSig`
109 func (s *MockSignable) SignBytes() []byte {
113 // Sign will add a signature and pubkey.
115 // Depending on the Signable, one may be able to call this multiple times for multisig
116 // Returns error if called with invalid data or too many times
117 func (s *MockSignable) Sign(pubkey crypto.PubKey, sig crypto.Signature) error {
123 // Signers will return the public key(s) that signed if the signature
124 // is valid, or an error if there is any issue with the signature,
125 // including if there are no signatures
126 func (s *MockSignable) Signers() ([]crypto.PubKey, error) {
127 if s.PubKey.Empty() {
128 return nil, fmt.Errorf("no signers")
130 if !s.PubKey.VerifyBytes(s.SignBytes(), s.Signature) {
131 return nil, fmt.Errorf("invalid signature")
133 return []crypto.PubKey{s.PubKey}, nil