module Cardano.CLI.Shelley.Run.Node
  ( ShelleyNodeCmdError(ShelleyNodeCmdReadFileError)
  , renderShelleyNodeCmdError
  , runNodeCmd
  , runNodeIssueOpCert
  , runNodeKeyGenCold
  , runNodeKeyGenKES
  , runNodeKeyGenVRF
  , readColdVerificationKeyOrFile
  ) where

import           Control.Monad.IO.Class (MonadIO (..))
import           Control.Monad.Trans.Except (ExceptT)
import           Control.Monad.Trans.Except.Extra (firstExceptT, hoistEither, newExceptT)
import qualified Data.ByteString.Char8 as BS
import           Data.String (fromString)
import           Data.Text (Text)
import qualified Data.Text as Text
import           Data.Word (Word64)

import           Cardano.Api
import           Cardano.Api.Shelley

import           Cardano.CLI.Shelley.Commands
import           Cardano.CLI.Shelley.Key (VerificationKeyOrFile, readVerificationKeyOrFile)
import           Cardano.CLI.Types (SigningKeyFile (..), VerificationKeyFile (..))

{- HLINT ignore "Reduce duplication" -}

data ShelleyNodeCmdError
  = ShelleyNodeCmdReadFileError !(FileError TextEnvelopeError)
  | ShelleyNodeCmdReadKeyFileError !(FileError InputDecodeError)
  | ShelleyNodeCmdWriteFileError !(FileError ())
  | ShelleyNodeCmdOperationalCertificateIssueError !OperationalCertIssueError
  | ShelleyNodeCmdVrfSigningKeyCreationError
      FilePath
      -- ^ Target path
      FilePath
      -- ^ Temp path
  deriving Int -> ShelleyNodeCmdError -> ShowS
[ShelleyNodeCmdError] -> ShowS
ShelleyNodeCmdError -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ShelleyNodeCmdError] -> ShowS
$cshowList :: [ShelleyNodeCmdError] -> ShowS
show :: ShelleyNodeCmdError -> String
$cshow :: ShelleyNodeCmdError -> String
showsPrec :: Int -> ShelleyNodeCmdError -> ShowS
$cshowsPrec :: Int -> ShelleyNodeCmdError -> ShowS
Show

renderShelleyNodeCmdError :: ShelleyNodeCmdError -> Text
renderShelleyNodeCmdError :: ShelleyNodeCmdError -> Text
renderShelleyNodeCmdError ShelleyNodeCmdError
err =
  case ShelleyNodeCmdError
err of
    ShelleyNodeCmdVrfSigningKeyCreationError String
targetPath String
tempPath ->
      String -> Text
Text.pack forall a b. (a -> b) -> a -> b
$ String
"Error creating VRF signing key file. Target path: " forall a. Semigroup a => a -> a -> a
<> String
targetPath
      forall a. Semigroup a => a -> a -> a
<> String
" Temporary path: " forall a. Semigroup a => a -> a -> a
<> String
tempPath

    ShelleyNodeCmdReadFileError FileError TextEnvelopeError
fileErr -> String -> Text
Text.pack (forall e. Error e => e -> String
displayError FileError TextEnvelopeError
fileErr)

    ShelleyNodeCmdReadKeyFileError FileError InputDecodeError
fileErr -> String -> Text
Text.pack (forall e. Error e => e -> String
displayError FileError InputDecodeError
fileErr)

    ShelleyNodeCmdWriteFileError FileError ()
fileErr -> String -> Text
Text.pack (forall e. Error e => e -> String
displayError FileError ()
fileErr)

    ShelleyNodeCmdOperationalCertificateIssueError OperationalCertIssueError
issueErr ->
      String -> Text
Text.pack (forall e. Error e => e -> String
displayError OperationalCertIssueError
issueErr)


