module Hydra.Data.Party where

import Hydra.Prelude hiding (init)

import Data.ByteString qualified as BS
import PlutusTx qualified
import PlutusTx.Builtins (BuiltinByteString, fromBuiltin, toBuiltin)
import PlutusTx.IsData
import PlutusTx.Prelude qualified as PlutusTx
import Test.QuickCheck (vector)

-- | On-chain representation of a Hydra party.
--
-- NOTE: This roughly corresponds to the 'Party' in 'hydra-node', but is
-- simplified to allow usage of this type in plutus-tx. If we would use the
-- complex type directly, which is based on 'cardano-crypto-class', we would get
-- errors like "Error: Unsupported feature: Kind: GHC.Types.Nat".
--
-- The data constructor should not be used to construct this value as it would
-- always come from off-chain code via 'partyFromVerificationKeyBytes'.
newtype Party = UnsafeParty {Party -> BuiltinByteString
vkey :: BuiltinByteString}
  deriving stock (Party -> Party -> Bool
(Party -> Party -> Bool) -> (Party -> Party -> Bool) -> Eq Party
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Party -> Party -> Bool
== :: Party -> Party -> Bool
$c/= :: Party -> Party -> Bool
/= :: Party -> Party -> Bool
Eq, (forall x. Party -> Rep Party x)
-> (forall x. Rep Party x -> Party) -> Generic Party
forall x. Rep Party x -> Party
forall x. Party -> Rep Party x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Party -> Rep Party x
from :: forall x. Party -> Rep Party x
$cto :: forall x. Rep Party x -> Party
to :: forall x. Rep Party x -> Party
Generic)
  deriving newtype (Int -> Party -> ShowS
[Party] -> ShowS
Party -> String
(Int -> Party -> ShowS)
-> (Party -> String) -> ([Party] -> ShowS) -> Show Party
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Party -> ShowS
showsPrec :: Int -> Party -> ShowS
$cshow :: Party -> String
show :: Party -> String
$cshowList :: [Party] -> ShowS
showList :: [Party] -> ShowS
Show, Party -> Party -> Bool
(Party -> Party -> Bool) -> Eq Party
forall a. (a -> a -> Bool) -> Eq a
$c== :: Party -> Party -> Bool
== :: Party -> Party -> Bool
PlutusTx.Eq)

instance Arbitrary Party where
  arbitrary :: Gen Party
arbitrary = ByteString -> Party
partyFromVerificationKeyBytes (ByteString -> Party)
-> ([Word8] -> ByteString) -> [Word8] -> Party
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Word8] -> ByteString
BS.pack ([Word8] -> Party) -> Gen [Word8] -> Gen Party
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Gen [Word8]
forall a. Arbitrary a => Int -> Gen [a]
vector Int
32

instance PlutusTx.ToData Party where
  toBuiltinData :: Party -> BuiltinData
toBuiltinData (UnsafeParty BuiltinByteString
bytes) = BuiltinByteString -> BuiltinData
forall a. ToData a => a -> BuiltinData
toBuiltinData BuiltinByteString
bytes

instance PlutusTx.FromData Party where
  fromBuiltinData :: BuiltinData -> Maybe Party
fromBuiltinData = (BuiltinByteString -> Party)
-> Maybe BuiltinByteString -> Maybe Party
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap BuiltinByteString -> Party
UnsafeParty (Maybe BuiltinByteString -> Maybe Party)
-> (BuiltinData -> Maybe BuiltinByteString)
-> BuiltinData
-> Maybe Party
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BuiltinData -> Maybe BuiltinByteString
forall a. FromData a => BuiltinData -> Maybe a
fromBuiltinData

instance PlutusTx.UnsafeFromData Party where
  unsafeFromBuiltinData :: BuiltinData -> Party
unsafeFromBuiltinData = BuiltinByteString -> Party
UnsafeParty (BuiltinByteString -> Party)
-> (BuiltinData -> BuiltinByteString) -> BuiltinData -> Party
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BuiltinData -> BuiltinByteString
forall a. UnsafeFromData a => BuiltinData -> a
unsafeFromBuiltinData

-- | Create an on-chain 'Party' from some verification key bytes.
partyFromVerificationKeyBytes :: ByteString -> Party
partyFromVerificationKeyBytes :: ByteString -> Party
partyFromVerificationKeyBytes =
  BuiltinByteString -> Party
UnsafeParty (BuiltinByteString -> Party)
-> (ByteString -> BuiltinByteString) -> ByteString -> Party
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> BuiltinByteString
ByteString -> ToBuiltin ByteString
forall a. HasToBuiltin a => a -> ToBuiltin a
toBuiltin

-- | Get the verification key bytes contained from an on-chain 'Party'.
partyToVerficationKeyBytes :: Party -> ByteString
partyToVerficationKeyBytes :: Party -> ByteString
partyToVerficationKeyBytes (UnsafeParty BuiltinByteString
bytes) =
  BuiltinByteString -> FromBuiltin BuiltinByteString
forall arep. HasFromBuiltin arep => arep -> FromBuiltin arep
fromBuiltin BuiltinByteString
bytes