github.com/cosmos/cosmos-sdk@v0.50.1/crypto/keyring/keyring_test.go (about)

     1  package keyring
     2  
     3  import (
     4  	"encoding/hex"
     5  	"errors"
     6  	"fmt"
     7  	"io"
     8  	"os"
     9  	"path/filepath"
    10  	"strconv"
    11  	"strings"
    12  	"testing"
    13  
    14  	"github.com/99designs/keyring"
    15  	cmtcrypto "github.com/cometbft/cometbft/crypto"
    16  	"github.com/stretchr/testify/require"
    17  	"golang.org/x/crypto/bcrypt"
    18  
    19  	"github.com/cosmos/cosmos-sdk/codec"
    20  	codectypes "github.com/cosmos/cosmos-sdk/codec/types"
    21  	"github.com/cosmos/cosmos-sdk/crypto"
    22  	cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
    23  	"github.com/cosmos/cosmos-sdk/crypto/hd"
    24  	cosmosbcrypt "github.com/cosmos/cosmos-sdk/crypto/keys/bcrypt"
    25  	"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
    26  	"github.com/cosmos/cosmos-sdk/crypto/keys/multisig"
    27  	"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
    28  	"github.com/cosmos/cosmos-sdk/crypto/types"
    29  	sdk "github.com/cosmos/cosmos-sdk/types"
    30  	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
    31  	"github.com/cosmos/cosmos-sdk/types/tx/signing"
    32  )
    33  
    34  const (
    35  	someKey = "theKey"
    36  	theID   = "theID"
    37  	otherID = "otherID"
    38  )
    39  
    40  func init() {
    41  	crypto.BcryptSecurityParameter = 1
    42  }
    43  
    44  func getCodec() codec.Codec {
    45  	registry := codectypes.NewInterfaceRegistry()
    46  	cryptocodec.RegisterInterfaces(registry)
    47  	return codec.NewProtoCodec(registry)
    48  }
    49  
    50  func TestNewKeyring(t *testing.T) {
    51  	cdc := getCodec()
    52  
    53  	tests := []struct {
    54  		name        string
    55  		appName     string
    56  		backend     string
    57  		dir         string
    58  		userInput   io.Reader
    59  		cdc         codec.Codec
    60  		expectedErr error
    61  	}{
    62  		{
    63  			name:        "file backend",
    64  			appName:     "cosmos",
    65  			backend:     BackendFile,
    66  			dir:         t.TempDir(),
    67  			userInput:   strings.NewReader(""),
    68  			cdc:         cdc,
    69  			expectedErr: nil,
    70  		},
    71  		{
    72  			name:        "unknown backend",
    73  			appName:     "cosmos",
    74  			backend:     "unknown",
    75  			dir:         t.TempDir(),
    76  			userInput:   strings.NewReader(""),
    77  			cdc:         cdc,
    78  			expectedErr: ErrUnknownBacked,
    79  		},
    80  	}
    81  	for _, tt := range tests {
    82  		t.Run(tt.name, func(t *testing.T) {
    83  			kr, err := New(tt.appName, tt.backend, tt.dir, tt.userInput, tt.cdc)
    84  			if tt.expectedErr == nil {
    85  				require.NoError(t, err)
    86  			} else {
    87  				require.Error(t, err)
    88  				require.Nil(t, kr)
    89  				require.True(t, errors.Is(err, tt.expectedErr))
    90  			}
    91  		})
    92  	}
    93  }
    94  
    95  func TestNewMnemonic(t *testing.T) {
    96  	cdc := getCodec()
    97  	tests := []struct {
    98  		name          string
    99  		backend       string
   100  		reader        *strings.Reader
   101  		userInput     string
   102  		path          string
   103  		algo          SignatureAlgo
   104  		uid           string
   105  		language      Language
   106  		expectedError error
   107  	}{
   108  		{
   109  			name:          "create new mnemonic",
   110  			backend:       BackendMemory,
   111  			reader:        strings.NewReader(""),
   112  			userInput:     "password\npassword\n",
   113  			path:          sdk.FullFundraiserPath,
   114  			algo:          hd.Secp256k1,
   115  			uid:           "foo",
   116  			language:      English,
   117  			expectedError: nil,
   118  		},
   119  		{
   120  			name:          "not supported algo",
   121  			backend:       BackendMemory,
   122  			reader:        strings.NewReader(""),
   123  			userInput:     "password\npassword\n",
   124  			path:          sdk.FullFundraiserPath,
   125  			algo:          notSupportedAlgo{},
   126  			uid:           "foo",
   127  			language:      English,
   128  			expectedError: ErrUnsupportedSigningAlgo,
   129  		},
   130  		{
   131  			name:          "unsupported language",
   132  			backend:       BackendMemory,
   133  			reader:        strings.NewReader(""),
   134  			userInput:     "password\npassword\n",
   135  			path:          sdk.FullFundraiserPath,
   136  			algo:          hd.Secp256k1,
   137  			uid:           "foo",
   138  			language:      Spanish,
   139  			expectedError: ErrUnsupportedLanguage,
   140  		},
   141  	}
   142  	for _, tt := range tests {
   143  		t.Run(tt.name, func(t *testing.T) {
   144  			kr, err := New("cosmos", tt.backend, t.TempDir(), tt.reader, cdc)
   145  			require.NoError(t, err)
   146  			tt.reader.Reset(tt.userInput)
   147  			k, _, err := kr.NewMnemonic(tt.uid, tt.language, tt.path, DefaultBIP39Passphrase, tt.algo)
   148  			if tt.expectedError == nil {
   149  				require.NoError(t, err)
   150  				require.Equal(t, tt.uid, k.Name)
   151  			} else {
   152  				require.Error(t, err)
   153  				require.True(t, errors.Is(err, tt.expectedError))
   154  			}
   155  		})
   156  	}
   157  }
   158  
   159  func TestKeyringDirectory(t *testing.T) {
   160  	dir := t.TempDir()
   161  	kb, err := New("keybasename", "test", dir, nil, getCodec())
   162  	require.NoError(t, err)
   163  
   164  	// create some random directory inside the keyring directory to check migrate ignores
   165  	// all files other than *.info
   166  	newPath := filepath.Join(dir, "random")
   167  	require.NoError(t, os.Mkdir(newPath, 0o755))
   168  	items, err := os.ReadDir(dir)
   169  	require.NoError(t, err)
   170  	require.GreaterOrEqual(t, len(items), 1)
   171  	keys, err := kb.List()
   172  	require.NoError(t, err)
   173  	require.Empty(t, keys)
   174  
   175  	_, _, err = kb.NewMnemonic("uid", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
   176  	require.NoError(t, err)
   177  
   178  	items, err = os.ReadDir(dir)
   179  	require.NoError(t, err)
   180  	require.GreaterOrEqual(t, len(items), 2)
   181  }
   182  
   183  func TestNewKey(t *testing.T) {
   184  	cdc := getCodec()
   185  	tests := []struct {
   186  		name    string
   187  		backend string
   188  		uid     string
   189  	}{
   190  		{
   191  			name:    "key creation",
   192  			backend: BackendTest,
   193  			uid:     "newKey",
   194  		},
   195  		{
   196  			name:    "in memory key creation",
   197  			backend: BackendMemory,
   198  			uid:     "newKey",
   199  		},
   200  	}
   201  	for _, tt := range tests {
   202  		t.Run(tt.name, func(t *testing.T) {
   203  			kb, err := New("keybasename", tt.backend, t.TempDir(), nil, cdc)
   204  			require.NoError(t, err)
   205  
   206  			// Check empty state
   207  			l, err := kb.List()
   208  			require.NoError(t, err)
   209  			require.Empty(t, l)
   210  
   211  			_, err = kb.Key(tt.uid)
   212  			require.Error(t, err)
   213  
   214  			r, _, err := kb.NewMnemonic(tt.uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
   215  			require.NoError(t, err)
   216  			require.Equal(t, tt.uid, r.Name)
   217  
   218  			k, err := kb.Key(tt.uid)
   219  			require.NoError(t, err)
   220  
   221  			addr, err := accAddr(k)
   222  			require.NoError(t, err)
   223  			_, err = kb.KeyByAddress(addr)
   224  			require.NoError(t, err)
   225  
   226  			addr, err = sdk.AccAddressFromBech32("cosmos1yq8lgssgxlx9smjhes6ryjasmqmd3ts2559g0t")
   227  			require.NoError(t, err)
   228  			_, err = kb.KeyByAddress(addr)
   229  			require.NotNil(t, err)
   230  
   231  			// list shows them in order
   232  			keyS, err := kb.List()
   233  			require.NoError(t, err)
   234  			require.Equal(t, 1, len(keyS))
   235  			require.Equal(t, tt.uid, keyS[0].Name)
   236  		})
   237  	}
   238  }
   239  
   240  func TestGetPub(t *testing.T) {
   241  	cdc := getCodec()
   242  	tests := []struct {
   243  		name    string
   244  		backend string
   245  		uid     string
   246  	}{
   247  		{
   248  			name:    "correct get",
   249  			backend: BackendTest,
   250  			uid:     "getKey",
   251  		},
   252  		{
   253  			name:    "in memory correct get",
   254  			backend: BackendMemory,
   255  			uid:     "getMemoryKey",
   256  		},
   257  	}
   258  	for _, tt := range tests {
   259  		t.Run(tt.name, func(t *testing.T) {
   260  			kb, err := New("keybasename", tt.backend, t.TempDir(), nil, cdc)
   261  			require.NoError(t, err)
   262  
   263  			r, _, err := kb.NewMnemonic(tt.uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
   264  			require.NoError(t, err)
   265  			require.Equal(t, tt.uid, r.Name)
   266  
   267  			k, err := kb.Key(tt.uid)
   268  			require.NoError(t, err)
   269  			_, err = k.GetPubKey()
   270  			require.NoError(t, err)
   271  
   272  			keyS, err := kb.List()
   273  			require.NoError(t, err)
   274  			require.Equal(t, 1, len(keyS))
   275  		})
   276  	}
   277  }
   278  
   279  func TestDeleteKey(t *testing.T) {
   280  	cdc := getCodec()
   281  	tests := []struct {
   282  		name    string
   283  		backend string
   284  		uid     string
   285  	}{
   286  		{
   287  			name:    "delete",
   288  			backend: BackendTest,
   289  			uid:     "key",
   290  		},
   291  		{
   292  			name:    "in memory delete",
   293  			backend: BackendMemory,
   294  			uid:     "key",
   295  		},
   296  	}
   297  	for _, tt := range tests {
   298  		t.Run(tt.name, func(t *testing.T) {
   299  			kb, err := New("keybasename", tt.backend, t.TempDir(), nil, cdc)
   300  			require.NoError(t, err)
   301  
   302  			r, _, err := kb.NewMnemonic(tt.uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
   303  			require.NoError(t, err)
   304  			require.Equal(t, tt.uid, r.Name)
   305  
   306  			err = kb.Delete(tt.uid)
   307  			require.NoError(t, err)
   308  			list, err := kb.List()
   309  			require.NoError(t, err)
   310  			require.Empty(t, list)
   311  		})
   312  	}
   313  }
   314  
   315  func TestOfflineKey(t *testing.T) {
   316  	cdc := getCodec()
   317  	tests := []struct {
   318  		name    string
   319  		backend string
   320  		uid     string
   321  	}{
   322  		{
   323  			name:    "offline creation",
   324  			backend: BackendTest,
   325  			uid:     "offline",
   326  		},
   327  		{
   328  			name:    "in memory offline creation",
   329  			backend: BackendMemory,
   330  			uid:     "offline",
   331  		},
   332  	}
   333  	for _, tt := range tests {
   334  		t.Run(tt.name, func(t *testing.T) {
   335  			kb, err := New("keybasename", tt.backend, t.TempDir(), nil, cdc)
   336  			require.NoError(t, err)
   337  
   338  			priv := ed25519.GenPrivKey()
   339  			pub := priv.PubKey()
   340  			k, err := kb.SaveOfflineKey(tt.uid, pub)
   341  			require.NoError(t, err)
   342  			require.Equal(t, tt.uid, k.Name)
   343  
   344  			key, err := k.GetPubKey()
   345  			require.NoError(t, err)
   346  			require.Equal(t, pub, key)
   347  
   348  			require.NotNil(t, k.GetOffline())
   349  			keys, err := kb.List()
   350  			require.NoError(t, err)
   351  			require.Equal(t, 1, len(keys))
   352  
   353  			err = kb.Delete(tt.uid)
   354  			require.NoError(t, err)
   355  			keys, err = kb.List()
   356  			require.NoError(t, err)
   357  			require.Empty(t, keys)
   358  		})
   359  	}
   360  }
   361  
   362  func TestSignVerifyKeyRing(t *testing.T) {
   363  	dir := t.TempDir()
   364  	cdc := getCodec()
   365  
   366  	kb, err := New("keybasename", "test", dir, nil, cdc)
   367  	require.NoError(t, err)
   368  	algo := hd.Secp256k1
   369  
   370  	n1, n2, n3 := "some dude", "a dudette", "dude-ish"
   371  
   372  	// create two users and get their info
   373  	kr1, _, err := kb.NewMnemonic(n1, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, algo)
   374  	require.Nil(t, err)
   375  
   376  	kr2, _, err := kb.NewMnemonic(n2, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, algo)
   377  	require.Nil(t, err)
   378  
   379  	// let's try to sign some messages
   380  	d1 := []byte("my first message")
   381  	d2 := []byte("some other important info!")
   382  	d3 := []byte("feels like I forgot something...")
   383  
   384  	// try signing both data with both ..
   385  	s11, pub1, err := kb.Sign(n1, d1, signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON)
   386  	require.NoError(t, err)
   387  
   388  	key1, err := kr1.GetPubKey()
   389  	require.NoError(t, err)
   390  	require.NotNil(t, key1)
   391  	require.Equal(t, key1, pub1)
   392  
   393  	s12, pub1, err := kb.Sign(n1, d2, signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON)
   394  	require.Nil(t, err)
   395  	require.Equal(t, key1, pub1)
   396  
   397  	s21, pub2, err := kb.Sign(n2, d1, signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON)
   398  	require.Nil(t, err)
   399  
   400  	key2, err := kr2.GetPubKey()
   401  	require.NoError(t, err)
   402  	require.NotNil(t, key2)
   403  	require.Equal(t, key2, pub2)
   404  
   405  	s22, pub2, err := kb.Sign(n2, d2, signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON)
   406  	require.Nil(t, err)
   407  	require.Equal(t, key2, pub2)
   408  
   409  	// let's try to validate and make sure it only works when everything is proper
   410  	cases := []struct {
   411  		key   types.PubKey
   412  		data  []byte
   413  		sig   []byte
   414  		valid bool
   415  	}{
   416  		// proper matches
   417  		{key1, d1, s11, true},
   418  		// change data, pubkey, or signature leads to fail
   419  		{key1, d2, s11, false},
   420  		{key2, d1, s11, false},
   421  		{key1, d1, s21, false},
   422  		// make sure other successes
   423  		{key1, d2, s12, true},
   424  		{key2, d1, s21, true},
   425  		{key2, d2, s22, true},
   426  	}
   427  
   428  	for i, tc := range cases {
   429  		valid := tc.key.VerifySignature(tc.data, tc.sig)
   430  		require.Equal(t, tc.valid, valid, "%d", i)
   431  	}
   432  
   433  	// Now try to sign data with a secret-less key
   434  	// Import a public key
   435  	armor, err := kb.ExportPubKeyArmor(n2)
   436  	require.NoError(t, err)
   437  	require.NoError(t, kb.Delete(n2))
   438  
   439  	require.NoError(t, kb.ImportPubKey(n3, armor))
   440  	i3, err := kb.Key(n3)
   441  	require.NoError(t, err)
   442  	require.Equal(t, i3.Name, n3)
   443  
   444  	_, _, err = kb.Sign(n3, d3, signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON)
   445  	require.Error(t, err)
   446  	require.Equal(t, "cannot sign with offline keys", err.Error())
   447  }
   448  
   449  func TestExportPrivKey(t *testing.T) {
   450  	cdc := getCodec()
   451  	tests := []struct {
   452  		name              string
   453  		uid               string
   454  		backend           string
   455  		encryptPassphrase string
   456  		createKey         func(keystore2 Keyring) (*Record, string, error)
   457  		expectedErr       error
   458  	}{
   459  		{
   460  			name:              "correct export",
   461  			uid:               "correctTest",
   462  			backend:           BackendTest,
   463  			encryptPassphrase: "myPassphrase",
   464  			createKey: func(keystore Keyring) (*Record, string, error) {
   465  				return keystore.NewMnemonic("correctTest", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase,
   466  					hd.Secp256k1)
   467  			},
   468  			expectedErr: nil,
   469  		},
   470  		{
   471  			name:              "correct in memory export",
   472  			uid:               "inMemory",
   473  			backend:           BackendMemory,
   474  			encryptPassphrase: "myPassphrase",
   475  			createKey: func(keystore Keyring) (*Record, string, error) {
   476  				return keystore.NewMnemonic("inMemory", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase,
   477  					hd.Secp256k1)
   478  			},
   479  			expectedErr: nil,
   480  		},
   481  		{
   482  			name:              "key is not created",
   483  			uid:               "noKeyTest",
   484  			backend:           BackendTest,
   485  			encryptPassphrase: "myPassphrase",
   486  			createKey: func(keystore Keyring) (*Record, string, error) {
   487  				return nil, "", nil
   488  			},
   489  			expectedErr: sdkerrors.ErrKeyNotFound,
   490  		},
   491  	}
   492  	for _, tt := range tests {
   493  		t.Run(tt.name, func(t *testing.T) {
   494  			kb, err := New("testExport", tt.backend, t.TempDir(), nil, cdc)
   495  			require.NoError(t, err)
   496  			_, _, err = tt.createKey(kb)
   497  			require.NoError(t, err)
   498  			_, err = kb.ExportPrivKeyArmor(tt.uid, tt.encryptPassphrase)
   499  			if tt.expectedErr == nil {
   500  				require.NoError(t, err)
   501  			} else {
   502  				require.Error(t, err)
   503  				require.True(t, errors.Is(err, tt.expectedErr))
   504  			}
   505  		})
   506  	}
   507  }
   508  
   509  func TestImportPrivKey(t *testing.T) {
   510  	cdc := getCodec()
   511  	tests := []struct {
   512  		name              string
   513  		uid               string
   514  		backend           string
   515  		encryptPassphrase string
   516  		armor             string
   517  		expectedErr       error
   518  	}{
   519  		{
   520  			name:              "correct import",
   521  			uid:               "testOne",
   522  			backend:           BackendTest,
   523  			encryptPassphrase: "this passphrase has been used for all test vectors",
   524  			armor:             "-----BEGIN TENDERMINT PRIVATE KEY-----\nkdf: bcrypt\nsalt: 6BC5D5187F9DF241E1A1243EECFF9C17\ntype: secp256k1\n\nGDPpPfrSVZloiwufbal19fmd75QeiqwToZ949SwmnxxM03qL75xXVf3tTD/BrF4l\nFs14HuhwntDBM2xgZvymTBk2edHlEI20Phv6oC0=\n=/zZh\n-----END TENDERMINT PRIVATE KEY-----",
   525  			expectedErr:       nil,
   526  		},
   527  		{
   528  			name:              "correct import",
   529  			uid:               "inMemory",
   530  			backend:           BackendMemory,
   531  			encryptPassphrase: "this passphrase has been used for all test vectors",
   532  			armor:             "-----BEGIN TENDERMINT PRIVATE KEY-----\nkdf: bcrypt\nsalt: 6BC5D5187F9DF241E1A1243EECFF9C17\ntype: secp256k1\n\nGDPpPfrSVZloiwufbal19fmd75QeiqwToZ949SwmnxxM03qL75xXVf3tTD/BrF4l\nFs14HuhwntDBM2xgZvymTBk2edHlEI20Phv6oC0=\n=/zZh\n-----END TENDERMINT PRIVATE KEY-----",
   533  			expectedErr:       nil,
   534  		},
   535  		{
   536  			name:              "wrong armor",
   537  			uid:               "testWrongArmor",
   538  			backend:           BackendTest,
   539  			encryptPassphrase: "this passphrase has been used for all test vectors",
   540  			armor:             "-----BEGIN TENDERMINT PRIVATE KEY-----\nkdf: bcrypt\nsalt: 7BC5D5187F9DF241E1A1243EECFF9C17\ntype: secp256k1\n\nGDPpPfrSVZloiwufbal19fmd75QeiqwToZ949SwmnxxM03qL75xXVf3tTD/BrF4l\nFs14HuhwntDBM2xgZvymTBk2edHlEI20Phv6oC0=\n=/zZh\n-----END TENDERMINT PRIVATE KEY-----",
   541  			expectedErr:       sdkerrors.ErrWrongPassword,
   542  		},
   543  		{
   544  			name:              "incorrect passphrase",
   545  			uid:               "testIncorrectPassphrase",
   546  			backend:           BackendTest,
   547  			encryptPassphrase: "wrong passphrase",
   548  			armor:             "-----BEGIN TENDERMINT PRIVATE KEY-----\nkdf: bcrypt\nsalt: 6BC5D5187F9DF241E1A1243EECFF9C17\ntype: secp256k1\n\nGDPpPfrSVZloiwufbal19fmd75QeiqwToZ949SwmnxxM03qL75xXVf3tTD/BrF4l\nFs14HuhwntDBM2xgZvymTBk2edHlEI20Phv6oC0=\n=/zZh\n-----END TENDERMINT PRIVATE KEY-----",
   549  			expectedErr:       sdkerrors.ErrWrongPassword,
   550  		},
   551  	}
   552  	for _, tt := range tests {
   553  		t.Run(tt.name, func(t *testing.T) {
   554  			kb, err := New("TestExport", tt.backend, t.TempDir(), nil, cdc)
   555  			require.NoError(t, err)
   556  			err = kb.ImportPrivKey(tt.uid, tt.armor, tt.encryptPassphrase)
   557  			if tt.expectedErr == nil {
   558  				require.NoError(t, err)
   559  			} else {
   560  				require.Error(t, err)
   561  				require.True(t, errors.Is(err, tt.expectedErr))
   562  			}
   563  		})
   564  	}
   565  }
   566  
   567  func TestImportPrivKeyHex(t *testing.T) {
   568  	cdc := getCodec()
   569  	tests := []struct {
   570  		name        string
   571  		uid         string
   572  		backend     string
   573  		hexKey      string
   574  		algo        string
   575  		expectedErr error
   576  	}{
   577  		{
   578  			name:        "correct import",
   579  			uid:         "hexImport",
   580  			backend:     BackendTest,
   581  			hexKey:      "0xa3e57952e835ed30eea86a2993ac2a61c03e74f2085b3635bd94aa4d7ae0cfdf",
   582  			algo:        "secp256k1",
   583  			expectedErr: nil,
   584  		},
   585  		{
   586  			name:        "correct import without prefix",
   587  			uid:         "hexImport",
   588  			backend:     BackendTest,
   589  			hexKey:      "a3e57952e835ed30eea86a2993ac2a61c03e74f2085b3635bd94aa4d7ae0cfdf",
   590  			algo:        "secp256k1",
   591  			expectedErr: nil,
   592  		},
   593  		{
   594  			name:        "wrong hex length",
   595  			uid:         "hexImport",
   596  			backend:     BackendTest,
   597  			hexKey:      "0xae57952e835ed30eea86a2993ac2a61c03e74f2085b3635bd94aa4d7ae0cfdf",
   598  			algo:        "secp256k1",
   599  			expectedErr: hex.ErrLength,
   600  		},
   601  		{
   602  			name:        "unsupported algo",
   603  			uid:         "hexImport",
   604  			backend:     BackendTest,
   605  			hexKey:      "0xa3e57952e835ed30eea86a2993ac2a61c03e74f2085b3635bd94aa4d7ae0cfdf",
   606  			algo:        "notSupportedAlgo",
   607  			expectedErr: ErrUnsupportedSigningAlgo,
   608  		},
   609  	}
   610  	for _, tt := range tests {
   611  		t.Run(tt.name, func(t *testing.T) {
   612  			kb, err := New("TestExport", tt.backend, t.TempDir(), nil, cdc)
   613  			require.NoError(t, err)
   614  			err = kb.ImportPrivKeyHex(tt.uid, tt.hexKey, tt.algo)
   615  			if tt.expectedErr == nil {
   616  				require.NoError(t, err)
   617  			} else {
   618  				require.Error(t, err)
   619  				require.True(t, errors.Is(err, tt.expectedErr))
   620  			}
   621  		})
   622  	}
   623  }
   624  
   625  func TestExportImportPrivKeyArmor(t *testing.T) {
   626  	cdc := getCodec()
   627  	tests := []struct {
   628  		name              string
   629  		uid               string
   630  		backend           string
   631  		userInput         io.Reader
   632  		encryptPassphrase string
   633  		importUID         string
   634  		importPassphrase  string
   635  	}{
   636  		{
   637  			name:              "export import",
   638  			uid:               "testOne",
   639  			backend:           BackendTest,
   640  			userInput:         nil,
   641  			encryptPassphrase: "apassphrase",
   642  			importUID:         "importedKey",
   643  			importPassphrase:  "apassphrase",
   644  		},
   645  		{
   646  			name:              "memory export import",
   647  			uid:               "inMemory",
   648  			backend:           BackendMemory,
   649  			userInput:         nil,
   650  			encryptPassphrase: "apassphrase",
   651  			importUID:         "importedKey",
   652  			importPassphrase:  "apassphrase",
   653  		},
   654  	}
   655  	for _, tt := range tests {
   656  		t.Run(tt.name, func(t *testing.T) {
   657  			kb, err := New("TestExport", tt.backend, t.TempDir(), tt.userInput, cdc)
   658  			require.NoError(t, err)
   659  			k, _, err := kb.NewMnemonic(tt.uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
   660  			require.NoError(t, err)
   661  			require.NotNil(t, k)
   662  			require.Equal(t, k.Name, tt.uid)
   663  
   664  			record, err := kb.Key(tt.uid)
   665  			require.NoError(t, err)
   666  			require.Equal(t, record.Name, tt.uid)
   667  			key, err := k.GetPubKey()
   668  			require.NoError(t, err)
   669  
   670  			armor, err := kb.ExportPrivKeyArmor(tt.uid, tt.encryptPassphrase)
   671  			require.NoError(t, err)
   672  
   673  			// Import while key has not been deleted
   674  			err = kb.ImportPrivKey(tt.uid, armor, tt.importPassphrase)
   675  			require.Error(t, err)
   676  			require.True(t, errors.Is(err, ErrOverwriteKey))
   677  
   678  			err = kb.Delete(tt.uid)
   679  			require.NoError(t, err)
   680  
   681  			err = kb.ImportPrivKey(tt.importUID, armor, tt.importPassphrase)
   682  			require.NoError(t, err)
   683  
   684  			importedRecord, err := kb.Key(tt.importUID)
   685  			require.NoError(t, err)
   686  			require.Equal(t, importedRecord.Name, tt.importUID)
   687  			importedKey, err := importedRecord.GetPubKey()
   688  			require.NoError(t, err)
   689  
   690  			require.Equal(t, key.Address(), importedKey.Address())
   691  
   692  			addr, err := record.GetAddress()
   693  			require.NoError(t, err)
   694  			importedAddr, err := importedRecord.GetAddress()
   695  			require.NoError(t, err)
   696  			require.True(t, addr.Equals(importedAddr))
   697  		})
   698  	}
   699  }
   700  
   701  func TestImportExportPrivKeyByAddress(t *testing.T) {
   702  	cdc := getCodec()
   703  	tests := []struct {
   704  		name             string
   705  		uid              string
   706  		backend          string
   707  		passphrase       string
   708  		importPassphrase string
   709  		expectedErr      error
   710  	}{
   711  		{
   712  			name:             "correct import export",
   713  			uid:              "okTest",
   714  			backend:          BackendTest,
   715  			passphrase:       "exportKey",
   716  			importPassphrase: "exportKey",
   717  			expectedErr:      nil,
   718  		},
   719  		{
   720  			name:             "correct in memory import export",
   721  			uid:              "inMemory",
   722  			backend:          BackendMemory,
   723  			passphrase:       "exportKey",
   724  			importPassphrase: "exportKey",
   725  			expectedErr:      nil,
   726  		},
   727  		{
   728  			name:             "wrong passphrase import",
   729  			uid:              "incorrectPass",
   730  			backend:          BackendTest,
   731  			passphrase:       "exportKey",
   732  			importPassphrase: "incorrectPassphrase",
   733  			expectedErr:      sdkerrors.ErrWrongPassword,
   734  		},
   735  	}
   736  	for _, tt := range tests {
   737  		t.Run(tt.name, func(t *testing.T) {
   738  			kr, err := New(t.Name(), tt.backend, t.TempDir(), nil, cdc)
   739  			require.NoError(t, err)
   740  
   741  			mnemonic, _, err := kr.NewMnemonic(tt.uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
   742  			require.NoError(t, err)
   743  
   744  			addr, err := mnemonic.GetAddress()
   745  			require.NoError(t, err)
   746  			armor, err := kr.ExportPrivKeyArmorByAddress(addr, tt.passphrase)
   747  			require.NoError(t, err)
   748  
   749  			// Should fail importing private key on existing key.
   750  			err = kr.ImportPrivKey(tt.uid, armor, tt.passphrase)
   751  			require.True(t, errors.Is(err, ErrOverwriteKey))
   752  
   753  			err = kr.Delete(tt.uid)
   754  			require.NoError(t, err)
   755  
   756  			err = kr.ImportPrivKey(tt.uid, armor, tt.importPassphrase)
   757  			if tt.expectedErr == nil {
   758  				require.NoError(t, err)
   759  			} else {
   760  				require.Error(t, err)
   761  				require.True(t, errors.Is(err, tt.expectedErr))
   762  			}
   763  		})
   764  	}
   765  }
   766  
   767  func TestExportPubkey(t *testing.T) {
   768  	cdc := getCodec()
   769  	tests := []struct {
   770  		name        string
   771  		uid         string
   772  		backend     string
   773  		exportUID   string
   774  		getPubkey   func(r *Record) (types.PubKey, error)
   775  		codec       codec.Codec
   776  		expectedErr error
   777  	}{
   778  		{
   779  			name:      "correct export",
   780  			uid:       "correctExport",
   781  			backend:   BackendTest,
   782  			exportUID: "correctExport",
   783  			getPubkey: func(r *Record) (types.PubKey, error) {
   784  				return r.GetPubKey()
   785  			},
   786  			codec:       cdc,
   787  			expectedErr: nil,
   788  		},
   789  		{
   790  			name:      "wrong uid at export",
   791  			uid:       "wrongUID",
   792  			backend:   BackendTest,
   793  			exportUID: "notAValidUID",
   794  			getPubkey: func(r *Record) (types.PubKey, error) {
   795  				return r.GetPubKey()
   796  			},
   797  			codec:       cdc,
   798  			expectedErr: sdkerrors.ErrKeyNotFound,
   799  		},
   800  		{
   801  			name:      "previous space on export uid",
   802  			uid:       "prefixSpace",
   803  			backend:   BackendTest,
   804  			exportUID: " prefixSpace",
   805  			getPubkey: func(r *Record) (types.PubKey, error) {
   806  				return r.GetPubKey()
   807  			},
   808  			codec:       cdc,
   809  			expectedErr: sdkerrors.ErrKeyNotFound,
   810  		},
   811  		{
   812  			name:      "export uid with suffix space",
   813  			uid:       "suffixSpace",
   814  			backend:   BackendTest,
   815  			exportUID: "suffixSpace ",
   816  			getPubkey: func(r *Record) (types.PubKey, error) {
   817  				return r.GetPubKey()
   818  			},
   819  			codec:       cdc,
   820  			expectedErr: sdkerrors.ErrKeyNotFound,
   821  		},
   822  		{
   823  			name:      "correct in memory export",
   824  			uid:       "inMemory",
   825  			backend:   BackendMemory,
   826  			exportUID: "inMemory",
   827  			getPubkey: func(r *Record) (types.PubKey, error) {
   828  				return r.GetPubKey()
   829  			},
   830  			codec:       cdc,
   831  			expectedErr: nil,
   832  		},
   833  		{
   834  			name:      "in memory wrong uid at export",
   835  			uid:       "wrongUid",
   836  			backend:   BackendMemory,
   837  			exportUID: "notAValidUid",
   838  			getPubkey: func(r *Record) (types.PubKey, error) {
   839  				return r.GetPubKey()
   840  			},
   841  			codec:       cdc,
   842  			expectedErr: sdkerrors.ErrKeyNotFound,
   843  		},
   844  		{
   845  			name:      "in memory previous space on export uid",
   846  			uid:       "prefixSpace",
   847  			backend:   BackendMemory,
   848  			exportUID: " prefixSpace",
   849  			getPubkey: func(r *Record) (types.PubKey, error) {
   850  				return r.GetPubKey()
   851  			},
   852  			codec:       cdc,
   853  			expectedErr: sdkerrors.ErrKeyNotFound,
   854  		},
   855  		{
   856  			name:      "in memory export uid with suffix space",
   857  			uid:       "suffixSpace",
   858  			backend:   BackendMemory,
   859  			exportUID: "suffixSpace ",
   860  			getPubkey: func(r *Record) (types.PubKey, error) {
   861  				return r.GetPubKey()
   862  			},
   863  			codec:       cdc,
   864  			expectedErr: sdkerrors.ErrKeyNotFound,
   865  		},
   866  	}
   867  	for _, tt := range tests {
   868  		t.Run(tt.name, func(t *testing.T) {
   869  			kb, err := New("keybase", tt.backend, t.TempDir(), nil, cdc)
   870  			require.NoError(t, err)
   871  			k, _, err := kb.NewMnemonic(tt.uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
   872  			require.NoError(t, err)
   873  			require.NotNil(t, k)
   874  			_, err = tt.getPubkey(k)
   875  			require.NoError(t, err)
   876  			_, err = kb.ExportPubKeyArmor(tt.exportUID)
   877  			if tt.expectedErr == nil {
   878  				require.NoError(t, err)
   879  			} else {
   880  				require.Error(t, err)
   881  				require.True(t, errors.Is(err, tt.expectedErr))
   882  			}
   883  		})
   884  	}
   885  }
   886  
   887  func TestImportPubKey(t *testing.T) {
   888  	cdc := getCodec()
   889  	tests := []struct {
   890  		name        string
   891  		uid         string
   892  		backend     string
   893  		armor       string
   894  		expectedErr error
   895  	}{
   896  		{
   897  			name:        "correct import",
   898  			uid:         "correctTest",
   899  			backend:     BackendTest,
   900  			armor:       "-----BEGIN TENDERMINT PUBLIC KEY-----\nversion: 0.0.1\ntype: secp256k1\n\nCh8vY29zbW9zLmNyeXB0by5zZWNwMjU2azEuUHViS2V5EiMKIQOlcgxiZM4cR0LA\nwum483+L6zRnXC6zEKtQ4FEa6z0VrA==\n=CqBG\n-----END TENDERMINT PUBLIC KEY-----",
   901  			expectedErr: nil,
   902  		},
   903  		{
   904  			name:        "modified armor",
   905  			uid:         "modified",
   906  			backend:     BackendTest,
   907  			armor:       "-----BEGIN TENDERMINT PUBLIC KEY-----\nversion: 0.0.1\ntype: secp256k1\n\nCh8vY29zbW8zLmNyeXB0by5zZWNwMjU2azEuUHViS2V5EiMKIQOlcgxiZM4cR0LA\nwum483+L6zRnXC6zEKtQ4FEa6z0VrA==\n=CqBG\n-----END TENDERMINT PUBLIC KEY-----",
   908  			expectedErr: fmt.Errorf("couldn't unarmor bytes: openpgp: invalid data: armor invalid"),
   909  		},
   910  		{
   911  			name:        "empty armor",
   912  			uid:         "empty",
   913  			backend:     BackendTest,
   914  			armor:       "",
   915  			expectedErr: fmt.Errorf("couldn't unarmor bytes: EOF"),
   916  		},
   917  		{
   918  			name:        "correct in memory import",
   919  			uid:         "inMemory",
   920  			backend:     BackendMemory,
   921  			armor:       "-----BEGIN TENDERMINT PUBLIC KEY-----\nversion: 0.0.1\ntype: secp256k1\n\nCh8vY29zbW9zLmNyeXB0by5zZWNwMjU2azEuUHViS2V5EiMKIQOlcgxiZM4cR0LA\nwum483+L6zRnXC6zEKtQ4FEa6z0VrA==\n=CqBG\n-----END TENDERMINT PUBLIC KEY-----",
   922  			expectedErr: nil,
   923  		},
   924  	}
   925  	for _, tt := range tests {
   926  		t.Run(tt.name, func(t *testing.T) {
   927  			kb, err := New("keybasename", tt.backend, t.TempDir(), nil, cdc)
   928  			require.NoError(t, err)
   929  			err = kb.ImportPubKey(tt.uid, tt.armor)
   930  			if tt.expectedErr == nil {
   931  				require.NoError(t, err)
   932  			} else {
   933  				require.Equal(t, err, tt.expectedErr)
   934  			}
   935  		})
   936  	}
   937  }
   938  
   939  func TestExportImportPubKeyKey(t *testing.T) {
   940  	cdc := getCodec()
   941  	tests := []struct {
   942  		name      string
   943  		uid       string
   944  		backend   string
   945  		importUID string
   946  	}{
   947  		{
   948  			name:      "complete export import",
   949  			uid:       "testOne",
   950  			backend:   BackendTest,
   951  			importUID: "importedKey",
   952  		},
   953  		{
   954  			name:      "in memory export import",
   955  			uid:       "inMemory",
   956  			backend:   BackendMemory,
   957  			importUID: "importedKey",
   958  		},
   959  	}
   960  	for _, tt := range tests {
   961  		t.Run(tt.name, func(t *testing.T) {
   962  			kb, err := New("keybasename", tt.backend, t.TempDir(), nil, cdc)
   963  			require.NoError(t, err)
   964  
   965  			k, _, err := kb.NewMnemonic(tt.uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
   966  			require.Nil(t, err)
   967  			require.NotNil(t, k)
   968  			require.Equal(t, k.Name, tt.uid)
   969  
   970  			key, err := k.GetPubKey()
   971  			require.NoError(t, err)
   972  
   973  			record, err := kb.Key(tt.uid)
   974  			require.NoError(t, err)
   975  			require.Equal(t, record.Name, tt.uid)
   976  
   977  			pk, err := record.GetPubKey()
   978  			require.NoError(t, err)
   979  			require.Equal(t, key.Address(), pk.Address())
   980  
   981  			// Export the public key only
   982  			armor, err := kb.ExportPubKeyArmor(tt.uid)
   983  			require.NoError(t, err)
   984  			err = kb.Delete(tt.uid)
   985  			require.NoError(t, err)
   986  
   987  			// Import it under a different name
   988  			err = kb.ImportPubKey(tt.importUID, armor)
   989  			require.NoError(t, err)
   990  
   991  			// Ensure consistency
   992  			record2, err := kb.Key(tt.importUID)
   993  			require.NoError(t, err)
   994  			key2, err := record2.GetPubKey()
   995  			require.NoError(t, err)
   996  
   997  			// Compare the public keys
   998  			require.True(t, key.Equals(key2))
   999  
  1000  			// Ensure keys cannot be overwritten
  1001  			err = kb.ImportPubKey(tt.importUID, armor)
  1002  			require.NotNil(t, err)
  1003  		})
  1004  	}
  1005  }
  1006  
  1007  func TestImportExportPubKeyByAddress(t *testing.T) {
  1008  	cdc := getCodec()
  1009  	tests := []struct {
  1010  		name    string
  1011  		backend string
  1012  		uid     string
  1013  	}{
  1014  		{
  1015  			name:    "import export",
  1016  			backend: BackendTest,
  1017  			uid:     "okTest",
  1018  		},
  1019  		{
  1020  			name:    "in memory import export",
  1021  			backend: BackendMemory,
  1022  			uid:     "okTest",
  1023  		},
  1024  	}
  1025  	for _, tt := range tests {
  1026  		t.Run(tt.name, func(t *testing.T) {
  1027  			kr, err := New(t.Name(), tt.backend, t.TempDir(), nil, cdc)
  1028  			require.NoError(t, err)
  1029  
  1030  			mnemonic, _, err := kr.NewMnemonic(tt.uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
  1031  			require.NoError(t, err)
  1032  
  1033  			addr, err := mnemonic.GetAddress()
  1034  			require.NoError(t, err)
  1035  			armor, err := kr.ExportPubKeyArmorByAddress(addr)
  1036  			require.NoError(t, err)
  1037  
  1038  			// Should fail importing private key on existing key.
  1039  			err = kr.ImportPubKey(tt.uid, armor)
  1040  			require.True(t, errors.Is(err, ErrOverwriteKey))
  1041  
  1042  			err = kr.Delete(tt.uid)
  1043  			require.NoError(t, err)
  1044  
  1045  			err = kr.ImportPubKey(tt.uid, armor)
  1046  			require.NoError(t, err)
  1047  		})
  1048  	}
  1049  }
  1050  
  1051  func TestAltKeyring_UnsafeExportPrivKeyHex(t *testing.T) {
  1052  	cdc := getCodec()
  1053  	kr, err := New(t.Name(), BackendTest, t.TempDir(), nil, cdc)
  1054  	require.NoError(t, err)
  1055  
  1056  	uid := theID
  1057  
  1058  	_, _, err = kr.NewMnemonic(uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
  1059  	require.NoError(t, err)
  1060  
  1061  	privKey, err := kr.(keystore).ExportPrivateKeyObject(uid)
  1062  
  1063  	require.NoError(t, err)
  1064  	require.Equal(t, 64, len(hex.EncodeToString(privKey.Bytes())))
  1065  
  1066  	// test error on non existing key
  1067  	_, err = kr.(keystore).ExportPrivateKeyObject("non-existing")
  1068  	require.Error(t, err)
  1069  }
  1070  
  1071  func TestNewAccount(t *testing.T) {
  1072  	cdc := getCodec()
  1073  
  1074  	tests := []struct {
  1075  		name             string
  1076  		backend          string
  1077  		uid              string
  1078  		bip39Passphrease string
  1079  		hdpath           string
  1080  		algo             SignatureAlgo
  1081  		mnemonic         string
  1082  		expectedErr      error
  1083  	}{
  1084  		{
  1085  			name:             "correct mnemonic",
  1086  			uid:              "correctTest",
  1087  			backend:          BackendTest,
  1088  			hdpath:           sdk.FullFundraiserPath,
  1089  			bip39Passphrease: "",
  1090  			algo:             hd.Secp256k1,
  1091  			mnemonic:         "aunt imitate maximum student guard unhappy guard rotate marine panel negative merit record priority zoo voice mixture boost describe fruit often occur expect teach",
  1092  			expectedErr:      nil,
  1093  		},
  1094  		{
  1095  			name:             "correct in memory mnemonic",
  1096  			uid:              "inMemory",
  1097  			backend:          BackendMemory,
  1098  			hdpath:           sdk.FullFundraiserPath,
  1099  			bip39Passphrease: "",
  1100  			algo:             hd.Secp256k1,
  1101  			mnemonic:         "aunt imitate maximum student guard unhappy guard rotate marine panel negative merit record priority zoo voice mixture boost describe fruit often occur expect teach",
  1102  			expectedErr:      nil,
  1103  		},
  1104  		{
  1105  			name:             "unsupported Algo",
  1106  			uid:              "correctTest",
  1107  			backend:          BackendTest,
  1108  			hdpath:           sdk.FullFundraiserPath,
  1109  			bip39Passphrease: "",
  1110  			algo:             notSupportedAlgo{},
  1111  			mnemonic:         "aunt imitate maximum student guard unhappy guard rotate marine panel negative merit record priority zoo voice mixture boost describe fruit often occur expect teach",
  1112  			expectedErr:      ErrUnsupportedSigningAlgo,
  1113  		},
  1114  		{
  1115  			name:             "wrong mnemonic",
  1116  			uid:              "wrongMnemonic",
  1117  			backend:          BackendTest,
  1118  			hdpath:           sdk.FullFundraiserPath,
  1119  			bip39Passphrease: "",
  1120  			algo:             hd.Secp256k1,
  1121  			mnemonic:         "fresh enact fresh ski large bicycle marine abandon motor end pact mixture annual elite bind fan write warrior adapt common manual cool happy dutch",
  1122  			expectedErr:      fmt.Errorf("Invalid byte at position"),
  1123  		},
  1124  		{
  1125  			name:             "in memory invalid mnemonic",
  1126  			uid:              "memoryInvalid",
  1127  			backend:          BackendMemory,
  1128  			hdpath:           sdk.FullFundraiserPath,
  1129  			bip39Passphrease: "",
  1130  			algo:             hd.Secp256k1,
  1131  			mnemonic:         "malarkey pair crucial catch public canyon evil outer stage ten gym tornado",
  1132  			expectedErr:      fmt.Errorf("Invalid mnemonic"),
  1133  		},
  1134  	}
  1135  	for _, tt := range tests {
  1136  		t.Run(tt.name, func(t *testing.T) {
  1137  			kb, err := New("keybasename", tt.backend, t.TempDir(), nil, cdc)
  1138  			require.NoError(t, err)
  1139  			k1, err := kb.NewAccount(tt.uid, tt.mnemonic, DefaultBIP39Passphrase, tt.hdpath, tt.algo)
  1140  			if tt.expectedErr == nil {
  1141  				require.NoError(t, err)
  1142  				require.Equal(t, tt.uid, k1.Name)
  1143  			} else {
  1144  				require.Error(t, err)
  1145  				require.ErrorContains(t, err, err.Error())
  1146  			}
  1147  		})
  1148  	}
  1149  }
  1150  
  1151  func TestInMemoryWithKeyring(t *testing.T) {
  1152  	priv := types.PrivKey(secp256k1.GenPrivKey())
  1153  	pub := priv.PubKey()
  1154  
  1155  	cdc := getCodec()
  1156  	_, err := NewLocalRecord("test record", priv, pub)
  1157  	require.NoError(t, err)
  1158  
  1159  	multi := multisig.NewLegacyAminoPubKey(
  1160  		1, []types.PubKey{
  1161  			pub,
  1162  		},
  1163  	)
  1164  
  1165  	appName := "test-app"
  1166  
  1167  	legacyMultiInfo, err := NewLegacyMultiInfo(appName, multi)
  1168  	require.NoError(t, err)
  1169  	serializedLegacyMultiInfo := MarshalInfo(legacyMultiInfo)
  1170  
  1171  	kb := NewInMemoryWithKeyring(keyring.NewArrayKeyring([]keyring.Item{
  1172  		{
  1173  			Key:         appName + ".info",
  1174  			Data:        serializedLegacyMultiInfo,
  1175  			Description: "test description",
  1176  		},
  1177  	}), cdc)
  1178  
  1179  	t.Run("key exists", func(t *testing.T) {
  1180  		_, err := kb.Key(appName)
  1181  		require.NoError(t, err)
  1182  	})
  1183  
  1184  	t.Run("key deleted", func(t *testing.T) {
  1185  		err := kb.Delete(appName)
  1186  		require.NoError(t, err)
  1187  
  1188  		t.Run("key is gone", func(t *testing.T) {
  1189  			_, err := kb.Key(appName)
  1190  			require.Error(t, err)
  1191  		})
  1192  	})
  1193  }
  1194  
  1195  func TestInMemoryCreateMultisig(t *testing.T) {
  1196  	cdc := getCodec()
  1197  	kb, err := New("keybasename", "memory", "", nil, cdc)
  1198  	require.NoError(t, err)
  1199  	multi := multisig.NewLegacyAminoPubKey(
  1200  		1, []types.PubKey{
  1201  			secp256k1.GenPrivKey().PubKey(),
  1202  		},
  1203  	)
  1204  	_, err = kb.SaveMultisig("multi", multi)
  1205  	require.NoError(t, err)
  1206  }
  1207  
  1208  // TestInMemorySignVerify does some detailed checks on how we sign and validate
  1209  // signatures
  1210  func TestInMemorySignVerify(t *testing.T) {
  1211  	cdc := getCodec()
  1212  	cstore := NewInMemory(cdc)
  1213  	algo := hd.Secp256k1
  1214  
  1215  	n1, n2, n3 := "some dude", "a dudette", "dude-ish"
  1216  
  1217  	// create two users and get their info
  1218  	kr1, _, err := cstore.NewMnemonic(n1, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, algo)
  1219  	require.Nil(t, err)
  1220  
  1221  	kr2, _, err := cstore.NewMnemonic(n2, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, algo)
  1222  	require.Nil(t, err)
  1223  
  1224  	// let's try to sign some messages
  1225  	d1 := []byte("my first message")
  1226  	d2 := []byte("some other important info!")
  1227  	d3 := []byte("feels like I forgot something...")
  1228  
  1229  	// try signing both data with both ..
  1230  	s11, pub1, err := cstore.Sign(n1, d1, signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON)
  1231  	require.Nil(t, err)
  1232  	key1, err := kr1.GetPubKey()
  1233  	require.NoError(t, err)
  1234  	require.Equal(t, key1, pub1)
  1235  
  1236  	s12, pub1, err := cstore.Sign(n1, d2, signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON)
  1237  	require.Nil(t, err)
  1238  	require.Equal(t, key1, pub1)
  1239  
  1240  	s21, pub2, err := cstore.Sign(n2, d1, signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON)
  1241  	require.Nil(t, err)
  1242  	key2, err := kr2.GetPubKey()
  1243  	require.NoError(t, err)
  1244  	require.Equal(t, key2, pub2)
  1245  
  1246  	s22, pub2, err := cstore.Sign(n2, d2, signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON)
  1247  	require.Nil(t, err)
  1248  	require.Equal(t, key2, pub2)
  1249  
  1250  	// let's try to validate and make sure it only works when everything is proper
  1251  	cases := []struct {
  1252  		key   types.PubKey
  1253  		data  []byte
  1254  		sig   []byte
  1255  		valid bool
  1256  	}{
  1257  		// proper matches
  1258  		{key1, d1, s11, true},
  1259  		// change data, pubkey, or signature leads to fail
  1260  		{key1, d2, s11, false},
  1261  		{key2, d1, s11, false},
  1262  		{key1, d1, s21, false},
  1263  		// make sure other successes
  1264  		{key1, d2, s12, true},
  1265  		{key2, d1, s21, true},
  1266  		{key2, d2, s22, true},
  1267  	}
  1268  
  1269  	for i, tc := range cases {
  1270  		valid := tc.key.VerifySignature(tc.data, tc.sig)
  1271  		require.Equal(t, tc.valid, valid, "%d", i)
  1272  	}
  1273  
  1274  	// Import a public key
  1275  	armor, err := cstore.ExportPubKeyArmor(n2)
  1276  	require.Nil(t, err)
  1277  	err = cstore.Delete(n2)
  1278  	require.NoError(t, err)
  1279  	err = cstore.ImportPubKey(n3, armor)
  1280  	require.NoError(t, err)
  1281  	i3, err := cstore.Key(n3)
  1282  	require.NoError(t, err)
  1283  	require.Equal(t, i3.Name, n3)
  1284  
  1285  	// Now try to sign data with a secret-less key
  1286  	_, _, err = cstore.Sign(n3, d3, signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON)
  1287  	require.Error(t, err)
  1288  	require.Equal(t, "cannot sign with offline keys", err.Error())
  1289  }
  1290  
  1291  // TestInMemorySeedPhrase verifies restoring from a seed phrase
  1292  func TestInMemorySeedPhrase(t *testing.T) {
  1293  	// make the storage with reasonable defaults
  1294  	cdc := getCodec()
  1295  	tests := []struct {
  1296  		name      string
  1297  		uid       string
  1298  		importUID string
  1299  	}{
  1300  		{
  1301  			name:      "correct in memory seed",
  1302  			uid:       "okTest",
  1303  			importUID: "imported",
  1304  		},
  1305  	}
  1306  	for _, tt := range tests {
  1307  		t.Run(tt.name, func(t *testing.T) {
  1308  			cstore := NewInMemory(cdc)
  1309  
  1310  			// make sure key works with initial password
  1311  			k, mnemonic, err := cstore.NewMnemonic(tt.uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
  1312  			require.Nil(t, err, "%+v", err)
  1313  			require.Equal(t, tt.uid, k.Name)
  1314  			require.NotEmpty(t, mnemonic)
  1315  
  1316  			// now, let us delete this key
  1317  			err = cstore.Delete(tt.uid)
  1318  			require.Nil(t, err, "%+v", err)
  1319  			_, err = cstore.Key(tt.uid)
  1320  			require.NotNil(t, err)
  1321  
  1322  			// let us re-create it from the mnemonic-phrase
  1323  			hdPath := hd.NewFundraiserParams(0, sdk.CoinType, 0).String()
  1324  			k1, err := cstore.NewAccount(tt.importUID, mnemonic, DefaultBIP39Passphrase, hdPath, hd.Secp256k1)
  1325  			require.NoError(t, err)
  1326  			require.Equal(t, tt.importUID, k1.Name)
  1327  			key, err := k.GetPubKey()
  1328  			require.NoError(t, err)
  1329  			key1, err := k1.GetPubKey()
  1330  			require.NoError(t, err)
  1331  			require.Equal(t, key.Address(), key1.Address())
  1332  			require.Equal(t, key, key1)
  1333  		})
  1334  	}
  1335  }
  1336  
  1337  func TestKeyChain_ShouldFailWhenAddingSameGeneratedAccount(t *testing.T) {
  1338  	cdc := getCodec()
  1339  	kr, err := New(t.Name(), BackendTest, t.TempDir(), nil, cdc)
  1340  	require.NoError(t, err)
  1341  
  1342  	// Given we create a mnemonic
  1343  	_, seed, err := kr.NewMnemonic("test", English, "", DefaultBIP39Passphrase, hd.Secp256k1)
  1344  	require.NoError(t, err)
  1345  
  1346  	require.NoError(t, kr.Delete("test"))
  1347  
  1348  	path := hd.CreateHDPath(118, 0, 0).String()
  1349  	_, err = kr.NewAccount("test1", seed, "", path, hd.Secp256k1)
  1350  	require.NoError(t, err)
  1351  
  1352  	// Creating another account with different uid but same seed should fail due to have same pub address
  1353  	_, err = kr.NewAccount("test2", seed, "", path, hd.Secp256k1)
  1354  	require.Error(t, err)
  1355  }
  1356  
  1357  func ExampleNew() {
  1358  	// Select the encryption and storage for your cryptostore
  1359  	cdc := getCodec()
  1360  	cstore := NewInMemory(cdc)
  1361  
  1362  	sec := hd.Secp256k1
  1363  
  1364  	// Add keys and see they return in alphabetical order
  1365  	bob, _, err := cstore.NewMnemonic("Bob", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, sec)
  1366  	if err != nil {
  1367  		// this should never happen
  1368  		fmt.Println(err)
  1369  	} else {
  1370  		// return info here just like in List
  1371  		fmt.Println(bob.Name)
  1372  	}
  1373  	_, _, _ = cstore.NewMnemonic("Alice", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, sec)
  1374  	_, _, _ = cstore.NewMnemonic("Carl", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, sec)
  1375  	records, _ := cstore.List()
  1376  	for _, k := range records {
  1377  		fmt.Println(k.Name)
  1378  	}
  1379  
  1380  	// We need to use passphrase to generate a signature
  1381  	tx := []byte("deadbeef")
  1382  	sig, pub, err := cstore.Sign("Bob", tx, signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON)
  1383  	if err != nil {
  1384  		fmt.Println("don't accept real passphrase")
  1385  	}
  1386  
  1387  	// and we can validate the signature with publicly available info
  1388  	bRecord, _ := cstore.Key("Bob")
  1389  	key, _ := bRecord.GetPubKey()
  1390  	bobKey, _ := bob.GetPubKey()
  1391  	if !key.Equals(bobKey) {
  1392  		fmt.Println("Get and Create return different keys")
  1393  	}
  1394  
  1395  	if pub.Equals(key) {
  1396  		fmt.Println("signed by Bob")
  1397  	}
  1398  	if !pub.VerifySignature(tx, sig) {
  1399  		fmt.Println("invalid signature")
  1400  	}
  1401  
  1402  	// Output:
  1403  	// Bob
  1404  	// Alice
  1405  	// Bob
  1406  	// Carl
  1407  	// signed by Bob
  1408  }
  1409  
  1410  func TestAltKeyring_List(t *testing.T) {
  1411  	cdc := getCodec()
  1412  	tests := []struct {
  1413  		name    string
  1414  		backend string
  1415  		uids    []string
  1416  	}{
  1417  		{
  1418  			name:    "correct list",
  1419  			backend: BackendTest,
  1420  			uids:    []string{"Bkey", "Rkey", "Zkey"},
  1421  		},
  1422  		{
  1423  			name:    "empty list",
  1424  			backend: BackendTest,
  1425  			uids:    nil,
  1426  		},
  1427  	}
  1428  	for _, tt := range tests {
  1429  		t.Run(tt.name, func(t *testing.T) {
  1430  			kr, err := New("listKeys", tt.backend, t.TempDir(), nil, cdc)
  1431  			require.NoError(t, err)
  1432  
  1433  			list, err := kr.List()
  1434  			require.NoError(t, err)
  1435  			require.Empty(t, list)
  1436  
  1437  			for _, uid := range tt.uids {
  1438  				_, _, err = kr.NewMnemonic(uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
  1439  				require.NoError(t, err)
  1440  			}
  1441  			list, err = kr.List()
  1442  			require.NoError(t, err)
  1443  			require.Len(t, list, len(tt.uids))
  1444  
  1445  			for i := range tt.uids {
  1446  				require.Equal(t, tt.uids[i], list[i].Name)
  1447  			}
  1448  		})
  1449  	}
  1450  }
  1451  
  1452  func TestAltKeyring_Get(t *testing.T) {
  1453  	cdc := getCodec()
  1454  	tests := []struct {
  1455  		name        string
  1456  		backend     string
  1457  		uid         string
  1458  		uidToFind   string
  1459  		expectedErr error
  1460  	}{
  1461  		{
  1462  			name:        "correct get",
  1463  			backend:     BackendTest,
  1464  			uid:         "okTest",
  1465  			uidToFind:   "okTest",
  1466  			expectedErr: nil,
  1467  		},
  1468  		{
  1469  			name:        "not found key",
  1470  			backend:     BackendTest,
  1471  			uid:         "notFoundUid",
  1472  			uidToFind:   "notFound",
  1473  			expectedErr: sdkerrors.ErrKeyNotFound,
  1474  		},
  1475  		{
  1476  			name:        "in memory correct get",
  1477  			backend:     BackendMemory,
  1478  			uid:         "okTest",
  1479  			uidToFind:   "okTest",
  1480  			expectedErr: nil,
  1481  		},
  1482  		{
  1483  			name:        "in memory not found key",
  1484  			backend:     BackendMemory,
  1485  			uid:         "notFoundUid",
  1486  			uidToFind:   "notFound",
  1487  			expectedErr: sdkerrors.ErrKeyNotFound,
  1488  		},
  1489  	}
  1490  	for _, tt := range tests {
  1491  		t.Run(tt.name, func(t *testing.T) {
  1492  			kr, err := New(tt.name, tt.backend, t.TempDir(), nil, cdc)
  1493  			require.NoError(t, err)
  1494  
  1495  			mnemonic, _, err := kr.NewMnemonic(tt.uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
  1496  			require.NoError(t, err)
  1497  
  1498  			key, err := kr.Key(tt.uidToFind)
  1499  			if tt.expectedErr == nil {
  1500  				require.NoError(t, err)
  1501  				requireEqualRenamedKey(t, mnemonic, key, true)
  1502  			} else {
  1503  				require.Error(t, err)
  1504  				require.True(t, errors.Is(err, tt.expectedErr))
  1505  			}
  1506  		})
  1507  	}
  1508  }
  1509  
  1510  func TestAltKeyring_KeyByAddress(t *testing.T) {
  1511  	cdc := getCodec()
  1512  	tests := []struct {
  1513  		name        string
  1514  		backend     string
  1515  		uid         string
  1516  		getAddres   func(*Record) (sdk.AccAddress, error)
  1517  		expectedErr error
  1518  	}{
  1519  		{
  1520  			name:    "correct get",
  1521  			backend: BackendTest,
  1522  			uid:     "okTest",
  1523  			getAddres: func(k *Record) (sdk.AccAddress, error) {
  1524  				return k.GetAddress()
  1525  			},
  1526  			expectedErr: nil,
  1527  		},
  1528  		{
  1529  			name:    "not found key",
  1530  			backend: BackendTest,
  1531  			uid:     "notFoundUid",
  1532  			getAddres: func(k *Record) (sdk.AccAddress, error) {
  1533  				return nil, nil
  1534  			},
  1535  			expectedErr: sdkerrors.ErrKeyNotFound,
  1536  		},
  1537  	}
  1538  	for _, tt := range tests {
  1539  		t.Run(tt.name, func(t *testing.T) {
  1540  			kr, err := New(tt.name, tt.backend, t.TempDir(), nil, cdc)
  1541  			require.NoError(t, err)
  1542  
  1543  			mnemonic, _, err := kr.NewMnemonic(tt.uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
  1544  			require.NoError(t, err)
  1545  			addr, err := tt.getAddres(mnemonic)
  1546  			require.NoError(t, err)
  1547  
  1548  			key, err := kr.KeyByAddress(addr)
  1549  			if tt.expectedErr == nil {
  1550  				require.NoError(t, err)
  1551  				requireEqualRenamedKey(t, mnemonic, key, true)
  1552  			} else {
  1553  				require.Error(t, err)
  1554  				require.True(t, errors.Is(err, tt.expectedErr))
  1555  			}
  1556  		})
  1557  	}
  1558  }
  1559  
  1560  func TestAltKeyring_Delete(t *testing.T) {
  1561  	cdc := getCodec()
  1562  	tests := []struct {
  1563  		name        string
  1564  		backend     string
  1565  		uid         string
  1566  		uidToDelete string
  1567  		expectedErr error
  1568  	}{
  1569  		{
  1570  			name:        "correct delete",
  1571  			backend:     BackendTest,
  1572  			uid:         "deleteKey",
  1573  			uidToDelete: "deleteKey",
  1574  			expectedErr: nil,
  1575  		},
  1576  		{
  1577  			name:        "not found delete",
  1578  			backend:     BackendTest,
  1579  			uid:         "deleteKey",
  1580  			uidToDelete: "notFound",
  1581  			expectedErr: sdkerrors.ErrKeyNotFound,
  1582  		},
  1583  		{
  1584  			name:        "in memory correct delete",
  1585  			backend:     BackendMemory,
  1586  			uid:         "inMemoryDeleteKey",
  1587  			uidToDelete: "inMemoryDeleteKey",
  1588  			expectedErr: nil,
  1589  		},
  1590  		{
  1591  			name:        "in memory not found delete",
  1592  			backend:     BackendMemory,
  1593  			uid:         "inMemoryDeleteKey",
  1594  			uidToDelete: "notFound",
  1595  			expectedErr: sdkerrors.ErrKeyNotFound,
  1596  		},
  1597  	}
  1598  	for _, tt := range tests {
  1599  		t.Run(tt.name, func(t *testing.T) {
  1600  			kr, err := New(t.Name(), tt.backend, t.TempDir(), nil, cdc)
  1601  			require.NoError(t, err)
  1602  
  1603  			_, _, err = kr.NewMnemonic(tt.uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
  1604  			require.NoError(t, err)
  1605  
  1606  			list, err := kr.List()
  1607  			require.NoError(t, err)
  1608  			require.Len(t, list, 1)
  1609  
  1610  			err = kr.Delete(tt.uidToDelete)
  1611  			list, listErr := kr.List()
  1612  			require.NoError(t, listErr)
  1613  			if tt.expectedErr == nil {
  1614  				require.NoError(t, err)
  1615  				require.Empty(t, list)
  1616  			} else {
  1617  				require.Error(t, err)
  1618  				require.True(t, errors.Is(err, tt.expectedErr))
  1619  				require.Len(t, list, 1)
  1620  			}
  1621  		})
  1622  	}
  1623  }
  1624  
  1625  func TestAltKeyring_DeleteByAddress(t *testing.T) {
  1626  	cdc := getCodec()
  1627  	tests := []struct {
  1628  		name        string
  1629  		backend     string
  1630  		uid         string
  1631  		getAddres   func(*Record) (sdk.AccAddress, error)
  1632  		expectedErr error
  1633  	}{
  1634  		{
  1635  			name:    "correct delete",
  1636  			backend: BackendTest,
  1637  			uid:     "okTest",
  1638  			getAddres: func(k *Record) (sdk.AccAddress, error) {
  1639  				return k.GetAddress()
  1640  			},
  1641  			expectedErr: nil,
  1642  		},
  1643  		{
  1644  			name:    "not found",
  1645  			backend: BackendTest,
  1646  			uid:     "notFoundUid",
  1647  			getAddres: func(k *Record) (sdk.AccAddress, error) {
  1648  				return nil, nil
  1649  			},
  1650  			expectedErr: sdkerrors.ErrKeyNotFound,
  1651  		},
  1652  		{
  1653  			name:    "in memory correct delete",
  1654  			backend: BackendMemory,
  1655  			uid:     "inMemory",
  1656  			getAddres: func(k *Record) (sdk.AccAddress, error) {
  1657  				return k.GetAddress()
  1658  			},
  1659  			expectedErr: nil,
  1660  		},
  1661  		{
  1662  			name:    "in memory not found",
  1663  			backend: BackendMemory,
  1664  			uid:     "inMemoryNotFoundUid",
  1665  			getAddres: func(k *Record) (sdk.AccAddress, error) {
  1666  				return nil, nil
  1667  			},
  1668  			expectedErr: sdkerrors.ErrKeyNotFound,
  1669  		},
  1670  	}
  1671  	for _, tt := range tests {
  1672  		t.Run(tt.name, func(t *testing.T) {
  1673  			kr, err := New(tt.name, tt.backend, t.TempDir(), nil, cdc)
  1674  			require.NoError(t, err)
  1675  
  1676  			mnemonic, _, err := kr.NewMnemonic(tt.uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
  1677  			require.NoError(t, err)
  1678  			addr, err := tt.getAddres(mnemonic)
  1679  			require.NoError(t, err)
  1680  
  1681  			err = kr.DeleteByAddress(addr)
  1682  			list, listErr := kr.List()
  1683  			require.NoError(t, listErr)
  1684  			if tt.expectedErr == nil {
  1685  				require.NoError(t, err)
  1686  				require.Empty(t, list)
  1687  			} else {
  1688  				require.Error(t, err)
  1689  				require.True(t, errors.Is(err, tt.expectedErr))
  1690  				require.Len(t, list, 1)
  1691  			}
  1692  		})
  1693  	}
  1694  }
  1695  
  1696  // TODO: review
  1697  func TestAltKeyring_SaveOfflineKey(t *testing.T) {
  1698  	cdc := getCodec()
  1699  	tests := []struct {
  1700  		name    string
  1701  		backend string
  1702  		uid     string
  1703  		pubKey  string
  1704  	}{
  1705  		{
  1706  			name:    "correct save",
  1707  			backend: BackendTest,
  1708  			uid:     "okSave",
  1709  			pubKey:  "cfd96f5e00069b64ddb8bfa433941400ab674db42436ae08bc9c74f3b5ade896",
  1710  		},
  1711  		{
  1712  			name:    "in memory correct save",
  1713  			backend: BackendMemory,
  1714  			uid:     "memorySave",
  1715  			pubKey:  "cfd96f5e00069b64ddb8bfa433941400ab674db42436ae08bc9c74f3b5ade896",
  1716  		},
  1717  	}
  1718  	for _, tt := range tests {
  1719  		t.Run(tt.name, func(t *testing.T) {
  1720  			kr, err := New(tt.name, tt.backend, t.TempDir(), nil, cdc)
  1721  			require.NoError(t, err)
  1722  			priv := ed25519.GenPrivKey()
  1723  			pub := priv.PubKey()
  1724  			pub.Bytes()
  1725  			k, err := kr.SaveOfflineKey(tt.uid, pub)
  1726  			require.NoError(t, err)
  1727  			pubKey, err := k.GetPubKey()
  1728  			require.NoError(t, err)
  1729  			require.Equal(t, pub, pubKey)
  1730  			require.Equal(t, tt.uid, k.Name)
  1731  
  1732  			list, err := kr.List()
  1733  			require.NoError(t, err)
  1734  			require.Len(t, list, 1)
  1735  		})
  1736  	}
  1737  }
  1738  
  1739  func TestNonConsistentKeyring_SavePubKey(t *testing.T) {
  1740  	cdc := getCodec()
  1741  	kr, err := New(t.Name(), BackendTest, t.TempDir(), nil, cdc)
  1742  	require.NoError(t, err)
  1743  
  1744  	list, err := kr.List()
  1745  	require.NoError(t, err)
  1746  	require.Empty(t, list)
  1747  
  1748  	key := someKey
  1749  	priv := ed25519.GenPrivKey()
  1750  	pub := priv.PubKey()
  1751  
  1752  	_, err = kr.SaveOfflineKey(key, pub)
  1753  	require.NoError(t, err)
  1754  
  1755  	// broken keyring state test
  1756  	unsafeKr, ok := kr.(keystore)
  1757  	require.True(t, ok)
  1758  	// we lost public key for some reason, but still have an address record
  1759  	require.NoError(t, unsafeKr.db.Remove(infoKey(key)))
  1760  	list, err = kr.List()
  1761  	require.NoError(t, err)
  1762  	require.Equal(t, 0, len(list))
  1763  
  1764  	k, err := kr.SaveOfflineKey(key, pub)
  1765  	require.Nil(t, err)
  1766  	pubKey, err := k.GetPubKey()
  1767  	require.NoError(t, err)
  1768  	require.Equal(t, pub, pubKey)
  1769  	require.Equal(t, key, k.Name)
  1770  
  1771  	list, err = kr.List()
  1772  	require.NoError(t, err)
  1773  	require.Equal(t, 1, len(list))
  1774  }
  1775  
  1776  func TestAltKeyring_SaveMultisig(t *testing.T) {
  1777  	cdc := getCodec()
  1778  	tests := []struct {
  1779  		name      string
  1780  		uid       string
  1781  		backend   string
  1782  		mnemonics []string
  1783  	}{
  1784  		{
  1785  			name:    "correct multisig",
  1786  			uid:     "multi",
  1787  			backend: BackendTest,
  1788  			mnemonics: []string{
  1789  				"faint misery damage shoot wedding chat dress joy page stand gun business dance amount amused pond smart rate inner ill loud agree two evil",
  1790  				"window surprise chief blame huge umbrella pool home draw staff water brief modify depth whisper hawk floor come fury property pond cluster ethics super",
  1791  			},
  1792  		},
  1793  		{
  1794  			name:    "correct in memory multisig",
  1795  			uid:     "multiInMemory",
  1796  			backend: BackendMemory,
  1797  			mnemonics: []string{
  1798  				"faint misery damage shoot wedding chat dress joy page stand gun business dance amount amused pond smart rate inner ill loud agree two evil",
  1799  				"window surprise chief blame huge umbrella pool home draw staff water brief modify depth whisper hawk floor come fury property pond cluster ethics super",
  1800  			},
  1801  		},
  1802  		{
  1803  			name:      "one key multisig",
  1804  			uid:       "multi",
  1805  			backend:   BackendTest,
  1806  			mnemonics: []string{"faint misery damage shoot wedding chat dress joy page stand gun business dance amount amused pond smart rate inner ill loud agree two evil"},
  1807  		},
  1808  	}
  1809  	for _, tt := range tests {
  1810  		t.Run(tt.name, func(t *testing.T) {
  1811  			kr, err := New(t.Name(), tt.backend, t.TempDir(), nil, cdc)
  1812  			require.NoError(t, err)
  1813  			pubKeys := make([]types.PubKey, len(tt.mnemonics))
  1814  			for i, mnemonic := range tt.mnemonics {
  1815  				r, err := kr.NewAccount(strconv.FormatInt(int64(i), 10), mnemonic, DefaultBIP39Passphrase, sdk.FullFundraiserPath, hd.Secp256k1)
  1816  				require.NoError(t, err)
  1817  				key, err := r.GetPubKey()
  1818  				require.NoError(t, err)
  1819  				pubKeys[i] = key
  1820  			}
  1821  			pub := multisig.NewLegacyAminoPubKey(len(tt.mnemonics), pubKeys)
  1822  			k, err := kr.SaveMultisig(tt.uid, pub)
  1823  			require.Nil(t, err)
  1824  			infoKey, err := k.GetPubKey()
  1825  			require.NoError(t, err)
  1826  			require.Equal(t, pub, infoKey)
  1827  			require.Equal(t, tt.uid, k.Name)
  1828  
  1829  			list, err := kr.List()
  1830  			require.NoError(t, err)
  1831  			require.Len(t, list, len(tt.mnemonics)+1)
  1832  		})
  1833  	}
  1834  }
  1835  
  1836  // TODO: add more tests
  1837  func TestAltKeyring_Sign(t *testing.T) {
  1838  	cdc := getCodec()
  1839  	tests := []struct {
  1840  		name    string
  1841  		backend string
  1842  		uid     string
  1843  		msg     []byte
  1844  		mode    signing.SignMode
  1845  	}{
  1846  		{
  1847  			name:    "correct sign",
  1848  			backend: BackendTest,
  1849  			uid:     "signKey",
  1850  			msg:     []byte("some message"),
  1851  			mode:    signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
  1852  		},
  1853  	}
  1854  	for _, tt := range tests {
  1855  		t.Run(tt.name, func(t *testing.T) {
  1856  			kr, err := New(t.Name(), tt.backend, t.TempDir(), nil, cdc)
  1857  			require.NoError(t, err)
  1858  
  1859  			_, _, err = kr.NewMnemonic(tt.uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
  1860  			require.NoError(t, err)
  1861  
  1862  			sign, key, err := kr.Sign(tt.uid, tt.msg, tt.mode)
  1863  			require.NoError(t, err)
  1864  
  1865  			require.True(t, key.VerifySignature(tt.msg, sign))
  1866  		})
  1867  	}
  1868  }
  1869  
  1870  func TestAltKeyring_SignByAddress(t *testing.T) {
  1871  	cdc := getCodec()
  1872  	tests := []struct {
  1873  		name    string
  1874  		backend string
  1875  		uid     string
  1876  		msg     []byte
  1877  		mode    signing.SignMode
  1878  	}{
  1879  		{
  1880  			name:    "correct sign by address",
  1881  			backend: BackendTest,
  1882  			uid:     "signKey",
  1883  			msg:     []byte("some message"),
  1884  			mode:    signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
  1885  		},
  1886  	}
  1887  	for _, tt := range tests {
  1888  		t.Run(tt.name, func(t *testing.T) {
  1889  			kr, err := New(t.Name(), tt.backend, t.TempDir(), nil, cdc)
  1890  			require.NoError(t, err)
  1891  
  1892  			mnemonic, _, err := kr.NewMnemonic(tt.uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
  1893  			require.NoError(t, err)
  1894  
  1895  			addr, err := mnemonic.GetAddress()
  1896  			require.NoError(t, err)
  1897  			sign, key, err := kr.SignByAddress(addr, tt.msg, tt.mode)
  1898  			require.NoError(t, err)
  1899  
  1900  			require.True(t, key.VerifySignature(tt.msg, sign))
  1901  		})
  1902  	}
  1903  }
  1904  
  1905  func TestAltKeyring_ConstructorSupportedAlgos(t *testing.T) {
  1906  	cdc := getCodec()
  1907  	tests := []struct {
  1908  		name        string
  1909  		algoOptions func(options *Options)
  1910  		expectedErr error
  1911  	}{
  1912  		{
  1913  			name: "add new algo",
  1914  			algoOptions: func(options *Options) {
  1915  				options.SupportedAlgos = SigningAlgoList{
  1916  					notSupportedAlgo{},
  1917  				}
  1918  			},
  1919  			expectedErr: nil,
  1920  		},
  1921  		{
  1922  			name:        "not supported algo",
  1923  			algoOptions: func(options *Options) {},
  1924  			expectedErr: ErrUnsupportedSigningAlgo,
  1925  		},
  1926  	}
  1927  	for _, tt := range tests {
  1928  		t.Run(tt.name, func(t *testing.T) {
  1929  			kr, err := New(t.Name(), BackendTest, t.TempDir(), nil, cdc, tt.algoOptions)
  1930  			require.NoError(t, err)
  1931  			_, _, err = kr.NewMnemonic("test", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, notSupportedAlgo{})
  1932  			if tt.expectedErr == nil {
  1933  				require.NoError(t, err)
  1934  			} else {
  1935  				require.Error(t, err)
  1936  				require.True(t, errors.Is(err, tt.expectedErr))
  1937  			}
  1938  		})
  1939  	}
  1940  }
  1941  
  1942  // TODO: review it
  1943  func TestBackendConfigConstructors(t *testing.T) {
  1944  	backend := newKWalletBackendKeyringConfig("test", "", nil)
  1945  	require.Equal(t, []keyring.BackendType{keyring.KWalletBackend}, backend.AllowedBackends)
  1946  	require.Equal(t, "kdewallet", backend.ServiceName)
  1947  	require.Equal(t, "test", backend.KWalletAppID)
  1948  
  1949  	backend = newPassBackendKeyringConfig("test", "directory", nil)
  1950  	require.Equal(t, []keyring.BackendType{keyring.PassBackend}, backend.AllowedBackends)
  1951  	require.Equal(t, "test", backend.ServiceName)
  1952  	require.Equal(t, "keyring-test", backend.PassPrefix)
  1953  }
  1954  
  1955  func TestRenameKey(t *testing.T) {
  1956  	testCases := []struct {
  1957  		name string
  1958  		run  func(Keyring)
  1959  	}{
  1960  		{
  1961  			name: "rename a key",
  1962  			run: func(kr Keyring) {
  1963  				oldKeyUID, newKeyUID := "old", "new"
  1964  				oldKeyRecord := newKeyRecord(t, kr, oldKeyUID)
  1965  				err := kr.Rename(oldKeyUID, newKeyUID) // rename from "old" to "new"
  1966  				require.NoError(t, err)
  1967  				newRecord, err := kr.Key(newKeyUID) // new key should be in keyring
  1968  				require.NoError(t, err)
  1969  				requireEqualRenamedKey(t, newRecord, oldKeyRecord, false) // oldKeyRecord and newRecord should be the same except name
  1970  				_, err = kr.Key(oldKeyUID)                                // old key should be gone from keyring
  1971  				require.Error(t, err)
  1972  			},
  1973  		},
  1974  		{
  1975  			name: "cant rename a key that doesnt exist",
  1976  			run: func(kr Keyring) {
  1977  				err := kr.Rename("bogus", "bogus2")
  1978  				require.Error(t, err)
  1979  			},
  1980  		},
  1981  		{
  1982  			name: "cant rename a key to an already existing key name",
  1983  			run: func(kr Keyring) {
  1984  				key1, key2 := "existingKey", "existingKey2" // create 2 keys
  1985  				newKeyRecord(t, kr, key1)
  1986  				newKeyRecord(t, kr, key2)
  1987  				err := kr.Rename(key2, key1)
  1988  				require.True(t, errors.Is(err, ErrKeyAlreadyExists))
  1989  				assertKeysExist(t, kr, key1, key2) // keys should still exist after failed rename
  1990  			},
  1991  		},
  1992  		{
  1993  			name: "cant rename key to itself",
  1994  			run: func(kr Keyring) {
  1995  				keyName := "keyName"
  1996  				newKeyRecord(t, kr, keyName)
  1997  				err := kr.Rename(keyName, keyName)
  1998  				require.True(t, errors.Is(err, ErrKeyAlreadyExists))
  1999  				assertKeysExist(t, kr, keyName)
  2000  			},
  2001  		},
  2002  	}
  2003  
  2004  	for _, tc := range testCases {
  2005  		tc := tc
  2006  		kr := newKeyring(t, "testKeyring")
  2007  		t.Run(tc.name, func(t *testing.T) {
  2008  			tc.run(kr)
  2009  		})
  2010  	}
  2011  }
  2012  
  2013  // TestChangeBcrypt tests the compatibility from upstream Bcrypt and our own
  2014  func TestChangeBcrypt(t *testing.T) {
  2015  	pw := []byte("somepasswword!")
  2016  
  2017  	saltBytes := cmtcrypto.CRandBytes(16)
  2018  	cosmosHash, err := cosmosbcrypt.GenerateFromPassword(saltBytes, pw, 2)
  2019  	require.NoError(t, err)
  2020  
  2021  	bcryptHash, err := bcrypt.GenerateFromPassword(pw, 2)
  2022  	require.NoError(t, err)
  2023  
  2024  	// Check the new hash with the old bcrypt, vice-versa and with the same
  2025  	// bcrypt version just because.
  2026  	err = cosmosbcrypt.CompareHashAndPassword(bcryptHash, pw)
  2027  	require.NoError(t, err)
  2028  
  2029  	err = cosmosbcrypt.CompareHashAndPassword(cosmosHash, pw)
  2030  	require.NoError(t, err)
  2031  
  2032  	err = bcrypt.CompareHashAndPassword(cosmosHash, pw)
  2033  	require.NoError(t, err)
  2034  
  2035  	err = bcrypt.CompareHashAndPassword(bcryptHash, pw)
  2036  	require.NoError(t, err)
  2037  }
  2038  
  2039  func requireEqualRenamedKey(t *testing.T, key, mnemonic *Record, nameMatch bool) {
  2040  	if nameMatch {
  2041  		require.Equal(t, key.Name, mnemonic.Name)
  2042  	}
  2043  	keyAddr, err := key.GetAddress()
  2044  	require.NoError(t, err)
  2045  	mnemonicAddr, err := mnemonic.GetAddress()
  2046  	require.NoError(t, err)
  2047  	require.Equal(t, keyAddr, mnemonicAddr)
  2048  
  2049  	key1, err := key.GetPubKey()
  2050  	require.NoError(t, err)
  2051  	key2, err := mnemonic.GetPubKey()
  2052  	require.NoError(t, err)
  2053  	require.Equal(t, key1, key2)
  2054  	require.Equal(t, key.GetType(), mnemonic.GetType())
  2055  }
  2056  
  2057  func newKeyring(t *testing.T, name string) Keyring {
  2058  	cdc := getCodec()
  2059  	kr, err := New(name, "test", t.TempDir(), nil, cdc)
  2060  	require.NoError(t, err)
  2061  	return kr
  2062  }
  2063  
  2064  func newKeyRecord(t *testing.T, kr Keyring, name string) *Record {
  2065  	k, _, err := kr.NewMnemonic(name, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
  2066  	require.NoError(t, err)
  2067  	return k
  2068  }
  2069  
  2070  func assertKeysExist(t *testing.T, kr Keyring, names ...string) {
  2071  	for _, n := range names {
  2072  		_, err := kr.Key(n)
  2073  		require.NoError(t, err)
  2074  	}
  2075  }
  2076  
  2077  func accAddr(k *Record) (sdk.AccAddress, error) { return k.GetAddress() }