runNodeCmd :: NodeCmd -> ExceptT ShelleyNodeCmdError IO ()
runNodeCmd :: NodeCmd -> ExceptT ShelleyNodeCmdError IO ()
runNodeCmd (NodeKeyGenCold VerificationKeyFile
vk SigningKeyFile
sk OpCertCounterFile
ctr) = VerificationKeyFile
-> SigningKeyFile
-> OpCertCounterFile
-> ExceptT ShelleyNodeCmdError IO ()
runNodeKeyGenCold VerificationKeyFile
vk SigningKeyFile
sk OpCertCounterFile
ctr
runNodeCmd (NodeKeyGenKES  VerificationKeyFile
vk SigningKeyFile
sk)     = VerificationKeyFile
-> SigningKeyFile -> ExceptT ShelleyNodeCmdError IO ()
runNodeKeyGenKES  VerificationKeyFile
vk SigningKeyFile
sk
runNodeCmd (NodeKeyGenVRF  VerificationKeyFile
vk SigningKeyFile
sk)     = VerificationKeyFile
-> SigningKeyFile -> ExceptT ShelleyNodeCmdError IO ()
runNodeKeyGenVRF  VerificationKeyFile
vk SigningKeyFile
sk
runNodeCmd (NodeKeyHashVRF VerificationKeyOrFile VrfKey
vk Maybe OutputFile
mOutFp) = VerificationKeyOrFile VrfKey
-> Maybe OutputFile -> ExceptT ShelleyNodeCmdError IO ()
runNodeKeyHashVRF VerificationKeyOrFile VrfKey
vk Maybe OutputFile
mOutFp
runNodeCmd (NodeNewCounter ColdVerificationKeyOrFile
vk Word
ctr OpCertCounterFile
out) = ColdVerificationKeyOrFile
-> Word -> OpCertCounterFile -> ExceptT ShelleyNodeCmdError IO ()
runNodeNewCounter ColdVerificationKeyOrFile
vk Word
ctr OpCertCounterFile
out
runNodeCmd (NodeIssueOpCert VerificationKeyOrFile KesKey
vk SigningKeyFile
sk OpCertCounterFile
ctr KESPeriod
p OutputFile
out) =
  VerificationKeyOrFile KesKey
-> SigningKeyFile
-> OpCertCounterFile
-> KESPeriod
-> OutputFile
-> ExceptT ShelleyNodeCmdError IO ()
runNodeIssueOpCert VerificationKeyOrFile KesKey
vk SigningKeyFile
sk OpCertCounterFile
ctr KESPeriod
p OutputFile
out



--
-- Node command implementations
--

runNodeKeyGenCold :: VerificationKeyFile
                  -> SigningKeyFile
                  -> OpCertCounterFile
                  -> ExceptT ShelleyNodeCmdError IO ()
runNodeKeyGenCold :: VerificationKeyFile
-> SigningKeyFile
-> OpCertCounterFile
-> ExceptT ShelleyNodeCmdError IO ()
runNodeKeyGenCold (VerificationKeyFile String
vkeyPath) (SigningKeyFile String
skeyPath)
                  (OpCertCounterFile String
ocertCtrPath) = do
    SigningKey StakePoolKey
skey <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall keyrole.
Key keyrole =>
AsType keyrole -> IO (SigningKey keyrole)
generateSigningKey AsType StakePoolKey
AsStakePoolKey
    let vkey :: VerificationKey StakePoolKey
vkey = forall keyrole.
Key keyrole =>
SigningKey keyrole -> VerificationKey keyrole
getVerificationKey SigningKey StakePoolKey
skey
    forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT FileError () -> ShelleyNodeCmdError
ShelleyNodeCmdWriteFileError
      forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newExceptT
      forall a b. (a -> b) -> a -> b
$ forall a.
HasTextEnvelope a =>
String
-> Maybe TextEnvelopeDescr -> a -> IO (Either (FileError ()) ())
writeFileTextEnvelope String
skeyPath (forall a. a -> Maybe a
Just TextEnvelopeDescr
skeyDesc) SigningKey StakePoolKey
skey
    forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT FileError () -> ShelleyNodeCmdError
ShelleyNodeCmdWriteFileError
      forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newExceptT
      forall a b. (a -> b) -> a -> b
