{-# LANGUAGE GeneralisedNewtypeDeriving #-}

module Cardano.CLI.Byron.Key
  ( -- * Keys
    ByronKeyFailure(..)
  , NewSigningKeyFile(..)
  , NewVerificationKeyFile(..)
  , VerificationKeyFile(..)
  , prettyPublicKey
  , readByronSigningKey
  , readPaymentVerificationKey
  , renderByronKeyFailure
  , byronWitnessToVerKey
  )
where

import           Cardano.Prelude hiding (option, show, trace, (%))
import           Prelude (show)

import           Control.Monad.Trans.Except.Extra (firstExceptT, handleIOExceptT, hoistEither, left,
                     right)
import qualified Data.ByteString as SB
import qualified Data.ByteString.UTF8 as UTF8
import           Data.String (fromString)
import qualified Data.Text as T
import           Formatting (build, sformat, (%))

import           Cardano.Api.Byron

import qualified Cardano.Chain.Common as Common
import           Cardano.CLI.Helpers (textShow)
import           Cardano.CLI.Shelley.Commands (ByronKeyFormat (..))
import           Cardano.CLI.Types
import qualified Cardano.Crypto.Signing as Crypto


data ByronKeyFailure
  = ReadSigningKeyFailure !FilePath !Text
  | ReadVerificationKeyFailure !FilePath !Text
  | LegacySigningKeyDeserialisationFailed !FilePath
  | SigningKeyDeserialisationFailed !FilePath
  | VerificationKeyDeserialisationFailed !FilePath !Text
  | CannotMigrateFromNonLegacySigningKey !FilePath
  deriving Int -> ByronKeyFailure -> ShowS
[ByronKeyFailure] -> ShowS
ByronKeyFailure -> String
(Int -> ByronKeyFailure -> ShowS)
-> (ByronKeyFailure -> String)
-> ([ByronKeyFailure] -> ShowS)
-> Show ByronKeyFailure
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ByronKeyFailure] -> ShowS
$cshowList :: [ByronKeyFailure] -> ShowS
show :: ByronKeyFailure -> String
$cshow :: ByronKeyFailure -> String
showsPrec :: Int -> ByronKeyFailure -> ShowS
$cshowsPrec :: Int -> ByronKeyFailure -> ShowS
Show

renderByronKeyFailure :: ByronKeyFailure -> Text
renderByronKeyFailure :: ByronKeyFailure -> Text
renderByronKeyFailure ByronKeyFailure
err =
  case ByronKeyFailure
err of
    CannotMigrateFromNonLegacySigningKey String
fp ->
      Text
"Migrate from non-legacy Byron key unnecessary: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
forall a. Show a => a -> Text
textShow String
fp
    ReadSigningKeyFailure String
sKeyFp Text
readErr ->
      Text
"Error reading signing key at: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
forall a. Show a => a -> Text
textShow String
sKeyFp Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" Error: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
forall a. Show a => a -> Text
textShow Text
readErr
    ReadVerificationKeyFailure String
vKeyFp Text
readErr ->
      Text
"Error reading verification key at: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
forall a. Show a => a -> Text
textShow String
vKeyFp Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" Error: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
forall a. Show a => a -> Text
textShow Text
readErr
    LegacySigningKeyDeserialisationFailed String
fp ->
      Text
"Error attempting to deserialise a legacy signing key at: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
forall a. Show a => a -> Text
textShow String
fp
    SigningKeyDeserialisationFailed String
sKeyFp  ->
      Text
"Error deserialising signing key at: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
forall a. Show a => a -> Text
textShow String
sKeyFp
    VerificationKeyDeserialisationFailed String
vKeyFp Text
deSerError ->
      Text
"Error deserialising verification key at: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
forall a. Show a => a -> Text
textShow String
vKeyFp Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" Error: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
forall a. Show a => a -> Text
textShow Text
deSerError

