Skip to content

Commit

Permalink
Added capabilities to read private key generated by `solana-keygen ne…
Browse files Browse the repository at this point in the history
…w` command line
  • Loading branch information
Matthieu Vachon committed Dec 11, 2020
1 parent 4e3f16d commit 98efad3
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 20 deletions.
4 changes: 2 additions & 2 deletions cmd/slnc/cmd/token_list_mints.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
var tokenListMintsCmd = &cobra.Command{
Use: "mints",
Short: "Lists mints",
RunE: func(cmd *cobra.Command, args []string) error {
RunE: func(cmd *cobra.Command, _ []string) error {
rpcCli := getClient()

mints, err := token.FetchMints(cmd.Context(), rpcCli)
Expand All @@ -36,7 +36,7 @@ var tokenListMintsCmd = &cobra.Command{
out := []string{"Mint | Decimals | Supply | Token Authority | Freeze Authority"}
for _, m := range mints {
line := []string{
fmt.Sprintf("%d", m),
fmt.Sprintf("%d", m.MintAuthorityOption),
fmt.Sprintf("%d", m.Supply),
fmt.Sprintf("%d", m.Decimals),
}
Expand Down
49 changes: 31 additions & 18 deletions keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,22 @@ import (
"crypto/ed25519"
crypto_rand "crypto/rand"
"encoding/json"
"errors"
"fmt"
"io/ioutil"

"github.com/mr-tron/base58"
)

type PrivateKey []byte

func MustPrivateKeyFromBase58(in string) PrivateKey {
out, err := PrivateKeyFromBase58(in)
if err != nil {
panic(err)
}
return out
}

func PrivateKeyFromBase58(privkey string) (PrivateKey, error) {
res, err := base58.Decode(privkey)
if err != nil {
Expand All @@ -21,6 +29,21 @@ func PrivateKeyFromBase58(privkey string) (PrivateKey, error) {
return res, nil
}

func PrivateKeyFromSolanaKeygenFile(file string) (PrivateKey, error) {
content, err := ioutil.ReadFile(file)
if err != nil {
return nil, fmt.Errorf("read keygen file: %w", err)
}

var values []uint8
err = json.Unmarshal(content, &values)
if err != nil {
return nil, fmt.Errorf("decode keygen file: %w", err)
}

return PrivateKey([]byte(values)), nil
}

func (k PrivateKey) String() string {
return base58.Encode(k)
}
Expand Down Expand Up @@ -58,7 +81,6 @@ func (k PrivateKey) PublicKey() PublicKey {
return publicKey
}

///
type PublicKey [32]byte

func (p PublicKey) Equals(pb PublicKey) bool {
Expand All @@ -76,13 +98,13 @@ func MustPublicKeyFromBase58(in string) PublicKey {
func PublicKeyFromBase58(in string) (out PublicKey, err error) {
val, err := base58.Decode(in)
if err != nil {
return
return out, fmt.Errorf("decode: %w", err)
}

if len(val) != 32 {
err = fmt.Errorf("invalid length, expected 32, got %d", len(val))
return
return out, fmt.Errorf("invalid length, expected 32, got %d", len(val))
}

copy(out[:], val)
return
}
Expand All @@ -93,23 +115,14 @@ func (p PublicKey) MarshalJSON() ([]byte, error) {

func (p *PublicKey) UnmarshalJSON(data []byte) (err error) {
var s string
err = json.Unmarshal(data, &s)
if err != nil {
return
}

dat, err := base58.Decode(s)
if err != nil {
if err := json.Unmarshal(data, &s); err != nil {
return err
}

if len(dat) != 32 {
return errors.New("invalid data length for public key")
*p, err = PublicKeyFromBase58(s)
if err != nil {
return fmt.Errorf("invalid public key %q: %w", s, err)
}

target := PublicKey{}
copy(target[:], dat)
*p = target
return
}

Expand Down
38 changes: 38 additions & 0 deletions keys_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package solana

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestPrivateKeyFromSolanaKeygenFile(t *testing.T) {
tests := []struct {
inFile string
expected PrivateKey
expectedPub PublicKey
expectedErr error
}{
{
"testdata/standard.solana-keygen.json",
MustPrivateKeyFromBase58("66cDvko73yAf8LYvFMM3r8vF5vJtkk7JKMgEKwkmBC86oHdq41C7i1a2vS3zE1yCcdLLk6VUatUb32ZzVjSBXtRs"),
MustPublicKeyFromBase58("F8UvVsKnzWyp2nF8aDcqvQ2GVcRpqT91WDsAtvBKCMt9"),
nil,
},
}

for _, test := range tests {
t.Run(test.inFile, func(t *testing.T) {
actual, err := PrivateKeyFromSolanaKeygenFile(test.inFile)
if test.expectedErr == nil {
require.NoError(t, err)
assert.Equal(t, test.expected, actual)
assert.Equal(t, test.expectedPub, actual.PublicKey(), "%s != %s", test.expectedPub, actual.PublicKey())

} else {
assert.Equal(t, test.expectedErr, err)
}
})
}
}
1 change: 1 addition & 0 deletions testdata/standard.solana-keygen.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[254,235,166,85,112,29,132,16,126,87,234,58,144,120,98,141,75,133,85,10,31,71,74,147,81,189,128,180,112,21,110,62,209,238,65,42,248,12,152,28,130,46,170,32,19,8,11,29,255,208,207,18,123,131,230,60,249,157,68,133,246,187,45,62]

0 comments on commit 98efad3

Please sign in to comment.