$ forall a.
HasTextEnvelope a =>
String
-> Maybe TextEnvelopeDescr -> a -> IO (Either (FileError ()) ())
writeFileTextEnvelope String
vkeyPath (forall a. a -> Maybe a
Just TextEnvelopeDescr
vkeyDesc) VerificationKey StakePoolKey
vkey
    forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT FileError () -> ShelleyNodeCmdError
ShelleyNodeCmdWriteFileError
      forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newExceptT
      forall a b. (a -> b) -> a -> b
$ forall a.
HasTextEnvelope a =>
String
-> Maybe TextEnvelopeDescr -> a -> IO (Either (FileError ()) ())
writeFileTextEnvelope String
ocertCtrPath (forall a. a -> Maybe a
Just TextEnvelopeDescr
ocertCtrDesc)
      forall a b. (a -> b) -> a -> b
$ Word64
-> VerificationKey StakePoolKey
-> OperationalCertificateIssueCounter
OperationalCertificateIssueCounter Word64
initialCounter VerificationKey StakePoolKey
vkey
  where
    skeyDesc, vkeyDesc, ocertCtrDesc :: TextEnvelopeDescr
    skeyDesc :: TextEnvelopeDescr
skeyDesc = TextEnvelopeDescr
"Stake Pool Operator Signing Key"
    vkeyDesc :: TextEnvelopeDescr
vkeyDesc = TextEnvelopeDescr
"Stake Pool Operator Verification Key"
    ocertCtrDesc :: TextEnvelopeDescr
ocertCtrDesc = TextEnvelopeDescr
"Next certificate issue number: "
                forall a. Semigroup a => a -> a -> a
<> forall a. IsString a => String -> a
fromString (forall a. Show a => a -> String
show Word64
initialCounter)

    initialCounter :: Word64
    initialCounter :: Word64
initialCounter = Word64
0


runNodeKeyGenKES :: VerificationKeyFile
                 -> SigningKeyFile
                 -> ExceptT ShelleyNodeCmdError IO ()
runNodeKeyGenKES :: VerificationKeyFile
-> SigningKeyFile -> ExceptT ShelleyNodeCmdError IO ()
runNodeKeyGenKES (VerificationKeyFile String
vkeyPath) (SigningKeyFile String
skeyPath) = do
    SigningKey KesKey
skey <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall keyrole.
Key keyrole =>
AsType keyrole -> IO (SigningKey keyrole)
generateSigningKey AsType KesKey
AsKesKey
    let vkey :: VerificationKey KesKey
vkey = forall keyrole.
Key keyrole =>
SigningKey keyrole -> VerificationKey keyrole
getVerificationKey SigningKey KesKey
skey
    forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT FileError () -> ShelleyNodeCmdError
ShelleyNodeCmdWriteFileError
      forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newExceptT
      forall a b. (a -> b) -> a -> b
$ forall a.
HasTextEnvelope a =>
String
-> Maybe TextEnvelopeDescr -> a -> IO (Either (FileError ()) ())
writeFileTextEnvelope String
skeyPath (forall a. a -> Maybe a
Just TextEnvelopeDescr
skeyDesc) SigningKey KesKey
skey
    forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT FileError () -> ShelleyNodeCmdError
ShelleyNodeCmdWriteFileError
      forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newExceptT
      forall a b. (a -> b) -> a -> b
$ forall a.
HasTextEnvelope a =>
String
-> Maybe TextEnvelopeDescr -> a -> IO (Either (FileError ()) ())
writeFileTextEnvelope String
vkeyPath (forall a. a -> Maybe a
Just TextEnvelopeDescr
vkeyDesc) VerificationKey KesKey
vkey
  where
    skeyDesc, vkeyDesc :: TextEnvelopeDescr
    skeyDesc :: TextEnvelopeDescr
skeyDesc = TextEnvelopeDescr
"KES Signing Key"
    vkeyDesc :: TextEnvelopeDescr
vkeyDesc = TextEnvelopeDescr
"KES Verification Key"

runNodeKeyGenVRF :: VerificationKeyFile -> SigningKeyFile
                 -> ExceptT ShelleyNodeCmdError IO ()