newtype NewSigningKeyFile =
  NewSigningKeyFile FilePath
  deriving (NewSigningKeyFile -> NewSigningKeyFile -> Bool
(NewSigningKeyFile -> NewSigningKeyFile -> Bool)
-> (NewSigningKeyFile -> NewSigningKeyFile -> Bool)
-> Eq NewSigningKeyFile
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NewSigningKeyFile -> NewSigningKeyFile -> Bool
$c/= :: NewSigningKeyFile -> NewSigningKeyFile -> Bool
== :: NewSigningKeyFile -> NewSigningKeyFile -> Bool
$c== :: NewSigningKeyFile -> NewSigningKeyFile -> Bool
Eq, Eq NewSigningKeyFile
Eq NewSigningKeyFile
-> (NewSigningKeyFile -> NewSigningKeyFile -> Ordering)
-> (NewSigningKeyFile -> NewSigningKeyFile -> Bool)
-> (NewSigningKeyFile -> NewSigningKeyFile -> Bool)
-> (NewSigningKeyFile -> NewSigningKeyFile -> Bool)
-> (NewSigningKeyFile -> NewSigningKeyFile -> Bool)
-> (NewSigningKeyFile -> NewSigningKeyFile -> NewSigningKeyFile)
-> (NewSigningKeyFile -> NewSigningKeyFile -> NewSigningKeyFile)
-> Ord NewSigningKeyFile
NewSigningKeyFile -> NewSigningKeyFile -> Bool
NewSigningKeyFile -> NewSigningKeyFile -> Ordering
NewSigningKeyFile -> NewSigningKeyFile -> NewSigningKeyFile
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: NewSigningKeyFile -> NewSigningKeyFile -> NewSigningKeyFile
$cmin :: NewSigningKeyFile -> NewSigningKeyFile -> NewSigningKeyFile
max :: NewSigningKeyFile -> NewSigningKeyFile -> NewSigningKeyFile
$cmax :: NewSigningKeyFile -> NewSigningKeyFile -> NewSigningKeyFile
>= :: NewSigningKeyFile -> NewSigningKeyFile -> Bool
$c>= :: NewSigningKeyFile -> NewSigningKeyFile -> Bool
> :: NewSigningKeyFile -> NewSigningKeyFile -> Bool
$c> :: NewSigningKeyFile -> NewSigningKeyFile -> Bool
<= :: NewSigningKeyFile -> NewSigningKeyFile -> Bool
$c<= :: NewSigningKeyFile -> NewSigningKeyFile -> Bool
< :: NewSigningKeyFile -> NewSigningKeyFile -> Bool
$c< :: NewSigningKeyFile -> NewSigningKeyFile -> Bool
compare :: NewSigningKeyFile -> NewSigningKeyFile -> Ordering
$ccompare :: NewSigningKeyFile -> NewSigningKeyFile -> Ordering
$cp1Ord :: Eq NewSigningKeyFile
Ord, Int -> NewSigningKeyFile -> ShowS
[NewSigningKeyFile] -> ShowS
NewSigningKeyFile -> String
(Int -> NewSigningKeyFile -> ShowS)
-> (NewSigningKeyFile -> String)
-> ([NewSigningKeyFile] -> ShowS)
-> Show NewSigningKeyFile
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NewSigningKeyFile] -> ShowS
$cshowList :: [NewSigningKeyFile] -> ShowS
show :: NewSigningKeyFile -> String
$cshow :: NewSigningKeyFile -> String
showsPrec :: Int -> NewSigningKeyFile -> ShowS
$cshowsPrec :: Int -> NewSigningKeyFile -> ShowS
Show, String -> NewSigningKeyFile
(String -> NewSigningKeyFile) -> IsString NewSigningKeyFile
forall a. (String -> a) -> IsString a
fromString :: String -> NewSigningKeyFile
$cfromString :: String -> NewSigningKeyFile
IsString)

