github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/crypto/keys/client/add_bech32.go (about)

     1  package client
     2  
     3  import (
     4  	"context"
     5  	"flag"
     6  	"fmt"
     7  
     8  	"github.com/gnolang/gno/tm2/pkg/commands"
     9  	"github.com/gnolang/gno/tm2/pkg/crypto"
    10  	"github.com/gnolang/gno/tm2/pkg/crypto/keys"
    11  )
    12  
    13  type AddBech32Cfg struct {
    14  	RootCfg *AddCfg
    15  
    16  	PublicKey string
    17  }
    18  
    19  // NewAddBech32Cmd creates a gnokey add bech32 command
    20  func NewAddBech32Cmd(rootCfg *AddCfg, io commands.IO) *commands.Command {
    21  	cfg := &AddBech32Cfg{
    22  		RootCfg: rootCfg,
    23  	}
    24  
    25  	return commands.NewCommand(
    26  		commands.Metadata{
    27  			Name:       "bech32",
    28  			ShortUsage: "add bech32 [flags] <key-name>",
    29  			ShortHelp:  "adds a public key to the keybase, using the bech32 representation",
    30  		},
    31  		cfg,
    32  		func(_ context.Context, args []string) error {
    33  			return execAddBech32(cfg, args, io)
    34  		},
    35  	)
    36  }
    37  
    38  func (c *AddBech32Cfg) RegisterFlags(fs *flag.FlagSet) {
    39  	fs.StringVar(
    40  		&c.PublicKey,
    41  		"pubkey",
    42  		"",
    43  		"parse a public key in bech32 format and save it to disk",
    44  	)
    45  }
    46  
    47  func execAddBech32(cfg *AddBech32Cfg, args []string, io commands.IO) error {
    48  	// Validate a key name was provided
    49  	if len(args) != 1 {
    50  		return flag.ErrHelp
    51  	}
    52  
    53  	name := args[0]
    54  
    55  	// Read the keybase from the home directory
    56  	kb, err := keys.NewKeyBaseFromDir(cfg.RootCfg.RootCfg.Home)
    57  	if err != nil {
    58  		return fmt.Errorf("unable to read keybase, %w", err)
    59  	}
    60  
    61  	// Check if the key exists
    62  	exists, err := kb.HasByName(name)
    63  	if err != nil {
    64  		return fmt.Errorf("unable to fetch key, %w", err)
    65  	}
    66  
    67  	// Get overwrite confirmation, if any
    68  	if exists {
    69  		overwrite, err := io.GetConfirmation(fmt.Sprintf("Override the existing name %s", name))
    70  		if err != nil {
    71  			return fmt.Errorf("unable to get confirmation, %w", err)
    72  		}
    73  
    74  		if !overwrite {
    75  			return errOverwriteAborted
    76  		}
    77  	}
    78  
    79  	// Parse the public key
    80  	publicKey, err := crypto.PubKeyFromBech32(cfg.PublicKey)
    81  	if err != nil {
    82  		return fmt.Errorf("unable to parse public key from bech32, %w", err)
    83  	}
    84  
    85  	// Save it offline in the keybase
    86  	_, err = kb.CreateOffline(name, publicKey)
    87  	if err != nil {
    88  		return fmt.Errorf("unable to save public key, %w", err)
    89  	}
    90  
    91  	io.Printfln("Key %q saved to disk.\n", name)
    92  
    93  	return nil
    94  }