runNodeKeyGenVRF :: VerificationKeyFile
-> SigningKeyFile -> ExceptT ShelleyNodeCmdError IO ()
runNodeKeyGenVRF (VerificationKeyFile String
vkeyPath) (SigningKeyFile String
skeyPath) = do
    SigningKey VrfKey
skey <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall keyrole.
Key keyrole =>
AsType keyrole -> IO (SigningKey keyrole)
generateSigningKey AsType VrfKey
AsVrfKey
    let vkey :: VerificationKey VrfKey
vkey = forall keyrole.
Key keyrole =>
SigningKey keyrole -> VerificationKey keyrole
getVerificationKey SigningKey VrfKey
skey
    forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT FileError () -> ShelleyNodeCmdError
ShelleyNodeCmdWriteFileError
      forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newExceptT
      forall a b. (a -> b) -> a -> b
$ forall a.
HasTextEnvelope a =>
String
-> Maybe TextEnvelopeDescr -> a -> IO (Either (FileError ()) ())
writeFileTextEnvelopeWithOwnerPermissions String
skeyPath (forall a. a -> Maybe a
Just TextEnvelopeDescr
skeyDesc) SigningKey VrfKey
skey
    forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT FileError () -> ShelleyNodeCmdError
ShelleyNodeCmdWriteFileError
      forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newExceptT
      forall a b. (a -> b) -> a -> b
$ forall a.
HasTextEnvelope a =>
String
-> Maybe TextEnvelopeDescr -> a -> IO (Either (FileError ()) ())
writeFileTextEnvelope String
vkeyPath (forall a. a -> Maybe a
Just TextEnvelopeDescr
vkeyDesc) VerificationKey VrfKey
vkey
  where
    skeyDesc, vkeyDesc :: TextEnvelopeDescr
    skeyDesc :: TextEnvelopeDescr
skeyDesc = TextEnvelopeDescr
"VRF Signing Key"
    vkeyDesc :: TextEnvelopeDescr
vkeyDesc = TextEnvelopeDescr
"VRF Verification Key"

runNodeKeyHashVRF :: VerificationKeyOrFile VrfKey
                  -> Maybe OutputFile
                  -> ExceptT ShelleyNodeCmdError IO ()
runNodeKeyHashVRF :: VerificationKeyOrFile VrfKey
-> Maybe OutputFile -> ExceptT ShelleyNodeCmdError IO ()
runNodeKeyHashVRF VerificationKeyOrFile VrfKey
verKeyOrFile Maybe OutputFile
mOutputFp = do
  VerificationKey VrfKey
vkey <- forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT FileError InputDecodeError -> ShelleyNodeCmdError
ShelleyNodeCmdReadKeyFileError
    forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newExceptT
    forall a b. (a -> b) -> a -> b
$ forall keyrole.
(HasTextEnvelope (VerificationKey keyrole),
 SerialiseAsBech32 (VerificationKey keyrole)) =>
AsType keyrole
-> VerificationKeyOrFile keyrole
-> IO
     (Either (FileError InputDecodeError) (VerificationKey keyrole))
readVerificationKeyOrFile AsType VrfKey
AsVrfKey VerificationKeyOrFile VrfKey
verKeyOrFile

  let hexKeyHash :: ByteString
hexKeyHash = forall a. SerialiseAsRawBytes a => a -> ByteString
serialiseToRawBytesHex (forall keyrole.
Key keyrole =>
VerificationKey keyrole -> Hash keyrole
verificationKeyHash VerificationKey VrfKey
vkey)

  case Maybe OutputFile
mOutputFp of
    Just (OutputFile String
fpath) -> forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ String -> ByteString -> IO ()
BS.writeFile String
fpath ByteString
hexKeyHash
    Maybe OutputFile
Nothing -> forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ ByteString -> IO ()
BS.putStrLn ByteString
hexKeyHash


runNodeNewCounter :: ColdVerificationKeyOrFile
                  -> Word
                  -> OpCertCounterFile
                  -> ExceptT ShelleyNodeCmdError IO ()
