-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #235 from InjectiveLabs/f/new-cosmos-keyring
feat: new cosmos keyring helper for injective client
- Loading branch information
Showing
15 changed files
with
1,319 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
# Injective Chain Keyring Helper | ||
|
||
Creates a new keyring from a variety of options. See `ConfigOpt` and related options. This keyring helper allows initializing the Cosmos SDK keyring used for signing transactions. | ||
|
||
It allows flexibly defining a static configuration of keys, supports multiple pre-defined keys in the same keyring, and allows loading keys from a file, deriving from mnemonic, or reading plain private key bytes from a HEX string. Extremely useful for testing and local development, but also robust for production use cases. | ||
|
||
## Usage | ||
|
||
```go | ||
NewCosmosKeyring(cdc codec.Codec, opts ...ConfigOpt) (sdk.AccAddress, cosmkeyring.Keyring, error) | ||
``` | ||
|
||
**ConfigOpts:** | ||
|
||
These options are global on the keyring level. | ||
|
||
* `WithKeyringDir` option sets keyring path in the filesystem, useful when keyring backend is `file`. | ||
* `WithKeyringAppName` option sets keyring application name (defaults to `injectived`) | ||
* `WithKeyringBackend` sets the keyring backend. Expected values: `test`, `file`, `os`. | ||
* `WithUseLedger` sets the option to use hardware wallet, if available on the system. | ||
|
||
These options allow adding keys to the keyring during initialization. | ||
|
||
* `WithKey` adds a single key to the keyring, without having alias name. | ||
* `WithNamedKey` addes a single key to the keyring, with a name. | ||
* `WithDefaultKey` sets a default key reference to use for signing (by name). | ||
|
||
**KeyConfigOpts:** | ||
|
||
These options are set per key. | ||
|
||
* `WithKeyFrom` sets the key name to use for signing. Must exist in the provided keyring. | ||
* `WithKeyPassphrase` sets the passphrase for keyring files. The package will fallback to `os.Stdin` if this option was not provided, but passphrase is required. | ||
* `WithPrivKeyHex` allows specifying a private key as plain-text hex. Insecure option, use for testing only. The package will create a virtual keyring holding that key, to meet all the interfaces. | ||
* `WithMnemonic` allows specifying a mnemonic phrase as plain-text hex. Insecure option, use for testing only. The package will create a virtual keyring to derive the keys and meet all the interfaces. | ||
|
||
## Examples | ||
|
||
Initialize an in-memory keyring with a private key hex: | ||
|
||
```go | ||
NewCosmosKeyring( | ||
cdc, | ||
WithKey( | ||
WithPrivKeyHex("e6888cb164d52e4880e08a8a5dbe69cd62f67fde3d5906f2c5c951be553b2267"), | ||
WithKeyFrom("sender"), | ||
), | ||
) | ||
``` | ||
|
||
Initialize an in-memory keyring with a mnemonic phrase: | ||
|
||
```go | ||
NewCosmosKeyring( | ||
s.cdc, | ||
WithKey( | ||
WithMnemonic("real simple naive ....... love"), | ||
WithKeyFrom("sender"), | ||
), | ||
) | ||
``` | ||
|
||
Real world use case of keyring initialization from CLI flags, with a single named key set as default: | ||
|
||
```go | ||
NewCosmosKeyring( | ||
cdc, | ||
WithKeyringDir(*keyringDir), | ||
WithKeyringAppName(*keyringAppName), | ||
WithKeyringBackend(Backend(*keyringBackend)), | ||
WithNamedKey( | ||
"dispatcher", | ||
WithKeyFrom(*dispatcherKeyFrom), | ||
WithKeyPassphrase(*dispatcherKeyPassphrase), | ||
WithPrivKeyHex(*dispatcherKeyPrivateHex), | ||
WithMnemonic(*dispatcherKeyMnemonic), | ||
), | ||
WithDefaultKey( | ||
"dispatcher", | ||
), | ||
) | ||
``` | ||
|
||
## Testing | ||
|
||
```bash | ||
go test -v -cover | ||
|
||
PASS | ||
coverage: 83.1% of statements | ||
``` | ||
|
||
## Generating a Test Fixture | ||
|
||
```bash | ||
> cd testdata | ||
|
||
> injectived keys --keyring-dir `pwd` --keyring-backend file add test | ||
``` | ||
|
||
Passphrase should be `test12345678` for this fixture to work. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package keyring | ||
|
||
import "github.com/pkg/errors" | ||
|
||
var ( | ||
ErrCosmosKeyringCreationFailed = errors.New("cosmos keyring creation failed") | ||
ErrCosmosKeyringImportFailed = errors.New("cosmos keyring unable to import key") | ||
ErrDeriveFailed = errors.New("key derivation failed") | ||
ErrFailedToApplyConfigOption = errors.New("failed to apply config option") | ||
ErrFailedToApplyKeyConfigOption = errors.New("failed to apply a key config option") | ||
ErrFilepathIncorrect = errors.New("incorrect filepath") | ||
ErrHexFormatError = errors.New("hex format error") | ||
ErrIncompatibleOptionsProvided = errors.New("incompatible keyring options provided") | ||
ErrInsufficientKeyDetails = errors.New("insufficient cosmos key details provided") | ||
ErrKeyIncompatible = errors.New("provided key is incompatible with requested config") | ||
ErrKeyRecordNotFound = errors.New("key record not found") | ||
ErrPrivkeyConflict = errors.New("privkey conflict") | ||
ErrUnexpectedAddress = errors.New("unexpected address") | ||
ErrMultipleKeysWithDifferentSecurity = errors.New("key security is different: cannot mix keyring with privkeys") | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package keyring | ||
|
||
import ( | ||
bip39 "github.com/cosmos/go-bip39" | ||
"github.com/pkg/errors" | ||
) | ||
|
||
type cosmosKeyConfig struct { | ||
Name string | ||
KeyFrom string | ||
KeyPassphrase string | ||
PrivKeyHex string | ||
Mnemonic string | ||
} | ||
|
||
// KeyConfigOpt defines a known cosmos keyring key option. | ||
type KeyConfigOpt func(c *cosmosKeyConfig) error | ||
|
||
// WithKeyFrom sets the key name to use for signing. Must exist in the provided keyring. | ||
func WithKeyFrom(v string) KeyConfigOpt { | ||
return func(c *cosmosKeyConfig) error { | ||
if v != "" { | ||
c.KeyFrom = v | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
// WithKeyPassphrase sets the passphrase for keyring files. Insecure option, use for testing only. | ||
// The package will fallback to os.Stdin if this option was not provided, but pass is required. | ||
func WithKeyPassphrase(v string) KeyConfigOpt { | ||
return func(c *cosmosKeyConfig) error { | ||
if v != "" { | ||
c.KeyPassphrase = v | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
// WithPrivKeyHex allows to specify a private key as plaintext hex. Insecure option, use for testing only. | ||
// The package will create a virtual keyring holding that key, to meet all the interfaces. | ||
func WithPrivKeyHex(v string) KeyConfigOpt { | ||
return func(c *cosmosKeyConfig) error { | ||
if v != "" { | ||
c.PrivKeyHex = v | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
// WithMnemonic allows to specify a mnemonic pharse as plaintext. Insecure option, use for testing only. | ||
// The package will create a virtual keyring to derive the keys and meet all the interfaces. | ||
func WithMnemonic(v string) KeyConfigOpt { | ||
return func(c *cosmosKeyConfig) error { | ||
if v != "" { | ||
if !bip39.IsMnemonicValid(v) { | ||
err := errors.New("provided mnemonic is not a valid BIP39 mnemonic") | ||
return err | ||
} | ||
|
||
c.Mnemonic = v | ||
} | ||
|
||
return nil | ||
} | ||
} |
Oops, something went wrong.