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

Option to write keys in bech32 #5058

Merged
merged 10 commits into from
Jun 1, 2023
12 changes: 12 additions & 0 deletions cardano-cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,18 @@
([PR5119](https://github.com/input-output-hk/cardano-node/pull/5119))
([PR5119](https://github.com/input-output-hk/cardano-node/pull/5119))

- Add `--out-file` argument to the shelley stake-pool id command.
Add `--key-format-output` argument to the following commands:
- `address key-gen`
- `stake-address key-gen`
- `node key-gen`
- `node key-gen-KES`
- `node key-gen-VRF`
- `genesis create-staked`
- `genesis create`
[PR5058](https://github.com/input-output-hk/cardano-node/pull/5058)


### Features

- The `--socket-path` option is now a required CLI argument for relevant commands if `CARDANO_NODE_SOCKET_PATH` is not supplied.
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 @@ -252,6 +252,7 @@ test-suite cardano-cli-golden
, hedgehog ^>= 1.2
, hedgehog-extras ^>= 0.4.5.1
, regex-compat
, regex-tdfa
, text
, time
, transformers
Expand Down
28 changes: 20 additions & 8 deletions cardano-cli/src/Cardano/CLI/Shelley/Commands.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}

Expand Down Expand Up @@ -38,6 +39,7 @@ module Cardano.CLI.Shelley.Commands
, VerificationKeyBase64 (..)
, GenesisKeyFile (..)
, MetadataFile (..)
, StakePoolMetadataFile
, PrivKeyFile (..)
, BlockId (..)
, WitnessSigningData (..)
Expand Down Expand Up @@ -91,7 +93,7 @@ renderShelleyCommand sc =
TextViewCmd cmd -> renderTextViewCmd cmd

data AddressCmd
= AddressKeyGen AddressKeyType (VerificationKeyFile Out) (SigningKeyFile Out)
= AddressKeyGen KeyOutputFormat AddressKeyType (VerificationKeyFile Out) (SigningKeyFile Out)
| AddressKeyHash VerificationKeyTextOrFile (Maybe (File () Out))
| AddressBuild
PaymentVerifier
Expand All @@ -111,7 +113,7 @@ renderAddressCmd cmd =
AddressInfo {} -> "address info"

data StakeAddressCmd
= StakeAddressKeyGen (VerificationKeyFile Out) (SigningKeyFile Out)
= StakeAddressKeyGen KeyOutputFormat (VerificationKeyFile Out) (SigningKeyFile Out)
| StakeAddressKeyHash (VerificationKeyOrFile StakeKey) (Maybe (File () Out))
| StakeAddressBuild StakeVerifier NetworkId (Maybe (File () Out))
| StakeRegistrationCert StakeIdentifier (File () Out)
Expand Down Expand Up @@ -275,9 +277,9 @@ renderTransactionCmd cmd =
TxView {} -> "transaction view"

data NodeCmd
= NodeKeyGenCold (VerificationKeyFile Out) (SigningKeyFile Out) (OpCertCounterFile Out)
| NodeKeyGenKES (VerificationKeyFile Out) (SigningKeyFile Out)
| NodeKeyGenVRF (VerificationKeyFile Out) (SigningKeyFile Out)
= NodeKeyGenCold KeyOutputFormat (VerificationKeyFile Out) (SigningKeyFile Out) (OpCertCounterFile Out)
| NodeKeyGenKES KeyOutputFormat (VerificationKeyFile Out) (SigningKeyFile Out)
| NodeKeyGenVRF KeyOutputFormat (VerificationKeyFile Out) (SigningKeyFile Out)
| NodeKeyHashVRF (VerificationKeyOrFile VrfKey) (Maybe (File () Out))
| NodeNewCounter ColdVerificationKeyOrFile Word (OpCertCounterFile InOut)
| NodeIssueOpCert (VerificationKeyOrFile KesKey) (SigningKeyFile In) (OpCertCounterFile InOut)
Expand Down Expand Up @@ -323,8 +325,8 @@ data PoolCmd
EpochNo
-- ^ Epoch in which to retire the stake pool.
(File Certificate Out)
| PoolGetId (VerificationKeyOrFile StakePoolKey) OutputFormat
| PoolMetadataHash (File StakePoolMetadata In) (Maybe (File () Out))
| PoolGetId (VerificationKeyOrFile StakePoolKey) PoolIdOutputFormat (Maybe (File () Out))
| PoolMetadataHash (StakePoolMetadataFile In) (Maybe (File () Out))
deriving Show

renderPoolCmd :: PoolCmd -> Text
Expand Down Expand Up @@ -448,9 +450,17 @@ renderTextViewCmd :: TextViewCmd -> Text
renderTextViewCmd (TextViewInfo _ _) = "text-view decode-cbor"

data GenesisCmd
= GenesisCreate GenesisDir Word Word (Maybe SystemStart) (Maybe Lovelace) NetworkId
= GenesisCreate
KeyOutputFormat
GenesisDir
Word
Word
(Maybe SystemStart)
(Maybe Lovelace)
NetworkId
| GenesisCreateCardano GenesisDir Word Word (Maybe SystemStart) (Maybe Lovelace) BlockCount Word Rational NetworkId FilePath FilePath FilePath FilePath (Maybe FilePath)
| GenesisCreateStaked
KeyOutputFormat
GenesisDir
Word
Word
Expand Down Expand Up @@ -526,6 +536,8 @@ data MetadataFile = MetadataFileJSON (File () In)

deriving Show

type StakePoolMetadataFile = File StakePoolMetadata

newtype GenesisDir
= GenesisDir FilePath
deriving Show
Expand Down
97 changes: 68 additions & 29 deletions cardano-cli/src/Cardano/CLI/Shelley/Parsers.hs
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,12 @@ pAddressCmd envCli =
]
where
pAddressKeyGen :: Parser AddressCmd
pAddressKeyGen = AddressKeyGen
<$> pAddressKeyType
<*> pVerificationKeyFileOut
<*> pSigningKeyFileOut
pAddressKeyGen =
AddressKeyGen
<$> pKeyOutputFormat
<*> pAddressKeyType
<*> pVerificationKeyFileOut
<*> pSigningKeyFileOut

pAddressKeyHash :: Parser AddressCmd
pAddressKeyHash =
Expand Down Expand Up @@ -382,7 +384,8 @@ pStakeAddressCmd envCli =
pStakeAddressKeyGen :: Parser StakeAddressCmd
pStakeAddressKeyGen =
StakeAddressKeyGen
<$> pVerificationKeyFileOut
<$> pKeyOutputFormat
<*> pVerificationKeyFileOut
<*> pSigningKeyFileOut

pStakeAddressKeyHash :: Parser StakeAddressCmd
Expand Down Expand Up @@ -863,17 +866,24 @@ pNodeCmd =
pKeyGenOperator :: Parser NodeCmd
pKeyGenOperator =
NodeKeyGenCold
<$> pColdVerificationKeyFile
<$> pKeyOutputFormat
<*> pColdVerificationKeyFile
<*> pColdSigningKeyFile
<*> pOperatorCertIssueCounterFile

pKeyGenKES :: Parser NodeCmd
pKeyGenKES =
NodeKeyGenKES <$> pVerificationKeyFileOut <*> pSigningKeyFileOut
NodeKeyGenKES
<$> pKeyOutputFormat
<*> pVerificationKeyFileOut
<*> pSigningKeyFileOut

pKeyGenVRF :: Parser NodeCmd
pKeyGenVRF =
NodeKeyGenVRF <$> pVerificationKeyFileOut <*> pSigningKeyFileOut
NodeKeyGenVRF
<$> pKeyOutputFormat
<*> pVerificationKeyFileOut
<*> pSigningKeyFileOut

pKeyHashVRF :: Parser NodeCmd
pKeyHashVRF =
Expand Down Expand Up @@ -916,7 +926,7 @@ pPoolCmd envCli =
]
where
pId :: Parser PoolCmd
pId = PoolGetId <$> pStakePoolVerificationKeyOrFile <*> pOutputFormat
pId = PoolGetId <$> pStakePoolVerificationKeyOrFile <*> pPoolIdOutputFormat <*> pMaybeOutputFile

pPoolMetadataHashSubCmd :: Parser PoolCmd
pPoolMetadataHashSubCmd = PoolMetadataHash <$> pPoolMetadataFile <*> pMaybeOutputFile
Expand Down Expand Up @@ -1387,7 +1397,8 @@ pGenesisCmd envCli =
pGenesisCreate :: Parser GenesisCmd
pGenesisCreate =
GenesisCreate
<$> pGenesisDir
<$> pKeyOutputFormat
<*> pGenesisDir
<*> pGenesisNumGenesisKeys
<*> pGenesisNumUTxOKeys
<*> pMaybeSystemStart
Expand All @@ -1397,7 +1408,8 @@ pGenesisCmd envCli =
pGenesisCreateStaked :: Parser GenesisCmd
pGenesisCreateStaked =
GenesisCreateStaked
<$> pGenesisDir
<$> pKeyOutputFormat
<*> pGenesisDir
<*> pGenesisNumGenesisKeys
<*> pGenesisNumUTxOKeys
<*> pGenesisNumPools
Expand Down Expand Up @@ -1638,7 +1650,7 @@ pCertificateFile balanceExecUnits =
, "stake key certificates etc). Optionally specify a script witness."
]

pPoolMetadataFile :: Parser (File StakePoolMetadata In)
pPoolMetadataFile :: Parser (StakePoolMetadataFile In)
pPoolMetadataFile =
fmap File $ Opt.strOption $ mconcat
[ Opt.long "pool-metadata-file"
Expand Down Expand Up @@ -1923,15 +1935,29 @@ pOperationalCertificateFile =
<> Opt.completer (Opt.bashCompleter "file")
)

pOutputFormat :: Parser OutputFormat
pOutputFormat =
Opt.option readOutputFormat
( Opt.long "output-format"
<> Opt.metavar "STRING"
<> Opt.help "Optional output format. Accepted output formats are \"hex\" \
\and \"bech32\" (default is \"bech32\")."
<> Opt.value OutputFormatBech32
)
pKeyOutputFormat :: Parser KeyOutputFormat
pKeyOutputFormat =
Opt.option readKeyOutputFormat $ mconcat
[ Opt.long "key-output-format"
, Opt.metavar "STRING"
, Opt.help $ mconcat
[ "Optional key output format. Accepted output formats are \"text-envelope\" "
, "and \"bech32\" (default is \"bech32\")."
]
, Opt.value KeyOutputFormatTextEnvelope
]

pPoolIdOutputFormat :: Parser PoolIdOutputFormat
pPoolIdOutputFormat =
Opt.option readPoolIdOutputFormat $ mconcat
[ Opt.long "output-format"
, Opt.metavar "STRING"
, Opt.help $ mconcat
[ "Optional pool id output format. Accepted output formats are \"hex\" "
, "and \"bech32\" (default is \"bech32\")."
]
, Opt.value PoolIdOutputFormatBech32
]

pMaybeOutputFile :: Parser (Maybe (File content Out))
pMaybeOutputFile =
Expand Down Expand Up @@ -3380,16 +3406,29 @@ readVerificationKey asType =
first (Text.unpack . renderInputDecodeError) $
deserialiseInput (AsVerificationKey asType) keyFormats (BSC.pack str)

readOutputFormat :: Opt.ReadM OutputFormat
readOutputFormat = do
s <- Opt.str
readPoolIdOutputFormat :: Opt.ReadM PoolIdOutputFormat
readPoolIdOutputFormat = do
s <- Opt.str @String
case s of
"hex" -> pure PoolIdOutputFormatHex
"bech32" -> pure PoolIdOutputFormatBech32
_ ->
fail $ mconcat
[ "Invalid output format: " <> show s
, ". Accepted output formats are \"hex\" and \"bech32\"."
]

readKeyOutputFormat :: Opt.ReadM KeyOutputFormat
readKeyOutputFormat = do
s <- Opt.str @String
case s of
"hex" -> pure OutputFormatHex
"bech32" -> pure OutputFormatBech32
"text-envelope" -> pure KeyOutputFormatTextEnvelope
"bech32" -> pure KeyOutputFormatBech32
_ ->
fail $ "Invalid output format: \""
<> s
<> "\". Accepted output formats are \"hex\" and \"bech32\"."
fail $ mconcat
[ "Invalid key output format: " <> show s
, ". Accepted output formats are \"text-envelope\" and \"bech32\"."
]

readURIOfMaxLength :: Int -> Opt.ReadM Text
readURIOfMaxLength maxLen =
Expand Down
74 changes: 63 additions & 11 deletions cardano-cli/src/Cardano/CLI/Shelley/Run/Address.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}

