Skip to content

Commit

Permalink
feat: add base64 Pubkeys from cli (backport #17639) (#18434)
Browse files Browse the repository at this point in the history
Co-authored-by: Julián Toledano <[email protected]>
Co-authored-by: Julien Robert <[email protected]>
  • Loading branch information
3 people authored Nov 10, 2023
1 parent 2b42efc commit 8f25a61
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Features

* (client/keys) [#17639](https://github.com/cosmos/cosmos-sdk/pull/17639) Allows using and saving public keys encoded as base64.
* (server) [#17094](https://github.com/cosmos/cosmos-sdk/pull/17094) Add a `shutdown-grace` flag for waiting a given time before exit.

### Improvements
Expand Down
58 changes: 49 additions & 9 deletions client/keys/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package keys
import (
"bufio"
"bytes"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
Expand All @@ -15,6 +16,7 @@ import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/input"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/crypto/keys/multisig"
Expand All @@ -23,15 +25,16 @@ import (
)

const (
flagInteractive = "interactive"
flagRecover = "recover"
flagNoBackup = "no-backup"
flagCoinType = "coin-type"
flagAccount = "account"
flagIndex = "index"
flagMultisig = "multisig"
flagNoSort = "nosort"
flagHDPath = "hd-path"
flagInteractive = "interactive"
flagRecover = "recover"
flagNoBackup = "no-backup"
flagCoinType = "coin-type"
flagAccount = "account"
flagIndex = "index"
flagMultisig = "multisig"
flagNoSort = "nosort"
flagHDPath = "hd-path"
flagPubKeyBase64 = "pubkey-base64"

// DefaultKeyPass contains the default key password for genesis transactions
DefaultKeyPass = "12345678"
Expand Down Expand Up @@ -69,6 +72,7 @@ Example:
f.Int(flagMultiSigThreshold, 1, "K out of N required signatures. For use in conjunction with --multisig")
f.Bool(flagNoSort, false, "Keys passed to --multisig are taken in the order they're supplied")
f.String(FlagPublicKey, "", "Parse a public key in JSON format and saves key info to <name> file.")
f.String(flagPubKeyBase64, "", "Parse a public key in base64 format and saves key info.")
f.BoolP(flagInteractive, "i", false, "Interactively prompt user for BIP39 passphrase and mnemonic")
f.Bool(flags.FlagUseLedger, false, "Store a local reference to a private key on a Ledger device")
f.Bool(flagRecover, false, "Provide seed phrase to recover existing key instead of creating")
Expand Down Expand Up @@ -189,6 +193,10 @@ func runAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
}

pubKey, _ := cmd.Flags().GetString(FlagPublicKey)
pubKeyBase64, _ := cmd.Flags().GetString(flagPubKeyBase64)
if pubKey != "" && pubKeyBase64 != "" {
return fmt.Errorf(`flags %s and %s cannot be used simultaneously`, FlagPublicKey, flagPubKeyBase64)
}
if pubKey != "" {
var pk cryptotypes.PubKey
if err = ctx.Codec.UnmarshalInterfaceJSON([]byte(pubKey), &pk); err != nil {
Expand All @@ -202,6 +210,38 @@ func runAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf

return printCreate(cmd, k, false, "", outputFormat)
}
if pubKeyBase64 != "" {
b64, err := base64.StdEncoding.DecodeString(pubKeyBase64)
if err != nil {
return err
}

var pk cryptotypes.PubKey
// create an empty pubkey in order to get the algo TypeUrl.
tempAny, err := codectypes.NewAnyWithValue(algo.Generate()([]byte{}).PubKey())
if err != nil {
return err
}

jsonPub, err := json.Marshal(struct {
Type string `json:"@type,omitempty"`
Key string `json:"key,omitempty"`
}{tempAny.TypeUrl, string(b64)})
if err != nil {
return fmt.Errorf("failed to JSON marshal typeURL and base64 key: %w", err)
}

if err = ctx.Codec.UnmarshalInterfaceJSON(jsonPub, &pk); err != nil {
return err
}

k, err := kb.SaveOfflineKey(name, pk)
if err != nil {
return fmt.Errorf("failed to save offline key: %w", err)
}

return printCreate(cmd, k, false, "", outputFormat)
}

coinType, _ := cmd.Flags().GetUint32(flagCoinType)
account, _ := cmd.Flags().GetUint32(flagAccount)
Expand Down
19 changes: 19 additions & 0 deletions client/keys/add_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ func Test_runAddCmdBasic(t *testing.T) {
func Test_runAddCmdDryRun(t *testing.T) {
pubkey1 := `{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AtObiFVE4s+9+RX5SP8TN9r2mxpoaT4eGj9CJfK7VRzN"}`
pubkey2 := `{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A/se1vkqgdQ7VJQCM4mxN+L+ciGhnnJ4XYsQCRBMrdRi"}`
b64Pubkey := "QWhnOHhpdXBJcGZ2UlR2ak5la1ExclROUThTOW96YjdHK2RYQmFLVjl4aUo="
cdc := moduletestutil.MakeTestEncodingConfig().Codec

testData := []struct {
Expand Down Expand Up @@ -181,6 +182,24 @@ func Test_runAddCmdDryRun(t *testing.T) {
},
added: false,
},
{
name: "base64 pubkey account is added",
args: []string{
"testkey",
fmt.Sprintf("--%s=%s", flags.FlagDryRun, "false"),
fmt.Sprintf("--%s=%s", flagPubKeyBase64, b64Pubkey),
},
added: true,
},
{
name: "base64 pubkey account is not added with dry run",
args: []string{
"testkey",
fmt.Sprintf("--%s=%s", flags.FlagDryRun, "true"),
fmt.Sprintf("--%s=%s", flagPubKeyBase64, b64Pubkey),
},
added: false,
},
}
for _, tt := range testData {
tt := tt
Expand Down

0 comments on commit 8f25a61

Please sign in to comment.