runNodeNewCounter :: ColdVerificationKeyOrFile
-> Word -> OpCertCounterFile -> ExceptT ShelleyNodeCmdError IO ()
runNodeNewCounter ColdVerificationKeyOrFile
coldVerKeyOrFile Word
counter
                  (OpCertCounterFile String
ocertCtrPath) = do

    VerificationKey StakePoolKey
vkey <- forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT FileError TextEnvelopeError -> ShelleyNodeCmdError
ShelleyNodeCmdReadFileError forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newExceptT forall a b. (a -> b) -> a -> b
$
      ColdVerificationKeyOrFile
-> IO
     (Either
        (FileError TextEnvelopeError) (VerificationKey StakePoolKey))
readColdVerificationKeyOrFile ColdVerificationKeyOrFile
coldVerKeyOrFile

    let ocertIssueCounter :: OperationalCertificateIssueCounter
ocertIssueCounter =
          Word64
-> VerificationKey StakePoolKey
-> OperationalCertificateIssueCounter
OperationalCertificateIssueCounter (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
counter) VerificationKey StakePoolKey
vkey

    forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT FileError () -> ShelleyNodeCmdError
ShelleyNodeCmdWriteFileError forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newExceptT forall a b. (a -> b) -> a -> b
$
      forall a.
HasTextEnvelope a =>
String
-> Maybe TextEnvelopeDescr -> a -> IO (Either (FileError ()) ())
writeFileTextEnvelope String
ocertCtrPath forall a. Maybe a
Nothing OperationalCertificateIssueCounter
ocertIssueCounter


runNodeIssueOpCert :: VerificationKeyOrFile KesKey
                   -- ^ This is the hot KES verification key.
                   -> SigningKeyFile
                   -- ^ This is the cold signing key.
                   -> OpCertCounterFile
                   -- ^ Counter that establishes the precedence
                   -- of the operational certificate.
                   -> KESPeriod
                   -- ^ Start of the validity period for this certificate.
                   -> OutputFile
                   -> ExceptT ShelleyNodeCmdError IO ()
runNodeIssueOpCert :: VerificationKeyOrFile KesKey
-> SigningKeyFile
-> OpCertCounterFile
-> KESPeriod
-> OutputFile
-> ExceptT ShelleyNodeCmdError IO ()
runNodeIssueOpCert VerificationKeyOrFile KesKey
kesVerKeyOrFile
                   (SigningKeyFile String
stakePoolSKeyFile)
                   (OpCertCounterFile String
ocertCtrPath)
                   KESPeriod
kesPeriod
                   (OutputFile String
certFile) = do

    OperationalCertificateIssueCounter
ocertIssueCounter <- forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT FileError TextEnvelopeError -> ShelleyNodeCmdError
ShelleyNodeCmdReadFileError
      forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newExceptT
      forall a b. (a -> b) -> a -> b
$ forall a.
HasTextEnvelope a =>
AsType a -> String -> IO (Either (FileError TextEnvelopeError) a)
readFileTextEnvelope AsType OperationalCertificateIssueCounter
AsOperationalCertificateIssueCounter String
ocertCtrPath

    VerificationKey KesKey
verKeyKes <- forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT FileError InputDecodeError -> ShelleyNodeCmdError
ShelleyNodeCmdReadKeyFileError
      forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newExceptT
      forall a b. (a -> b) -> a -> b
$ forall keyrole.
(HasTextEnvelope (VerificationKey keyrole),
 SerialiseAsBech32 (VerificationKey keyrole)) =>
AsType keyrole
-> VerificationKeyOrFile keyrole
-> IO
     (Either (FileError InputDecodeError) (VerificationKey keyrole))
readVerificationKeyOrFile AsType KesKey
AsKesKey VerificationKeyOrFile KesKey
kesVerKeyOrFile

    Either
  (SigningKey StakePoolKey) (SigningKey GenesisDelegateExtendedKey)
signKey <- forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT FileError InputDecodeError -> ShelleyNodeCmdError
ShelleyNodeCmdReadKeyFileError
      forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newExceptT
      forall a b. (a -> b) -> a -> b