newtype NewVerificationKeyFile =
  NewVerificationKeyFile FilePath
   deriving (NewVerificationKeyFile -> NewVerificationKeyFile -> Bool
(NewVerificationKeyFile -> NewVerificationKeyFile -> Bool)
-> (NewVerificationKeyFile -> NewVerificationKeyFile -> Bool)
-> Eq NewVerificationKeyFile
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NewVerificationKeyFile -> NewVerificationKeyFile -> Bool
$c/= :: NewVerificationKeyFile -> NewVerificationKeyFile -> Bool
== :: NewVerificationKeyFile -> NewVerificationKeyFile -> Bool
$c== :: NewVerificationKeyFile -> NewVerificationKeyFile -> Bool
Eq, Eq NewVerificationKeyFile
Eq NewVerificationKeyFile
-> (NewVerificationKeyFile -> NewVerificationKeyFile -> Ordering)
-> (NewVerificationKeyFile -> NewVerificationKeyFile -> Bool)
-> (NewVerificationKeyFile -> NewVerificationKeyFile -> Bool)
-> (NewVerificationKeyFile -> NewVerificationKeyFile -> Bool)
-> (NewVerificationKeyFile -> NewVerificationKeyFile -> Bool)
-> (NewVerificationKeyFile
    -> NewVerificationKeyFile -> NewVerificationKeyFile)
-> (NewVerificationKeyFile
    -> NewVerificationKeyFile -> NewVerificationKeyFile)
-> Ord NewVerificationKeyFile
NewVerificationKeyFile -> NewVerificationKeyFile -> Bool
NewVerificationKeyFile -> NewVerificationKeyFile -> Ordering
NewVerificationKeyFile
-> NewVerificationKeyFile -> NewVerificationKeyFile
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: NewVerificationKeyFile
-> NewVerificationKeyFile -> NewVerificationKeyFile
$cmin :: NewVerificationKeyFile
-> NewVerificationKeyFile -> NewVerificationKeyFile
max :: NewVerificationKeyFile
-> NewVerificationKeyFile -> NewVerificationKeyFile
$cmax :: NewVerificationKeyFile
-> NewVerificationKeyFile -> NewVerificationKeyFile
>= :: NewVerificationKeyFile -> NewVerificationKeyFile -> Bool
$c>= :: NewVerificationKeyFile -> NewVerificationKeyFile -> Bool
> :: NewVerificationKeyFile -> NewVerificationKeyFile -> Bool
$c> :: NewVerificationKeyFile -> NewVerificationKeyFile -> Bool
<= :: NewVerificationKeyFile -> NewVerificationKeyFile -> Bool
$c<= :: NewVerificationKeyFile -> NewVerificationKeyFile -> Bool
< :: NewVerificationKeyFile -> NewVerificationKeyFile -> Bool
$c< :: NewVerificationKeyFile -> NewVerificationKeyFile -> Bool
compare :: NewVerificationKeyFile -> NewVerificationKeyFile -> Ordering
$ccompare :: NewVerificationKeyFile -> NewVerificationKeyFile -> Ordering
$cp1Ord :: Eq NewVerificationKeyFile
Ord, Int -> NewVerificationKeyFile -> ShowS
[NewVerificationKeyFile] -> ShowS
NewVerificationKeyFile -> String
(Int -> NewVerificationKeyFile -> ShowS)
-> (NewVerificationKeyFile -> String)
-> ([NewVerificationKeyFile] -> ShowS)
-> Show NewVerificationKeyFile
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NewVerificationKeyFile] -> ShowS
$cshowList :: [NewVerificationKeyFile] -> ShowS
show :: NewVerificationKeyFile -> String
$cshow :: NewVerificationKeyFile -> String
showsPrec :: Int -> NewVerificationKeyFile -> ShowS
$cshowsPrec :: Int -> NewVerificationKeyFile -> ShowS
Show, String -> NewVerificationKeyFile
(String -> NewVerificationKeyFile)
-> IsString NewVerificationKeyFile
forall a. (String -> a) -> IsString a
fromString :: String -> NewVerificationKeyFile
$cfromString :: String -> NewVerificationKeyFile
IsString)

-- | Print some invariant properties of a public key:
--   its hash and formatted view.
prettyPublicKey :: VerificationKey ByronKey-> Text
prettyPublicKey :: VerificationKey ByronKey -> Text
prettyPublicKey (ByronVerificationKey vk) =
  Format
  Text
  (AddressHash VerificationKey
   -> VerificationKey -> VerificationKey -> Text)
