{-# LANGUAGE FlexibleContexts           #-}
{-# LANGUAGE FlexibleInstances          #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE TypeSynonymInstances       #-}
{-# LANGUAGE UndecidableInstances       #-}

module Cardano.Chain.Common.KeyHash
  ( KeyHash (..)
  , hashKey
  )
where

import Cardano.Prelude

import Formatting (formatToString)
import Formatting.Buildable (Buildable)
import NoThunks.Class (NoThunks (..))
import Text.JSON.Canonical
  (FromObjectKey(..), JSValue(..), ToObjectKey(..), toJSString)

import Cardano.Binary (FromCBOR, ToCBOR)
import Cardano.Chain.Common.AddressHash
import Cardano.Crypto (decodeAbstractHash, hashHexF)
import Cardano.Crypto.Signing (VerificationKey)


-- | A 'KeyHash' refers to a 'VerificationKey'
newtype KeyHash = KeyHash
  { KeyHash -> AddressHash VerificationKey
unKeyHash :: AddressHash VerificationKey
  } deriving ( KeyHash -> KeyHash -> Bool
(KeyHash -> KeyHash -> Bool)
-> (KeyHash -> KeyHash -> Bool) -> Eq KeyHash
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: KeyHash -> KeyHash -> Bool
$c/= :: KeyHash -> KeyHash -> Bool
== :: KeyHash -> KeyHash -> Bool
$c== :: KeyHash -> KeyHash -> Bool
Eq
             , Eq KeyHash
Eq KeyHash
-> (KeyHash -> KeyHash -> Ordering)
-> (KeyHash -> KeyHash -> Bool)
-> (KeyHash -> KeyHash -> Bool)
-> (KeyHash -> KeyHash -> Bool)
-> (KeyHash -> KeyHash -> Bool)
-> (KeyHash -> KeyHash -> KeyHash)
-> (KeyHash -> KeyHash -> KeyHash)
-> Ord KeyHash
KeyHash -> KeyHash -> Bool
KeyHash -> KeyHash -> Ordering
KeyHash -> KeyHash -> KeyHash
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 :: KeyHash -> KeyHash -> KeyHash
$cmin :: KeyHash -> KeyHash -> KeyHash
max :: KeyHash -> KeyHash -> KeyHash
$cmax :: KeyHash -> KeyHash -> KeyHash
>= :: KeyHash -> KeyHash -> Bool
$c>= :: KeyHash -> KeyHash -> Bool
> :: KeyHash -> KeyHash -> Bool
$c> :: KeyHash -> KeyHash -> Bool
<= :: KeyHash -> KeyHash -> Bool
$c<= :: KeyHash -> KeyHash -> Bool
< :: KeyHash -> KeyHash -> Bool
$c< :: KeyHash -> KeyHash -> Bool
compare :: KeyHash -> KeyHash -> Ordering
$ccompare :: KeyHash -> KeyHash -> Ordering
$cp1Ord :: Eq KeyHash
Ord
             , Int -> KeyHash -> ShowS
[KeyHash] -> ShowS
KeyHash -> String
(Int -> KeyHash -> ShowS)
-> (KeyHash -> String) -> ([KeyHash] -> ShowS) -> Show KeyHash
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [KeyHash] -> ShowS
$cshowList :: [KeyHash] -> ShowS
show :: KeyHash -> String
$cshow :: KeyHash -> String
showsPrec :: Int -> KeyHash -> ShowS
$cshowsPrec :: Int -> KeyHash -> ShowS
Show
             , KeyHash -> ()
(KeyHash -> ()) -> NFData KeyHash
forall a. (a -> ()) -> NFData a
rnf :: KeyHash -> ()
$crnf :: KeyHash -> ()
NFData
             , KeyHash -> Builder
(KeyHash -> Builder) -> Buildable KeyHash
forall p. (p -> Builder) -> Buildable p
build :: KeyHash -> Builder
$cbuild :: KeyHash -> Builder
Buildable
             , Typeable KeyHash
Decoder s KeyHash
Typeable KeyHash
-> (forall s. Decoder s KeyHash)
-> (Proxy KeyHash -> Text)
-> FromCBOR KeyHash
Proxy KeyHash -> Text
forall s. Decoder s KeyHash
forall a.
Typeable a
-> (forall s. Decoder s a) -> (Proxy a -> Text) -> FromCBOR a
label :: Proxy KeyHash -> Text
$clabel :: Proxy KeyHash -> Text
fromCBOR :: Decoder s KeyHash
$cfromCBOR :: forall s. Decoder s KeyHash
$cp1FromCBOR :: Typeable KeyHash
FromCBOR
             , Typeable KeyHash
Typeable KeyHash
-> (KeyHash -> Encoding)
-> ((forall t. ToCBOR t => Proxy t -> Size)
    -> Proxy KeyHash -> Size)
-> ((forall t. ToCBOR t => Proxy t -> Size)
    -> Proxy [KeyHash] -> Size)
-> ToCBOR KeyHash
KeyHash -> Encoding
(forall t. ToCBOR t => Proxy t -> Size) -> Proxy [KeyHash] -> Size
(forall t. ToCBOR t => Proxy t -> Size) -> Proxy KeyHash -> Size
forall a.
Typeable a
-> (a -> Encoding)
-> ((forall t. ToCBOR t => Proxy t -> Size) -> Proxy a -> Size)
-> ((forall t. ToCBOR t => Proxy t -> Size) -> Proxy [a] -> Size)
-> ToCBOR a
encodedListSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size) -> Proxy [KeyHash] -> Size
$cencodedListSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size) -> Proxy [KeyHash] -> Size
encodedSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size) -> Proxy KeyHash -> Size
$cencodedSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size) -> Proxy KeyHash -> Size
toCBOR :: KeyHash -> Encoding
$ctoCBOR :: KeyHash -> Encoding
$cp1ToCBOR :: Typeable KeyHash
ToCBOR
             , KeyHash -> Int