$ forall b.
[FromSomeType SerialiseAsBech32 b]
-> [FromSomeType HasTextEnvelope b]
-> String
-> IO (Either (FileError InputDecodeError) b)
readKeyFileAnyOf
          [FromSomeType
   SerialiseAsBech32
   (Either
      (SigningKey StakePoolKey) (SigningKey GenesisDelegateExtendedKey))]
bech32PossibleBlockIssuers
          [FromSomeType
   HasTextEnvelope
   (Either
      (SigningKey StakePoolKey) (SigningKey GenesisDelegateExtendedKey))]
textEnvPossibleBlockIssuers
          String
stakePoolSKeyFile

    (OperationalCertificate
ocert, OperationalCertificateIssueCounter
nextOcertCtr) <-
      forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT OperationalCertIssueError -> ShelleyNodeCmdError
ShelleyNodeCmdOperationalCertificateIssueError
        forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) x a. Monad m => Either x a -> ExceptT x m a
hoistEither
        forall a b. (a -> b) -> a -> b
$ VerificationKey KesKey
-> Either
     (SigningKey StakePoolKey) (SigningKey GenesisDelegateExtendedKey)
-> KESPeriod
-> OperationalCertificateIssueCounter
-> Either
     OperationalCertIssueError
     (OperationalCertificate, OperationalCertificateIssueCounter)
issueOperationalCertificate
            VerificationKey KesKey
verKeyKes
            Either
  (SigningKey StakePoolKey) (SigningKey GenesisDelegateExtendedKey)
signKey
            KESPeriod
kesPeriod
            OperationalCertificateIssueCounter
ocertIssueCounter

    -- Write the counter first, to reduce the chance of ending up with
    -- a new cert but without updating the counter.
    forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT FileError () -> ShelleyNodeCmdError
ShelleyNodeCmdWriteFileError
      forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newExceptT
      forall a b. (a -> b) -> a -> b
$ forall a.
HasTextEnvelope a =>
String
-> Maybe TextEnvelopeDescr -> a -> IO (Either (FileError ()) ())
writeFileTextEnvelope
        String
ocertCtrPath
        (forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Word64 -> TextEnvelopeDescr
ocertCtrDesc forall a b. (a -> b) -> a -> b
$ OperationalCertificateIssueCounter -> Word64
getCounter OperationalCertificateIssueCounter
nextOcertCtr)
        OperationalCertificateIssueCounter
nextOcertCtr

    forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT FileError () -> ShelleyNodeCmdError
ShelleyNodeCmdWriteFileError
      forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newExceptT
      forall a b. (a -> b) -> a -> b
$ forall a.
HasTextEnvelope a =>
String
-> Maybe TextEnvelopeDescr -> a -> IO (Either (FileError ()) ())
writeFileTextEnvelope String
certFile forall a. Maybe a
Nothing OperationalCertificate
ocert
  where
    getCounter :: OperationalCertificateIssueCounter -> Word64
    getCounter :: OperationalCertificateIssueCounter -> Word64
getCounter (OperationalCertificateIssueCounter Word64
n VerificationKey StakePoolKey
_) = Word64
n

    ocertCtrDesc :: Word64 -> TextEnvelopeDescr
    ocertCtrDesc :: Word64 -> TextEnvelopeDescr
ocertCtrDesc Word64
n = TextEnvelopeDescr
"Next certificate issue number: " forall a. Semigroup a => a -> a -> a
<> forall a. IsString a => String -> a
fromString (forall a. Show a => a -> String
show Word64
n)

    textEnvPossibleBlockIssuers
      :: [FromSomeType HasTextEnvelope
                       (Either (SigningKey StakePoolKey)
                               (SigningKey GenesisDelegateExtendedKey))]
    textEnvPossibleBlockIssuers :: [FromSomeType
   HasTextEnvelope
   (Either
      (SigningKey StakePoolKey) (SigningKey GenesisDelegateExtendedKey))]
