Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mnemonic sentence support #975

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@ index-state:
packages:
cardano-cli

source-repository-package
type: git
location: https://github.com/intersectmbo/cardano-addresses.git
tag: b170724d92549a69fc3074b5f9b3f1871701aaab
subdir: core
--sha256: sha256-ldr7lEdME4XUjtgARPDBMMzeg3i2UojlW03ab3Pv0T0=

source-repository-package
type: git
location: https://github.com/intersectmbo/cardano-api.git
tag: 29ca290f33c8df3d54e68cd566a762fa4aad2693
subdir: cardano-api
--sha256: sha256-LuCEwN4nAiAfDelb7slBTkvfvUqQFQK0mMwaOF1kcHo=

program-options
ghc-options: -Werror

Expand Down
1 change: 1 addition & 0 deletions cardano-cli/cardano-cli.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ library
exceptions,
filepath,
formatting,
haskeline,
http-client,
http-client-tls,
http-types,
Expand Down
43 changes: 43 additions & 0 deletions cardano-cli/src/Cardano/CLI/Commands/Key.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ module Cardano.CLI.Commands.Key
( KeyCmds (..)
, KeyVerificationKeyCmdArgs (..)
, KeyNonExtendedKeyCmdArgs (..)
, KeyGenerateMnemonicCmdArgs (..)
, KeyExtendedSigningKeyFromMnemonicArgs (..)
, ExtendedSigningType (..)
, MnemonicSource (..)
, KeyConvertByronKeyCmdArgs (..)
, KeyConvertByronGenesisVKeyCmdArgs (..)
, KeyConvertITNKeyCmdArgs (..)
Expand All @@ -19,12 +23,15 @@ where
import Cardano.Api.Shelley

import Cardano.CLI.Types.Common
import Cardano.Prelude (Word32)

import Data.Text (Text)

data KeyCmds
= KeyVerificationKeyCmd !KeyVerificationKeyCmdArgs
| KeyNonExtendedKeyCmd !KeyNonExtendedKeyCmdArgs
| KeyGenerateMnemonicCmd !KeyGenerateMnemonicCmdArgs
| KeyExtendedSigningKeyFromMnemonicCmd !KeyExtendedSigningKeyFromMnemonicArgs
| KeyConvertByronKeyCmd !KeyConvertByronKeyCmdArgs
| KeyConvertByronGenesisVKeyCmd !KeyConvertByronGenesisVKeyCmdArgs
| KeyConvertITNKeyCmd !KeyConvertITNKeyCmdArgs
Expand Down Expand Up @@ -52,6 +59,38 @@ data KeyNonExtendedKeyCmdArgs = KeyNonExtendedKeyCmdArgs
}
deriving Show

-- | Generate a mnemonic phrase that can be used to derive signing keys.
data KeyGenerateMnemonicCmdArgs = KeyGenerateMnemonicCmdArgs
{ mnemonicOutputFormat :: !(Maybe (File () Out))
-- ^ Output format for the mnemonic phrase
, mnemonicWords :: !MnemonicSize
-- ^ Number of mnemonic words to generate it must be one of: 12, 15, 18, 21, or 24.
}
deriving Show

-- | Get a verification key from a mnemonic. This supports all extended key types.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

verification key?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch

data KeyExtendedSigningKeyFromMnemonicArgs = KeyExtendedSigningKeyFromMnemonicArgs
{ keyOutputFormat :: !KeyOutputFormat
, extendedSigningKeyType :: !ExtendedSigningType
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

derivedExtendedSigningKeyType?

, derivationAccountNo :: !Word32
, mnemonicSource :: !MnemonicSource
, signingKeyFileOut :: !(SigningKeyFile Out)
}
deriving Show

data MnemonicSource
= MnemonicFromFile !(File () In)
| MnemonicFromInteractivePrompt
deriving Show

data ExtendedSigningType
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DerivedExtendedSigningKeyType?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment saying something like "This is the key derived from the mnemonic"

= ExtendedSigningPaymentKey !Word32
| ExtendedSigningStakeKey !Word32
| ExtendedSigningDRepKey
| ExtendedSigningCCColdKey
| ExtendedSigningCCHotKey
deriving Show

-- | Convert a Byron payment, genesis or genesis delegate key (signing or
-- verification) to a corresponding Shelley-format key.
data KeyConvertByronKeyCmdArgs = KeyConvertByronKeyCmdArgs
Expand Down Expand Up @@ -124,6 +163,10 @@ renderKeyCmds = \case
"key verification-key"
KeyNonExtendedKeyCmd{} ->
"key non-extended-key"
KeyGenerateMnemonicCmd{} ->
"key generate-mnemonic"
KeyExtendedSigningKeyFromMnemonicCmd{} ->
"key from-mnemonic"
KeyConvertByronKeyCmd{} ->
"key convert-byron-key"
KeyConvertByronGenesisVKeyCmd{} ->
Expand Down
124 changes: 124 additions & 0 deletions cardano-cli/src/Cardano/CLI/Options/Key.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import Cardano.CLI.Types.Common