-> AddressHash VerificationKey
-> VerificationKey
-> VerificationKey
-> Text
forall a. Format Text a -> a
sformat (  Format
  (AddressHash VerificationKey
   -> VerificationKey -> VerificationKey -> Text)
  (AddressHash VerificationKey
   -> VerificationKey -> VerificationKey -> Text)
"    public key hash: "Format
  (AddressHash VerificationKey
   -> VerificationKey -> VerificationKey -> Text)
  (AddressHash VerificationKey
   -> VerificationKey -> VerificationKey -> Text)
-> Format
     Text
     (AddressHash VerificationKey
      -> VerificationKey -> VerificationKey -> Text)
-> Format
     Text
     (AddressHash VerificationKey
      -> VerificationKey -> VerificationKey -> Text)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Format
  (VerificationKey -> VerificationKey -> Text)
  (AddressHash VerificationKey
   -> VerificationKey -> VerificationKey -> Text)
forall a r. Buildable a => Format r (a -> r)
build Format
  (VerificationKey -> VerificationKey -> Text)
  (AddressHash VerificationKey
   -> VerificationKey -> VerificationKey -> Text)
-> Format Text (VerificationKey -> VerificationKey -> Text)
-> Format
     Text
     (AddressHash VerificationKey
      -> VerificationKey -> VerificationKey -> Text)
forall r a r'. Format r a -> Format r' r -> Format r' a
%
           Format
  (VerificationKey -> VerificationKey -> Text)
  (VerificationKey -> VerificationKey -> Text)
"\npublic key (base64): "Format
  (VerificationKey -> VerificationKey -> Text)
  (VerificationKey -> VerificationKey -> Text)
-> Format Text (VerificationKey -> VerificationKey -> Text)
-> Format Text (VerificationKey -> VerificationKey -> Text)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Format
  (VerificationKey -> Text)
  (VerificationKey -> VerificationKey -> Text)
forall r. Format r (VerificationKey -> r)
Crypto.fullVerificationKeyF Format
  (VerificationKey -> Text)
  (VerificationKey -> VerificationKey -> Text)
-> Format Text (VerificationKey -> Text)
-> Format Text (VerificationKey -> VerificationKey -> Text)
forall r a r'. Format r a -> Format r' r -> Format r' a
%
           Format (VerificationKey -> Text) (VerificationKey -> Text)
"\n   public key (hex): "Format (VerificationKey -> Text) (VerificationKey -> Text)
-> Format Text (VerificationKey -> Text)
-> Format Text (VerificationKey -> Text)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Format Text (VerificationKey -> Text)
forall r. Format r (VerificationKey -> r)
Crypto.fullVerificationKeyHexF)
    (VerificationKey -> AddressHash VerificationKey
forall a. ToCBOR a => a -> AddressHash a
Common.addressHash VerificationKey
vk) VerificationKey
vk VerificationKey
vk

byronWitnessToVerKey :: SomeByronSigningKey -> VerificationKey ByronKey
byronWitnessToVerKey :: SomeByronSigningKey -> VerificationKey ByronKey
byronWitnessToVerKey (AByronSigningKeyLegacy SigningKey ByronKeyLegacy
sKeyLeg) = VerificationKey ByronKeyLegacy -> VerificationKey ByronKey
forall keyroleA keyroleB.
CastVerificationKeyRole keyroleA keyroleB =>
VerificationKey keyroleA -> VerificationKey keyroleB
castVerificationKey (VerificationKey ByronKeyLegacy -> VerificationKey ByronKey)
-> VerificationKey ByronKeyLegacy -> VerificationKey ByronKey
forall a b. (a -> b) -> a -> b
$ SigningKey ByronKeyLegacy -> VerificationKey ByronKeyLegacy
forall keyrole.
Key keyrole =>
SigningKey keyrole -> VerificationKey keyrole
getVerificationKey SigningKey ByronKeyLegacy
sKeyLeg
byronWitnessToVerKey (AByronSigningKey SigningKey ByronKey
sKeyNonLeg) = SigningKey ByronKey -> VerificationKey ByronKey
forall keyrole.
Key keyrole =>
SigningKey keyrole -> VerificationKey keyrole
getVerificationKey SigningKey ByronKey
sKeyNonLeg

