github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/crypto/keys/client/export.go (about) 1 package client 2 3 import ( 4 "context" 5 "errors" 6 "flag" 7 "fmt" 8 "os" 9 10 "github.com/gnolang/gno/tm2/pkg/commands" 11 "github.com/gnolang/gno/tm2/pkg/crypto/keys" 12 ) 13 14 type ExportCfg struct { 15 RootCfg *BaseCfg 16 17 NameOrBech32 string 18 OutputPath string 19 Unsafe bool 20 } 21 22 func NewExportCmd(rootCfg *BaseCfg, io commands.IO) *commands.Command { 23 cfg := &ExportCfg{ 24 RootCfg: rootCfg, 25 } 26 27 return commands.NewCommand( 28 commands.Metadata{ 29 Name: "export", 30 ShortUsage: "export [flags]", 31 ShortHelp: "exports private key armor", 32 }, 33 cfg, 34 func(_ context.Context, args []string) error { 35 return execExport(cfg, io) 36 }, 37 ) 38 } 39 40 func (c *ExportCfg) RegisterFlags(fs *flag.FlagSet) { 41 fs.StringVar( 42 &c.NameOrBech32, 43 "key", 44 "", 45 "name or bech32 address of the private key", 46 ) 47 48 fs.StringVar( 49 &c.OutputPath, 50 "output-path", 51 "", 52 "the desired output path for the armor file", 53 ) 54 55 fs.BoolVar( 56 &c.Unsafe, 57 "unsafe", 58 false, 59 "export the private key armor as unencrypted", 60 ) 61 } 62 63 func execExport(cfg *ExportCfg, io commands.IO) error { 64 // check keyname 65 if cfg.NameOrBech32 == "" { 66 return errors.New("key to be exported shouldn't be empty") 67 } 68 69 // Create a new instance of the key-base 70 kb, err := keys.NewKeyBaseFromDir(cfg.RootCfg.Home) 71 if err != nil { 72 return fmt.Errorf( 73 "unable to create a key base from directory %s, %w", 74 cfg.RootCfg.Home, 75 err, 76 ) 77 } 78 79 // Get the key-base decrypt password 80 decryptPassword, err := io.GetPassword( 81 "Enter a passphrase to decrypt your private key from disk:", 82 cfg.RootCfg.InsecurePasswordStdin, 83 ) 84 if err != nil { 85 return fmt.Errorf( 86 "unable to retrieve decrypt password from user, %w", 87 err, 88 ) 89 } 90 91 var ( 92 armor string 93 exportErr error 94 ) 95 96 if cfg.Unsafe { 97 // Generate the unencrypted armor 98 armor, exportErr = kb.ExportPrivKeyUnsafe( 99 cfg.NameOrBech32, 100 decryptPassword, 101 ) 102 103 privk, err := kb.ExportPrivateKeyObject(cfg.NameOrBech32, decryptPassword) 104 if err != nil { 105 panic(err) 106 } 107 108 fmt.Printf("privk:\n%x\n", privk.Bytes()) 109 } else { 110 // Get the armor encrypt password 111 encryptPassword, err := io.GetCheckPassword( 112 [2]string{ 113 "Enter a passphrase to encrypt your private key armor:", 114 "Repeat the passphrase:", 115 }, 116 cfg.RootCfg.InsecurePasswordStdin, 117 ) 118 if err != nil { 119 return fmt.Errorf( 120 "unable to retrieve armor encrypt password from user, %w", 121 err, 122 ) 123 } 124 125 // Generate the encrypted armor 126 armor, exportErr = kb.ExportPrivKey( 127 cfg.NameOrBech32, 128 decryptPassword, 129 encryptPassword, 130 ) 131 } 132 133 if exportErr != nil { 134 return fmt.Errorf( 135 "unable to export the private key, %w", 136 exportErr, 137 ) 138 } 139 140 // Write the armor to disk 141 if err := os.WriteFile( 142 cfg.OutputPath, 143 []byte(armor), 144 0o644, 145 ); err != nil { 146 return fmt.Errorf( 147 "unable to write encrypted armor to file, %w", 148 err, 149 ) 150 } 151 152 io.Printfln("Private key armor successfully outputted to %s", cfg.OutputPath) 153 154 return nil 155 }