Expand Down Expand Up @@ -59,39 +60,90 @@ renderShelleyAddressCmdError err =
runAddressCmd :: AddressCmd -> ExceptT ShelleyAddressCmdError IO ()
runAddressCmd cmd =
case cmd of
AddressKeyGen kt vkf skf -> runAddressKeyGenToFile kt vkf skf
AddressKeyGen fmt kt vkf skf -> runAddressKeyGenToFile fmt kt vkf skf
AddressKeyHash vkf mOFp -> runAddressKeyHash vkf mOFp
AddressBuild paymentVerifier mbStakeVerifier nw mOutFp -> runAddressBuild paymentVerifier mbStakeVerifier nw mOutFp
AddressInfo txt mOFp -> firstExceptT ShelleyAddressCmdAddressInfoError $ runAddressInfo txt mOFp

runAddressKeyGenToFile
:: AddressKeyType
:: KeyOutputFormat
-> AddressKeyType
-> VerificationKeyFile Out
-> SigningKeyFile Out
-> ExceptT ShelleyAddressCmdError IO ()
runAddressKeyGenToFile kt vkf skf = case kt of
AddressKeyShelley -> generateAndWriteKeyFiles AsPaymentKey vkf skf
AddressKeyShelleyExtended -> generateAndWriteKeyFiles AsPaymentExtendedKey vkf skf
AddressKeyByron -> generateAndWriteKeyFiles AsByronKey vkf skf
runAddressKeyGenToFile fmt kt vkf skf = case kt of
AddressKeyShelley -> generateAndWriteKeyFiles fmt AsPaymentKey vkf skf
AddressKeyShelleyExtended -> generateAndWriteKeyFiles fmt AsPaymentExtendedKey vkf skf
AddressKeyByron -> generateAndWriteByronKeyFiles AsByronKey vkf skf