import Data.Foldable
import Data.Text (Text)
import GHC.Word (Word32)
import Options.Applicative hiding (help, str)
import qualified Options.Applicative as Opt

Expand All @@ -42,6 +43,23 @@ pKeyCmds =
, "extended verification key. This supports all "
, "extended key types."
]
, subParser "generate-mnemonic" $
Opt.info pKeyGenerateMnemonicCmd $
Opt.progDesc $
mconcat
[ "Generate a mnemonic sentence that can be used "
, "for key derivation."
]
, subParser "key-from-mnemonic" $
Opt.info pKeyExtendedSigningKeyFromMnemonicCmd $
Opt.progDesc $
mconcat
[ "Derive an extended signing key from a mnemonic "
, "sentence. "
, "To ensure the safety of the mnemonic phrase, "
, "we recommend that key derivation is performed "
, "in an air-gapped environment."
]
, subParser "convert-byron-key" $
Opt.info pKeyConvertByronKeyCmd $
Opt.progDesc $
Expand Down Expand Up @@ -114,6 +132,112 @@ pKeyNonExtendedKeyCmd =
<$> pExtendedVerificationKeyFileIn
<*> pVerificationKeyFileOut

pKeyGenerateMnemonicCmd :: Parser KeyCmds
pKeyGenerateMnemonicCmd =
fmap KeyGenerateMnemonicCmd $
KeyGenerateMnemonicCmdArgs
<$> optional pOutputFile
<*> pMnemonicSize

pMnemonicSize :: Parser MnemonicSize
pMnemonicSize = do
option
(maybeReader parseSize)
( long "size"
<> metavar "WORD32"
<> Opt.help
( mconcat
[ "Specify the desired number of words for the output"
, "mnemonic sentence (valid options are: 12, 15, 18, 21, and 24)"
]
)
)
where
parseSize :: String -> Maybe MnemonicSize
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use ReadM so you can fail with an appropriate error message?

parseSize "12" = Just MS12
parseSize "15" = Just MS15
parseSize "18" = Just MS18
parseSize "21" = Just MS21
parseSize "24" = Just MS24
parseSize _ = Nothing

pKeyExtendedSigningKeyFromMnemonicCmd :: Parser KeyCmds
pKeyExtendedSigningKeyFromMnemonicCmd =
fmap KeyExtendedSigningKeyFromMnemonicCmd $
KeyExtendedSigningKeyFromMnemonicArgs
<$> pKeyOutputFormat
<*> pExtendedSigningKeyType
<*> pAccountNumber
<*> pMnemonicSource
<*> pSigningKeyFileOut

pExtendedSigningKeyType :: Parser ExtendedSigningType
pExtendedSigningKeyType =
asum
[ ( ExtendedSigningPaymentKey
<$ ( Opt.flag' () $
mconcat
[ Opt.long "payment-key"
, Opt.help "Derive an extended payment key."
]
)
)
<*> pPaymentAddressNumber
, ( ExtendedSigningStakeKey
<$ ( Opt.flag' () $
mconcat
[ Opt.long "stake-key"
, Opt.help "Derive an extended stake key."
]
)
)
<*> pPaymentAddressNumber
, Opt.flag' ExtendedSigningDRepKey $
mconcat
[ Opt.long "drep-key"
, Opt.help "Derive an extended DRep key."
]
, Opt.flag' ExtendedSigningCCColdKey $
mconcat
[ Opt.long "cc-cold-key"
, Opt.help "Derive an extended committee cold key."
]
, Opt.flag' ExtendedSigningCCHotKey $
mconcat
[ Opt.long "cc-hot-key"
, Opt.help "Derive an extended committee hot key."
]
]

pMnemonicSource :: Parser MnemonicSource
pMnemonicSource =
asum
[ MnemonicFromFile . File <$> parseFilePath "mnemonic-from-file" "Input text file with the mnemonic."
, Opt.flag' MnemonicFromInteractivePrompt $
mconcat
[ Opt.long "mnemonic-from-interactive-prompt"
, Opt.help "Input the mnemonic through an interactive prompt."
]
]

pPaymentAddressNumber :: Parser Word32
pPaymentAddressNumber =
Opt.option integralReader $
mconcat
[ Opt.long "payment-address-number"
, Opt.metavar "WORD32"
, Opt.help "Payment address number in the derivation path."
]

pAccountNumber :: Parser Word32
pAccountNumber =
Opt.option integralReader $
mconcat
[ Opt.long "account-number"
, Opt.metavar "WORD32"
, Opt.help "Account number in the derivation path."
]

pKeyConvertByronKeyCmd :: Parser KeyCmds
pKeyConvertByronKeyCmd =
fmap KeyConvertByronKeyCmd $
Expand Down
Loading
Loading