github.com/cosmos/cosmos-sdk@v0.50.10/client/keys/add_test.go (about) 1 package keys 2 3 import ( 4 "bytes" 5 "context" 6 "fmt" 7 "io" 8 "testing" 9 10 "github.com/cosmos/go-bip39" 11 "github.com/stretchr/testify/require" 12 13 "github.com/cosmos/cosmos-sdk/client" 14 "github.com/cosmos/cosmos-sdk/client/flags" 15 "github.com/cosmos/cosmos-sdk/crypto/hd" 16 "github.com/cosmos/cosmos-sdk/crypto/keyring" 17 "github.com/cosmos/cosmos-sdk/testutil" 18 "github.com/cosmos/cosmos-sdk/testutil/testdata" 19 sdk "github.com/cosmos/cosmos-sdk/types" 20 moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" 21 ) 22 23 func Test_runAddCmdBasic(t *testing.T) { 24 cmd := AddKeyCommand() 25 cmd.Flags().AddFlagSet(Commands().PersistentFlags()) 26 27 mockIn := testutil.ApplyMockIODiscardOutErr(cmd) 28 kbHome := t.TempDir() 29 30 cdc := moduletestutil.MakeTestEncodingConfig().Codec 31 kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome, mockIn, cdc) 32 require.NoError(t, err) 33 34 clientCtx := client.Context{}.WithKeyringDir(kbHome).WithInput(mockIn).WithCodec(cdc) 35 ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx) 36 37 t.Cleanup(func() { 38 _ = kb.Delete("keyname1") 39 _ = kb.Delete("keyname2") 40 }) 41 42 cmd.SetArgs([]string{ 43 "keyname1", 44 fmt.Sprintf("--%s=%s", flags.FlagKeyringDir, kbHome), 45 fmt.Sprintf("--%s=%s", flags.FlagOutput, flags.OutputFormatText), 46 fmt.Sprintf("--%s=%s", flags.FlagKeyType, hd.Secp256k1Type), 47 fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest), 48 }) 49 mockIn.Reset("y\n") 50 require.NoError(t, cmd.ExecuteContext(ctx)) 51 52 mockIn.Reset("N\n") 53 require.Error(t, cmd.ExecuteContext(ctx)) 54 55 cmd.SetArgs([]string{ 56 "keyname2", 57 fmt.Sprintf("--%s=%s", flags.FlagKeyringDir, kbHome), 58 fmt.Sprintf("--%s=%s", flags.FlagOutput, flags.OutputFormatText), 59 fmt.Sprintf("--%s=%s", flags.FlagKeyType, hd.Secp256k1Type), 60 fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest), 61 }) 62 63 require.NoError(t, cmd.ExecuteContext(ctx)) 64 require.Error(t, cmd.ExecuteContext(ctx)) 65 66 mockIn.Reset("y\n") 67 require.NoError(t, cmd.ExecuteContext(ctx)) 68 69 cmd.SetArgs([]string{ 70 "keyname4", 71 fmt.Sprintf("--%s=%s", flags.FlagKeyringDir, kbHome), 72 fmt.Sprintf("--%s=%s", flags.FlagOutput, flags.OutputFormatText), 73 fmt.Sprintf("--%s=%s", flags.FlagKeyType, hd.Secp256k1Type), 74 fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest), 75 }) 76 77 require.NoError(t, cmd.ExecuteContext(ctx)) 78 require.Error(t, cmd.ExecuteContext(ctx)) 79 80 cmd.SetArgs([]string{ 81 "keyname5", 82 fmt.Sprintf("--%s=%s", flags.FlagKeyringDir, kbHome), 83 fmt.Sprintf("--%s=true", flags.FlagDryRun), 84 fmt.Sprintf("--%s=%s", flags.FlagOutput, flags.OutputFormatText), 85 fmt.Sprintf("--%s=%s", flags.FlagKeyType, hd.Secp256k1Type), 86 }) 87 88 require.NoError(t, cmd.ExecuteContext(ctx)) 89 90 // In recovery mode 91 cmd.SetArgs([]string{ 92 "keyname6", 93 fmt.Sprintf("--%s=true", flagRecover), 94 }) 95 96 // use valid mnemonic and complete recovery key generation successfully 97 mockIn.Reset("decide praise business actor peasant farm drastic weather extend front hurt later song give verb rhythm worry fun pond reform school tumble august one\n") 98 require.NoError(t, cmd.ExecuteContext(ctx)) 99 100 // use invalid mnemonic and fail recovery key generation 101 mockIn.Reset("invalid mnemonic\n") 102 require.Error(t, cmd.ExecuteContext(ctx)) 103 104 // In interactive mode 105 cmd.SetArgs([]string{ 106 "keyname7", 107 "-i", 108 fmt.Sprintf("--%s=false", flagRecover), 109 }) 110 111 const password = "password1!" 112 113 // set password and complete interactive key generation successfully 114 mockIn.Reset("\n" + password + "\n" + password + "\n") 115 require.NoError(t, cmd.ExecuteContext(ctx)) 116 117 // passwords don't match and fail interactive key generation 118 mockIn.Reset("\n" + password + "\n" + "fail" + "\n") 119 require.Error(t, cmd.ExecuteContext(ctx)) 120 } 121 122 func Test_runAddCmdDryRun(t *testing.T) { 123 pubkey1 := `{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AtObiFVE4s+9+RX5SP8TN9r2mxpoaT4eGj9CJfK7VRzN"}` 124 pubkey2 := `{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A/se1vkqgdQ7VJQCM4mxN+L+ciGhnnJ4XYsQCRBMrdRi"}` 125 b64Pubkey := "QWhnOHhpdXBJcGZ2UlR2ak5la1ExclROUThTOW96YjdHK2RYQmFLVjl4aUo=" 126 cdc := moduletestutil.MakeTestEncodingConfig().Codec 127 128 testData := []struct { 129 name string 130 args []string 131 added bool 132 }{ 133 { 134 name: "account is added", 135 args: []string{ 136 "testkey", 137 fmt.Sprintf("--%s=%s", flags.FlagDryRun, "false"), 138 }, 139 added: true, 140 }, 141 { 142 name: "account is not added with dry run", 143 args: []string{ 144 "testkey", 145 fmt.Sprintf("--%s=%s", flags.FlagDryRun, "true"), 146 }, 147 added: false, 148 }, 149 { 150 name: "multisig account is added", 151 args: []string{ 152 "testkey", 153 fmt.Sprintf("--%s=%s", flags.FlagDryRun, "false"), 154 fmt.Sprintf("--%s=%s", flagMultisig, "subkey"), 155 }, 156 added: true, 157 }, 158 { 159 name: "multisig account is not added with dry run", 160 args: []string{ 161 "testkey", 162 fmt.Sprintf("--%s=%s", flags.FlagDryRun, "true"), 163 fmt.Sprintf("--%s=%s", flagMultisig, "subkey"), 164 }, 165 added: false, 166 }, 167 { 168 name: "pubkey account is added", 169 args: []string{ 170 "testkey", 171 fmt.Sprintf("--%s=%s", flags.FlagDryRun, "false"), 172 fmt.Sprintf("--%s=%s", FlagPublicKey, pubkey1), 173 }, 174 added: true, 175 }, 176 { 177 name: "pubkey account is not added with dry run", 178 args: []string{ 179 "testkey", 180 fmt.Sprintf("--%s=%s", flags.FlagDryRun, "true"), 181 fmt.Sprintf("--%s=%s", FlagPublicKey, pubkey2), 182 }, 183 added: false, 184 }, 185 { 186 name: "base64 pubkey account is added", 187 args: []string{ 188 "testkey", 189 fmt.Sprintf("--%s=%s", flags.FlagDryRun, "false"), 190 fmt.Sprintf("--%s=%s", flagPubKeyBase64, b64Pubkey), 191 }, 192 added: true, 193 }, 194 { 195 name: "base64 pubkey account is not added with dry run", 196 args: []string{ 197 "testkey", 198 fmt.Sprintf("--%s=%s", flags.FlagDryRun, "true"), 199 fmt.Sprintf("--%s=%s", flagPubKeyBase64, b64Pubkey), 200 }, 201 added: false, 202 }, 203 } 204 for _, tt := range testData { 205 tt := tt 206 t.Run(tt.name, func(t *testing.T) { 207 cmd := AddKeyCommand() 208 cmd.Flags().AddFlagSet(Commands().PersistentFlags()) 209 210 kbHome := t.TempDir() 211 mockIn := testutil.ApplyMockIODiscardOutErr(cmd) 212 213 kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome, mockIn, cdc) 214 require.NoError(t, err) 215 216 clientCtx := client.Context{}. 217 WithCodec(cdc). 218 WithKeyringDir(kbHome). 219 WithKeyring(kb) 220 ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx) 221 222 path := sdk.GetConfig().GetFullBIP44Path() 223 _, err = kb.NewAccount("subkey", testdata.TestMnemonic, "", path, hd.Secp256k1) 224 require.NoError(t, err) 225 226 t.Cleanup(func() { 227 _ = kb.Delete("subkey") 228 }) 229 230 b := bytes.NewBufferString("") 231 cmd.SetOut(b) 232 233 cmd.SetArgs(tt.args) 234 require.NoError(t, cmd.ExecuteContext(ctx)) 235 236 if tt.added { 237 _, err := kb.Key("testkey") 238 require.NoError(t, err) 239 240 out, err := io.ReadAll(b) 241 require.NoError(t, err) 242 require.Contains(t, string(out), "name: testkey") 243 } else { 244 _, err = kb.Key("testkey") 245 require.Error(t, err) 246 require.Equal(t, "testkey.info: key not found", err.Error()) 247 } 248 }) 249 } 250 } 251 252 func TestAddRecoverFileBackend(t *testing.T) { 253 cmd := AddKeyCommand() 254 cmd.Flags().AddFlagSet(Commands().PersistentFlags()) 255 cdc := moduletestutil.MakeTestEncodingConfig().Codec 256 257 mockIn := testutil.ApplyMockIODiscardOutErr(cmd) 258 kbHome := t.TempDir() 259 260 clientCtx := client.Context{}.WithKeyringDir(kbHome).WithInput(mockIn).WithCodec(cdc) 261 ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx) 262 263 cmd.SetArgs([]string{ 264 "keyname1", 265 fmt.Sprintf("--%s=%s", flags.FlagKeyringDir, kbHome), 266 fmt.Sprintf("--%s=%s", flags.FlagOutput, flags.OutputFormatText), 267 fmt.Sprintf("--%s=%s", flags.FlagKeyType, hd.Secp256k1Type), 268 fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendFile), 269 fmt.Sprintf("--%s", flagRecover), 270 }) 271 272 keyringPassword := "12345678" 273 274 entropySeed, err := bip39.NewEntropy(mnemonicEntropySize) 275 require.NoError(t, err) 276 277 mnemonic, err := bip39.NewMnemonic(entropySeed) 278 require.NoError(t, err) 279 280 mockIn.Reset(fmt.Sprintf("%s\n%s\n%s\n", mnemonic, keyringPassword, keyringPassword)) 281 require.NoError(t, cmd.ExecuteContext(ctx)) 282 283 kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendFile, kbHome, mockIn, cdc) 284 require.NoError(t, err) 285 286 t.Cleanup(func() { 287 mockIn.Reset(fmt.Sprintf("%s\n%s\n", keyringPassword, keyringPassword)) 288 _ = kb.Delete("keyname1") 289 }) 290 291 mockIn.Reset(fmt.Sprintf("%s\n%s\n", keyringPassword, keyringPassword)) 292 k, err := kb.Key("keyname1") 293 require.NoError(t, err) 294 require.Equal(t, "keyname1", k.Name) 295 }