generateAndWriteKeyFiles
generateAndWriteByronKeyFiles
:: Key keyrole
=> AsType keyrole
-> VerificationKeyFile Out
-> SigningKeyFile Out
-> ExceptT ShelleyAddressCmdError IO ()
generateAndWriteKeyFiles asType vkf skf = do
uncurry (writePaymentKeyFiles vkf skf) =<< liftIO (generateKeyPair asType)
generateAndWriteByronKeyFiles asType vkf skf = do
uncurry (writeByronPaymentKeyFiles vkf skf) =<< liftIO (generateKeyPair asType)

generateAndWriteKeyFiles
:: Key keyrole
=> SerialiseAsBech32 (SigningKey keyrole)
=> SerialiseAsBech32 (VerificationKey keyrole)
=> KeyOutputFormat
-> AsType keyrole
-> VerificationKeyFile Out
-> SigningKeyFile Out
-> ExceptT ShelleyAddressCmdError IO ()
generateAndWriteKeyFiles fmt asType vkf skf = do
uncurry (writePaymentKeyFiles fmt vkf skf) =<< liftIO (generateKeyPair asType)

writePaymentKeyFiles
:: Key keyrole
=> VerificationKeyFile Out
=> SerialiseAsBech32 (SigningKey keyrole)
=> SerialiseAsBech32 (VerificationKey keyrole)
=> KeyOutputFormat
-> VerificationKeyFile Out
-> SigningKeyFile Out
-> VerificationKey keyrole
-> SigningKey keyrole
-> ExceptT ShelleyAddressCmdError IO ()
writePaymentKeyFiles vkeyPath skeyPath vkey skey = do
writePaymentKeyFiles fmt vkeyPath skeyPath vkey skey = do
firstExceptT ShelleyAddressCmdWriteFileError $ do
case fmt of
KeyOutputFormatTextEnvelope ->
newExceptT
$ writeLazyByteStringFile skeyPath
$ textEnvelopeToJSON (Just skeyDesc) skey
KeyOutputFormatBech32 ->
newExceptT
$ writeTextFile skeyPath
$ serialiseToBech32 skey

case fmt of
KeyOutputFormatTextEnvelope ->
newExceptT
$ writeLazyByteStringFile vkeyPath
$ textEnvelopeToJSON (Just vkeyDesc) vkey
KeyOutputFormatBech32 ->
newExceptT
$ writeTextFile vkeyPath
$ serialiseToBech32 vkey

where
skeyDesc, vkeyDesc :: TextEnvelopeDescr
skeyDesc = "Payment Signing Key"
vkeyDesc = "Payment Verification Key"

writeByronPaymentKeyFiles
:: Key keyrole
=> VerificationKeyFile Out
-> SigningKeyFile Out
-> VerificationKey keyrole
-> SigningKey keyrole
-> ExceptT ShelleyAddressCmdError IO ()
writeByronPaymentKeyFiles vkeyPath skeyPath vkey skey = do
firstExceptT ShelleyAddressCmdWriteFileError $ do
-- No bech32 encoding for Byron keys
newExceptT $ writeLazyByteStringFile skeyPath $ textEnvelopeToJSON (Just skeyDesc) skey
newExceptT $ writeLazyByteStringFile vkeyPath $ textEnvelopeToJSON (Just vkeyDesc) vkey
where
Expand Down
Loading