-- TODO:  we need to support password-protected secrets.
-- | Read signing key from a file.
readByronSigningKey :: ByronKeyFormat -> SigningKeyFile -> ExceptT ByronKeyFailure IO SomeByronSigningKey
readByronSigningKey :: ByronKeyFormat
-> SigningKeyFile -> ExceptT ByronKeyFailure IO SomeByronSigningKey
readByronSigningKey ByronKeyFormat
bKeyFormat (SigningKeyFile String
fp) = do
  ByteString
sK <- (IOException -> ByronKeyFailure)
-> IO ByteString -> ExceptT ByronKeyFailure IO ByteString
forall (m :: * -> *) x a.
MonadIO m =>
(IOException -> x) -> IO a -> ExceptT x m a
handleIOExceptT (String -> Text -> ByronKeyFailure
ReadSigningKeyFailure String
fp (Text -> ByronKeyFailure)
-> (IOException -> Text) -> IOException -> ByronKeyFailure
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. String -> Text
T.pack (String -> Text) -> (IOException -> String) -> IOException -> Text
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. IOException -> String
forall e. Exception e => e -> String
displayException) (IO ByteString -> ExceptT ByronKeyFailure IO ByteString)
-> IO ByteString -> ExceptT ByronKeyFailure IO ByteString
forall a b. (a -> b) -> a -> b
$ String -> IO ByteString
SB.readFile String
fp
  case ByronKeyFormat
bKeyFormat of
    ByronKeyFormat
LegacyByronKeyFormat ->
      case AsType (SigningKey ByronKeyLegacy)
-> ByteString -> Maybe (SigningKey ByronKeyLegacy)
forall a.
SerialiseAsRawBytes a =>
AsType a -> ByteString -> Maybe a
deserialiseFromRawBytes (AsType ByronKeyLegacy -> AsType (SigningKey ByronKeyLegacy)
forall a. AsType a -> AsType (SigningKey a)
AsSigningKey AsType ByronKeyLegacy
AsByronKeyLegacy) ByteString
sK of
        Just SigningKey ByronKeyLegacy
legKey -> SomeByronSigningKey
-> ExceptT ByronKeyFailure IO SomeByronSigningKey
forall (m :: * -> *) a x. Monad m => a -> ExceptT x m a
right (SomeByronSigningKey
 -> ExceptT ByronKeyFailure IO SomeByronSigningKey)
-> SomeByronSigningKey
-> ExceptT ByronKeyFailure IO SomeByronSigningKey
forall a b. (a -> b) -> a -> b
$ SigningKey ByronKeyLegacy -> SomeByronSigningKey
AByronSigningKeyLegacy SigningKey ByronKeyLegacy
legKey
        Maybe (SigningKey ByronKeyLegacy)
Nothing -> ByronKeyFailure -> ExceptT ByronKeyFailure IO SomeByronSigningKey
forall (m :: * -> *) x a. Monad m => x -> ExceptT x m a
left (ByronKeyFailure -> ExceptT ByronKeyFailure IO SomeByronSigningKey)
-> ByronKeyFailure
-> ExceptT ByronKeyFailure IO SomeByronSigningKey
forall a b. (a -> b) -> a -> b
$ String -> ByronKeyFailure
LegacySigningKeyDeserialisationFailed String
fp
    ByronKeyFormat
NonLegacyByronKeyFormat ->
      case AsType (SigningKey ByronKey)
-> ByteString -> Maybe (SigningKey ByronKey)
forall a.
SerialiseAsRawBytes a =>
AsType a -> ByteString -> Maybe a
deserialiseFromRawBytes (AsType ByronKey -> AsType (SigningKey ByronKey)
forall a. AsType a -> AsType (SigningKey a)
AsSigningKey AsType ByronKey
AsByronKey) ByteString
sK of
        Just SigningKey ByronKey
