{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GeneralisedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}

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

import           Cardano.Api.Byron

import           Cardano.CLI.Types.Common
import qualified Cardano.Crypto.Signing as Crypto

import           Control.Exception (Exception (..))
import qualified Data.ByteString as SB
import qualified Data.ByteString.UTF8 as UTF8
import           Data.String (IsString, fromString)
import           Data.Text (Text)
import qualified Data.Text as T
import           Formatting (build, sformat, (%))

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
$cshowsPrec :: Int -> ByronKeyFailure -> ShowS
showsPrec :: Int -> ByronKeyFailure -> ShowS
$cshow :: ByronKeyFailure -> String
show :: ByronKeyFailure -> String
$cshowList :: [ByronKeyFailure] -> ShowS
showList :: [ByronKeyFailure] -> ShowS
Show

renderByronKeyFailure :: ByronKeyFailure -> Doc ann
renderByronKeyFailure :: forall ann. ByronKeyFailure -> Doc ann
renderByronKeyFailure = \case
  CannotMigrateFromNonLegacySigningKey String
fp ->
    Doc ann
"Migrate from non-legacy Byron key unnecessary: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> String -> Doc ann
forall a ann. Show a => a -> Doc ann
pshow String
fp
  ReadSigningKeyFailure String
sKeyFp Text
readErr ->
    Doc ann
"Error reading signing key at: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> String -> Doc ann
forall a ann. Show a => a -> Doc ann
pshow String
sKeyFp Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
" Error: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Text -> Doc ann
forall a ann. Show a => a -> Doc ann
pshow Text
readErr
  ReadVerificationKeyFailure String
vKeyFp Text
readErr ->
    Doc ann
"Error reading verification key at: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> String -> Doc ann
forall a ann. Show a => a -> Doc ann
pshow String
vKeyFp Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
" Error: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Text -> Doc ann
forall a ann. Show a => a -> Doc ann
pshow Text
readErr
  LegacySigningKeyDeserialisationFailed String
fp ->
    Doc ann
"Error attempting to deserialise a legacy signing key at: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> String -> Doc ann
forall a ann. Show a => a -> Doc ann
pshow String
fp
  SigningKeyDeserialisationFailed String
sKeyFp ->
    Doc ann
"Error deserialising signing key at: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> String -> Doc ann
forall a ann. Show a => a -> Doc ann
pshow String
sKeyFp
  VerificationKeyDeserialisationFailed String
vKeyFp Text
deSerError ->
    Doc ann