(KeyHash -> Int) -> HeapWords KeyHash
forall a. (a -> Int) -> HeapWords a
heapWords :: KeyHash -> Int
$cheapWords :: KeyHash -> Int
HeapWords
             , Context -> KeyHash -> IO (Maybe ThunkInfo)
Proxy KeyHash -> String
(Context -> KeyHash -> IO (Maybe ThunkInfo))
-> (Context -> KeyHash -> IO (Maybe ThunkInfo))
-> (Proxy KeyHash -> String)
-> NoThunks KeyHash
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy KeyHash -> String
$cshowTypeOf :: Proxy KeyHash -> String
wNoThunks :: Context -> KeyHash -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> KeyHash -> IO (Maybe ThunkInfo)
noThunks :: Context -> KeyHash -> IO (Maybe ThunkInfo)
$cnoThunks :: Context -> KeyHash -> IO (Maybe ThunkInfo)
NoThunks
             )

instance Monad m => ToObjectKey m KeyHash where
  toObjectKey :: KeyHash -> m JSString
toObjectKey = JSString -> m JSString
forall (f :: * -> *) a. Applicative f => a -> f a
pure (JSString -> m JSString)
-> (KeyHash -> JSString) -> KeyHash -> m JSString
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. String -> JSString
toJSString (String -> JSString) -> (KeyHash -> String) -> KeyHash -> JSString
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Format String (AddressHash VerificationKey -> String)
-> AddressHash VerificationKey -> String
forall a. Format String a -> a
formatToString Format String (AddressHash VerificationKey -> String)
forall r algo a. Format r (AbstractHash algo a -> r)
hashHexF (AddressHash VerificationKey -> String)
-> (KeyHash -> AddressHash VerificationKey) -> KeyHash -> String
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. KeyHash -> AddressHash VerificationKey
unKeyHash

instance MonadError SchemaError m => FromObjectKey m KeyHash where
  fromObjectKey :: JSString -> m (Maybe KeyHash)
fromObjectKey = (AddressHash VerificationKey -> Maybe KeyHash)
-> m (AddressHash VerificationKey) -> m (Maybe KeyHash)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (KeyHash -> Maybe KeyHash
forall a. a -> Maybe a
Just (KeyHash -> Maybe KeyHash)
-> (AddressHash VerificationKey -> KeyHash)
-> AddressHash VerificationKey
-> Maybe KeyHash
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. AddressHash VerificationKey -> KeyHash
KeyHash)
    (m (AddressHash VerificationKey) -> m (Maybe KeyHash))
-> (JSString -> m (AddressHash VerificationKey))
-> JSString
-> m (Maybe KeyHash)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Text -> Either Text (AddressHash VerificationKey))
-> JSValue -> m (AddressHash VerificationKey)
forall a (m :: * -> *) e.
(Typeable a, ReportSchemaErrors m, Buildable e) =>
(Text -> Either e a) -> JSValue -> m a
parseJSString Text -> Either Text (AddressHash VerificationKey)
forall algo a.
HashAlgorithm algo =>
Text -> Either Text (AbstractHash algo a)
decodeAbstractHash
    (JSValue -> m (AddressHash VerificationKey))
-> (JSString -> JSValue)
-> JSString
-> m (AddressHash VerificationKey)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. JSString -> JSValue
JSString

hashKey :: VerificationKey -> KeyHash
hashKey :: VerificationKey -> KeyHash
hashKey = AddressHash VerificationKey -> KeyHash
KeyHash (AddressHash VerificationKey -> KeyHash)
-> (VerificationKey -> AddressHash VerificationKey)
-> VerificationKey
-> KeyHash
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. VerificationKey -> AddressHash VerificationKey
forall a. ToCBOR a => a -> AddressHash a
addressHash