nonLegSKey -> SomeByronSigningKey
-> ExceptT ByronKeyFailure IO SomeByronSigningKey
forall (m :: * -> *) a x. Monad m => a -> ExceptT x m a
right (SomeByronSigningKey
 -> ExceptT ByronKeyFailure IO SomeByronSigningKey)
-> SomeByronSigningKey
-> ExceptT ByronKeyFailure IO SomeByronSigningKey
forall a b. (a -> b) -> a -> b
$ SigningKey ByronKey -> SomeByronSigningKey
AByronSigningKey SigningKey ByronKey
nonLegSKey
        Maybe (SigningKey ByronKey)
Nothing -> ByronKeyFailure -> ExceptT ByronKeyFailure IO SomeByronSigningKey
forall (m :: * -> *) x a. Monad m => x -> ExceptT x m a
left (ByronKeyFailure -> ExceptT ByronKeyFailure IO SomeByronSigningKey)
-> ByronKeyFailure
-> ExceptT ByronKeyFailure IO SomeByronSigningKey
forall a b. (a -> b) -> a -> b
$ String -> ByronKeyFailure
SigningKeyDeserialisationFailed String
fp

-- | Read verification key from a file.  Throw an error if the file can't be read
-- or the key fails to deserialise.
readPaymentVerificationKey :: VerificationKeyFile -> ExceptT ByronKeyFailure IO Crypto.VerificationKey
readPaymentVerificationKey :: VerificationKeyFile -> ExceptT ByronKeyFailure IO VerificationKey
readPaymentVerificationKey (VerificationKeyFile String
fp) = do
  ByteString
vkB <- (IOException -> ByronKeyFailure)
-> IO ByteString -> ExceptT ByronKeyFailure IO ByteString
forall (m :: * -> *) x a.
MonadIO m =>
(IOException -> x) -> IO a -> ExceptT x m a
handleIOExceptT (String -> Text -> ByronKeyFailure
ReadVerificationKeyFailure String
fp (Text -> ByronKeyFailure)
-> (IOException -> Text) -> IOException -> ByronKeyFailure
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. String -> Text
T.pack (String -> Text) -> (IOException -> String) -> IOException -> Text
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. IOException -> String
forall e. Exception e => e -> String
displayException) (String -> IO ByteString
SB.readFile String
fp)
  -- Verification Key
  let eVk :: ExceptT VerificationKeyParseError IO VerificationKey
eVk = Either VerificationKeyParseError VerificationKey
-> ExceptT VerificationKeyParseError IO VerificationKey
forall (m :: * -> *) x a. Monad m => Either x a -> ExceptT x m a
hoistEither (Either VerificationKeyParseError VerificationKey
 -> ExceptT VerificationKeyParseError IO VerificationKey)
-> (String -> Either VerificationKeyParseError VerificationKey)
-> String
-> ExceptT VerificationKeyParseError IO VerificationKey
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Text -> Either VerificationKeyParseError VerificationKey
Crypto.parseFullVerificationKey (Text -> Either VerificationKeyParseError VerificationKey)
-> (String -> Text)
-> String
-> Either VerificationKeyParseError VerificationKey
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. String -> Text
forall a. IsString a => String -> a
fromString (String -> ExceptT VerificationKeyParseError IO VerificationKey)
-> String -> ExceptT VerificationKeyParseError IO VerificationKey
forall a b. (a -> b) -> a -> b
$ ByteString -> String
UTF8.toString ByteString
vkB
  -- Convert error to 'CliError'
  (VerificationKeyParseError -> ByronKeyFailure)
-> ExceptT VerificationKeyParseError IO VerificationKey
-> ExceptT ByronKeyFailure IO VerificationKey
forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT (String -> Text -> ByronKeyFailure
VerificationKeyDeserialisationFailed String
fp (Text -> ByronKeyFailure)
-> (VerificationKeyParseError -> Text)
-> VerificationKeyParseError
-> ByronKeyFailure
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. String -> Text
T.pack (String -> Text)
-> (VerificationKeyParseError -> String)
-> VerificationKeyParseError
-> Text
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. VerificationKeyParseError -> String
forall a. Show a => a -> String
show) ExceptT VerificationKeyParseError IO VerificationKey
eVk