{-# OPTIONS_GHC -Wno-missing-import-lists #-}

module Plutus.Script.Utils.V2.Scripts
    ( -- * Script data hashes
      PV2.Datum
    , PV2.DatumHash
    , PV2.Redeemer
    , PV2.RedeemerHash
    , P.datumHash
    , P.redeemerHash
    , P.dataHash
    -- * Script hashes
    , PV2.Validator
    , PV2.ValidatorHash
    , PV2.MintingPolicy
    , PV2.MintingPolicyHash
    , PV2.StakeValidator
    , PV2.StakeValidatorHash
    , validatorHash
    , mintingPolicyHash
    , stakeValidatorHash
    , scriptHash
    -- * Script utilities
    , scriptCurrencySymbol
    , toCardanoApiScript
    ) where

import Cardano.Api qualified as Script
import Cardano.Api.Shelley qualified as Script
import Codec.Serialise (serialise)
import Data.ByteString.Lazy qualified as BSL
import Data.ByteString.Short qualified as SBS
import Plutus.Script.Utils.Scripts qualified as P
import Plutus.V2.Ledger.Api qualified as PV2
import PlutusTx.Builtins qualified as Builtins

-- | Hash a 'PV2.Validator' script.
validatorHash :: PV2.Validator -> PV2.ValidatorHash
validatorHash :: Validator -> ValidatorHash
validatorHash =
    BuiltinByteString -> ValidatorHash
PV2.ValidatorHash
  (BuiltinByteString -> ValidatorHash)
-> (Validator -> BuiltinByteString) -> Validator -> ValidatorHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptHash -> BuiltinByteString
PV2.getScriptHash
  (ScriptHash -> BuiltinByteString)
-> (Validator -> ScriptHash) -> Validator -> BuiltinByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Script -> ScriptHash
scriptHash
  (Script -> ScriptHash)
-> (Validator -> Script) -> Validator -> ScriptHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Validator -> Script
PV2.getValidator

-- | Hash a 'PV2.MintingPolicy' script.
mintingPolicyHash :: PV2.MintingPolicy -> PV2.MintingPolicyHash
mintingPolicyHash :: MintingPolicy -> MintingPolicyHash
mintingPolicyHash =
    BuiltinByteString -> MintingPolicyHash
PV2.MintingPolicyHash
  (BuiltinByteString -> MintingPolicyHash)
-> (MintingPolicy -> BuiltinByteString)
-> MintingPolicy
-> MintingPolicyHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptHash -> BuiltinByteString
PV2.getScriptHash
  (ScriptHash -> BuiltinByteString)
-> (MintingPolicy -> ScriptHash)
-> MintingPolicy
-> BuiltinByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Script -> ScriptHash
scriptHash
  (Script -> ScriptHash)
-> (MintingPolicy -> Script) -> MintingPolicy -> ScriptHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MintingPolicy -> Script
PV2.getMintingPolicy

-- | Hash a 'PV2.StakeValidator' script.
stakeValidatorHash :: PV2.StakeValidator -> PV2.StakeValidatorHash
stakeValidatorHash :: StakeValidator -> StakeValidatorHash
stakeValidatorHash =
    BuiltinByteString -> StakeValidatorHash
PV2.StakeValidatorHash
  (BuiltinByteString -> StakeValidatorHash)
-> (StakeValidator -> BuiltinByteString)
-> StakeValidator
-> StakeValidatorHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptHash -> BuiltinByteString
PV2.getScriptHash
  (ScriptHash -> BuiltinByteString)
-> (StakeValidator -> ScriptHash)
-> StakeValidator
-> BuiltinByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Script -> ScriptHash
scriptHash
  (Script -> ScriptHash)
-> (StakeValidator -> Script) -> StakeValidator -> ScriptHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StakeValidator -> Script
PV2.getStakeValidator

-- | Convert a 'Builtins.BuiltinsData' value to a 'cardano-api' script
--   data value.
--
-- For why we depend on `cardano-api`,
-- see note [Hash computation of datums, redeemers and scripts]
-- toCardanoAPIData :: Builtins.BuiltinData -> Script.ScriptData
-- toCardanoAPIData = Script.fromPlutusData . Builtins.builtinDataToData

-- | Hash a 'Script'
scriptHash :: PV2.Script -> PV2.ScriptHash
scriptHash :: Script -> ScriptHash
scriptHash =
    BuiltinByteString -> ScriptHash
PV2.ScriptHash
    (BuiltinByteString -> ScriptHash)
-> (Script -> BuiltinByteString) -> Script -> ScriptHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> BuiltinByteString
forall a arep. ToBuiltin a arep => a -> arep
Builtins.toBuiltin
    (ByteString -> BuiltinByteString)
-> (Script -> ByteString) -> Script -> BuiltinByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptHash -> ByteString
forall a. SerialiseAsRawBytes a => a -> ByteString
Script.serialiseToRawBytes
    (ScriptHash -> ByteString)
-> (Script -> ScriptHash) -> Script -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Script PlutusScriptV2 -> ScriptHash
forall lang. Script lang -> ScriptHash
Script.hashScript
    (Script PlutusScriptV2 -> ScriptHash)
-> (Script -> Script PlutusScriptV2) -> Script -> ScriptHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Script -> Script PlutusScriptV2
toCardanoApiScript

-- | Convert a 'Script' to a 'cardano-api' script.
--
-- For why we depend on `cardano-api`,
-- see note [Hash computation of datums, redeemers and scripts]
toCardanoApiScript :: PV2.Script -> Script.Script Script.PlutusScriptV2
toCardanoApiScript :: Script -> Script PlutusScriptV2
toCardanoApiScript =
    PlutusScriptVersion PlutusScriptV2
-> PlutusScript PlutusScriptV2 -> Script PlutusScriptV2
forall lang.
PlutusScriptVersion lang -> PlutusScript lang -> Script lang
Script.PlutusScript PlutusScriptVersion PlutusScriptV2
Script.PlutusScriptV2
  (PlutusScript PlutusScriptV2 -> Script PlutusScriptV2)
-> (Script -> PlutusScript PlutusScriptV2)
-> Script
-> Script PlutusScriptV2
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> PlutusScript PlutusScriptV2
forall lang. ShortByteString -> PlutusScript lang
Script.PlutusScriptSerialised
  (ShortByteString -> PlutusScript PlutusScriptV2)
-> (Script -> ShortByteString)
-> Script
-> PlutusScript PlutusScriptV2
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ShortByteString
SBS.toShort
  (ByteString -> ShortByteString)
-> (Script -> ByteString) -> Script -> ShortByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
BSL.toStrict
  (ByteString -> ByteString)
-> (Script -> ByteString) -> Script -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Script -> ByteString
forall a. Serialise a => a -> ByteString
serialise

{-# INLINABLE scriptCurrencySymbol #-}
-- | The 'CurrencySymbol' of a 'MintingPolicy'.
scriptCurrencySymbol :: PV2.MintingPolicy -> PV2.CurrencySymbol
scriptCurrencySymbol :: MintingPolicy -> CurrencySymbol
scriptCurrencySymbol MintingPolicy
scrpt =
    let (PV2.MintingPolicyHash BuiltinByteString
hsh) = MintingPolicy -> MintingPolicyHash
mintingPolicyHash MintingPolicy
scrpt in BuiltinByteString -> CurrencySymbol
PV2.CurrencySymbol BuiltinByteString
hsh

{- See Note [Hash computation of datums, redeemers and scripts] -}

{- See Note [Scripts returning Bool] -}