textEnvPossibleBlockIssuers =
      [ forall (c :: * -> Constraint) a b.
c a =>
AsType a -> (a -> b) -> FromSomeType c b
FromSomeType (forall a. AsType a -> AsType (SigningKey a)
AsSigningKey AsType StakePoolKey
AsStakePoolKey)        forall a b. a -> Either a b
Left
      , forall (c :: * -> Constraint) a b.
c a =>
AsType a -> (a -> b) -> FromSomeType c b
FromSomeType (forall a. AsType a -> AsType (SigningKey a)
AsSigningKey AsType GenesisDelegateKey
AsGenesisDelegateKey) (forall a b. a -> Either a b
Left forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall keyroleA keyroleB.
CastSigningKeyRole keyroleA keyroleB =>
SigningKey keyroleA -> SigningKey keyroleB
castSigningKey)
      , forall (c :: * -> Constraint) a b.
c a =>
AsType a -> (a -> b) -> FromSomeType c b
FromSomeType (forall a. AsType a -> AsType (SigningKey a)
AsSigningKey AsType GenesisDelegateExtendedKey
AsGenesisDelegateExtendedKey) forall a b. b -> Either a b
Right
      ]

    bech32PossibleBlockIssuers
      :: [FromSomeType SerialiseAsBech32
                       (Either (SigningKey StakePoolKey)
                               (SigningKey GenesisDelegateExtendedKey))]
    bech32PossibleBlockIssuers :: [FromSomeType
   SerialiseAsBech32
   (Either
      (SigningKey StakePoolKey) (SigningKey GenesisDelegateExtendedKey))]
bech32PossibleBlockIssuers =
      [forall (c :: * -> Constraint) a b.
c a =>
AsType a -> (a -> b) -> FromSomeType c b
FromSomeType (forall a. AsType a -> AsType (SigningKey a)
AsSigningKey AsType StakePoolKey
AsStakePoolKey) forall a b. a -> Either a b
Left]

-- | Read a cold verification key or file.
--
-- If a filepath is provided, it will be interpreted as a text envelope
-- formatted file.
readColdVerificationKeyOrFile
  :: ColdVerificationKeyOrFile
  -> IO (Either (FileError TextEnvelopeError) (VerificationKey StakePoolKey))
readColdVerificationKeyOrFile :: ColdVerificationKeyOrFile
-> IO
     (Either
        (FileError TextEnvelopeError) (VerificationKey StakePoolKey))
readColdVerificationKeyOrFile ColdVerificationKeyOrFile
coldVerKeyOrFile =
  case ColdVerificationKeyOrFile
coldVerKeyOrFile of
    ColdStakePoolVerificationKey VerificationKey StakePoolKey
vk -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a b. b -> Either a b
Right VerificationKey StakePoolKey
vk)
    ColdGenesisDelegateVerificationKey VerificationKey GenesisDelegateKey
vk ->
      forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a b. b -> Either a b
Right (forall keyroleA keyroleB.
CastVerificationKeyRole keyroleA keyroleB =>
VerificationKey keyroleA -> VerificationKey keyroleB
castVerificationKey VerificationKey GenesisDelegateKey
vk)
    ColdVerificationKeyFile (VerificationKeyFile String
fp) ->
      forall b.
[FromSomeType HasTextEnvelope b]
-> String -> IO (Either (FileError TextEnvelopeError) b)
readFileTextEnvelopeAnyOf
        [ forall (c :: * -> Constraint) a b.
c a =>
AsType a -> (a -> b) -> FromSomeType c b
FromSomeType (forall a. AsType a -> AsType (VerificationKey a)
AsVerificationKey AsType StakePoolKey
AsStakePoolKey) forall a. a -> a
id
        , forall (c :: * -> Constraint) a b.
c a =>
AsType a -> (a -> b) -> FromSomeType c b
FromSomeType (forall a. AsType a -> AsType (VerificationKey a)
AsVerificationKey AsType GenesisDelegateKey
AsGenesisDelegateKey) forall keyroleA keyroleB.
CastVerificationKeyRole keyroleA keyroleB =>
VerificationKey keyroleA -> VerificationKey keyroleB
castVerificationKey
        ]
        String
fp