"Error deserialising verification key at: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> String -> Doc ann
forall a ann. Show a => a -> Doc ann
pshow String
vKeyFp Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
" Error: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Text -> Doc ann
forall a ann. Show a => a -> Doc ann
pshow 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
$c== :: NewSigningKeyFile -> NewSigningKeyFile -> Bool
== :: NewSigningKeyFile -> NewSigningKeyFile -> Bool
$c/= :: NewSigningKeyFile -> NewSigningKeyFile -> Bool
/= :: 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
$ccompare :: NewSigningKeyFile -> NewSigningKeyFile -> Ordering
compare :: NewSigningKeyFile -> NewSigningKeyFile -> Ordering
$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
>= :: NewSigningKeyFile -> NewSigningKeyFile -> Bool
$cmax :: NewSigningKeyFile -> NewSigningKeyFile -> NewSigningKeyFile
max :: NewSigningKeyFile -> NewSigningKeyFile -> NewSigningKeyFile
$cmin :: NewSigningKeyFile -> NewSigningKeyFile -> NewSigningKeyFile
min :: NewSigningKeyFile -> NewSigningKeyFile -> 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
$cshowsPrec :: Int -> NewSigningKeyFile -> ShowS
showsPrec :: Int -> NewSigningKeyFile -> ShowS
$cshow :: NewSigningKeyFile -> String
show :: NewSigningKeyFile -> String
$cshowList :: [NewSigningKeyFile] -> ShowS
showList :: [NewSigningKeyFile] -> ShowS
Show, String -> NewSigningKeyFile
(String -> NewSigningKeyFile) -> IsString NewSigningKeyFile
forall a. (String -> a) -> IsString a
$cfromString :: String -> NewSigningKeyFile
fromString :: 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
$c== :: NewVerificationKeyFile -> NewVerificationKeyFile -> Bool
== :: NewVerificationKeyFile -> NewVerificationKeyFile -> Bool
$c/= :: NewVerificationKeyFile -> NewVerificationKeyFile -> Bool
/= :: 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
$ccompare :: NewVerificationKeyFile -> NewVerificationKeyFile -> Ordering
compare :: NewVerificationKeyFile -> NewVerificationKeyFile -> Ordering
$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
>= :: NewVerificationKeyFile -> NewVerificationKeyFile -> Bool
$cmax :: NewVerificationKeyFile
-> NewVerificationKeyFile -> NewVerificationKeyFile
max :: NewVerificationKeyFile
-> NewVerificationKeyFile -> NewVerificationKeyFile
$cmin :: NewVerificationKeyFile
-> NewVerificationKeyFile -> NewVerificationKeyFile
min :: NewVerificationKeyFile
-> NewVerificationKeyFile -> 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
$cshowsPrec :: Int -> NewVerificationKeyFile -> ShowS
showsPrec :: Int -> NewVerificationKeyFile -> ShowS
$cshow :: NewVerificationKeyFile -> String
show :: NewVerificationKeyFile -> String
$cshowList :: [NewVerificationKeyFile] -> ShowS
showList :: [NewVerificationKeyFile] -> ShowS
Show, String -> NewVerificationKeyFile
(String -> NewVerificationKeyFile)
-> IsString NewVerificationKeyFile
forall a. (String -> a) -> IsString a
$cfromString :: String -> NewVerificationKeyFile
fromString :: 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 VerificationKey
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. EncCBOR a => a -> AddressHash a
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, HasTypeProxy keyrole) =>
SigningKey keyrole -> VerificationKey keyrole
getVerificationKey SigningKey ByronKeyLegacy
sKeyLeg
byronWitnessToVerKey (AByronSigningKey SigningKey ByronKey
sKeyNonLeg) = SigningKey ByronKey -> VerificationKey ByronKey
forall keyrole.
(Key keyrole, HasTypeProxy 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 In -> ExceptT ByronKeyFailure IO SomeByronSigningKey
readByronSigningKey :: ByronKeyFormat
-> SigningKeyFile 'In
-> ExceptT ByronKeyFailure IO SomeByronSigningKey
readByronSigningKey ByronKeyFormat
bKeyFormat (File 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 b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack (String -> Text) -> (IOException -> String) -> IOException -> Text
forall b c a. (b -> c) -> (a -> b) -> 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
-> Either SerialiseAsRawBytesError (SigningKey ByronKeyLegacy)
forall a.
SerialiseAsRawBytes a =>
AsType a -> ByteString -> Either SerialiseAsRawBytesError a
deserialiseFromRawBytes (AsType ByronKeyLegacy -> AsType (SigningKey ByronKeyLegacy)
forall a. AsType a -> AsType (SigningKey a)
AsSigningKey AsType ByronKeyLegacy
AsByronKeyLegacy) ByteString
sK of
        Right 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
        Left SerialiseAsRawBytesError
_ -> 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
-> Either SerialiseAsRawBytesError (SigningKey ByronKey)
forall a.
SerialiseAsRawBytes a =>
AsType a -> ByteString -> Either SerialiseAsRawBytesError a
deserialiseFromRawBytes (AsType ByronKey -> AsType (SigningKey ByronKey)
forall a. AsType a -> AsType (SigningKey a)
AsSigningKey AsType ByronKey
AsByronKey) ByteString
sK of
        Right 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
        Left SerialiseAsRawBytesError
_ -> 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 In -> ExceptT ByronKeyFailure IO Crypto.VerificationKey
readPaymentVerificationKey :: VerificationKeyFile 'In
-> ExceptT ByronKeyFailure IO VerificationKey
readPaymentVerificationKey (File 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 b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack (String -> Text) -> (IOException -> String) -> IOException -> Text
forall b c a. (b -> c) -> (a -> b) -> 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 b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either VerificationKeyParseError VerificationKey
Crypto.parseFullVerificationKey (Text -> Either VerificationKeyParseError VerificationKey)
-> (String -> Text)
-> String
-> Either VerificationKeyParseError VerificationKey
forall b c a. (b -> c) -> (a -> b) -> 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 b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack (String -> Text)
-> (VerificationKeyParseError -> String)
-> VerificationKeyParseError
-> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VerificationKeyParseError -> String
forall a. Show a => a -> String
show) ExceptT VerificationKeyParseError IO VerificationKey
eVk