{-|
This module contains functions related to the computation of script hashes for
PlutusV1.
-}

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

module Plutus.Script.Utils.V1.Scripts
    ( -- * Script hashes
      PV1.Validator
    , PV1.ValidatorHash
    , PV1.MintingPolicy
    , PV1.MintingPolicyHash
    , PV1.StakeValidator
    , PV1.StakeValidatorHash
    , fromCardanoHash
    , validatorHash
    , mintingPolicyHash
    , stakeValidatorHash
    , scriptHash
    -- * Script utilities
    , scriptCurrencySymbol
    , toCardanoApiScript
    ) where

import Cardano.Api qualified as C
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.V1.Ledger.Api qualified as PV1
import Plutus.V1.Ledger.Scripts qualified as PV1
import PlutusTx.Builtins qualified as Builtins

-- | Hash a 'PV1.Validator' script.
validatorHash :: PV1.Validator -> PV1.ValidatorHash
validatorHash :: Validator -> ValidatorHash
validatorHash =
    BuiltinByteString -> ValidatorHash
PV1.ValidatorHash
  (BuiltinByteString -> ValidatorHash)
-> (Validator -> BuiltinByteString) -> Validator -> ValidatorHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptHash -> BuiltinByteString
PV1.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
PV1.getValidator

-- | Hash a 'PV1.MintingPolicy' script.
mintingPolicyHash :: PV1.MintingPolicy -> PV1.MintingPolicyHash
mintingPolicyHash :: MintingPolicy -> MintingPolicyHash
mintingPolicyHash =
    BuiltinByteString -> MintingPolicyHash
PV1.MintingPolicyHash
  (BuiltinByteString -> MintingPolicyHash)
-> (MintingPolicy -> BuiltinByteString)
-> MintingPolicy
-> MintingPolicyHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptHash -> BuiltinByteString
PV1.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
PV1.getMintingPolicy

-- | Hash a 'PV1.StakeValidator' script.
stakeValidatorHash :: PV1.StakeValidator -> PV1.StakeValidatorHash
stakeValidatorHash :: StakeValidator -> StakeValidatorHash
stakeValidatorHash =
    BuiltinByteString -> StakeValidatorHash
PV1.StakeValidatorHash
  (BuiltinByteString -> StakeValidatorHash)
-> (StakeValidator -> BuiltinByteString)
-> StakeValidator
-> StakeValidatorHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptHash -> BuiltinByteString
PV1.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
PV1.getStakeValidator

-- | Hash a 'Script'
scriptHash :: PV1.Script -> PV1.ScriptHash
scriptHash :: Script -> ScriptHash
scriptHash =
    ScriptHash -> ScriptHash
fromCardanoHash
    (ScriptHash -> ScriptHash)
-> (Script -> ScriptHash) -> Script -> ScriptHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Script PlutusScriptV1 -> ScriptHash
forall lang. Script lang -> ScriptHash
Script.hashScript
    (Script PlutusScriptV1 -> ScriptHash)
-> (Script -> Script PlutusScriptV1) -> Script -> ScriptHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Script -> Script PlutusScriptV1
toCardanoApiScript

-- | Transform a Cardano Script hash in a Plutus Script hash
fromCardanoHash :: C.ScriptHash -> PV1.ScriptHash
fromCardanoHash :: ScriptHash -> ScriptHash
fromCardanoHash =
    BuiltinByteString -> ScriptHash
PV1.ScriptHash
    (BuiltinByteString -> ScriptHash)
-> (ScriptHash -> BuiltinByteString) -> ScriptHash -> 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)
-> (ScriptHash -> ByteString) -> ScriptHash -> BuiltinByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptHash -> ByteString
forall a. SerialiseAsRawBytes a => a -> ByteString
Script.serialiseToRawBytes

-- | 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 :: PV1.Script -> Script.Script Script.PlutusScriptV1
toCardanoApiScript :: Script -> Script PlutusScriptV1
toCardanoApiScript =
    PlutusScriptVersion PlutusScriptV1
-> PlutusScript PlutusScriptV1 -> Script PlutusScriptV1
forall lang.
PlutusScriptVersion lang -> PlutusScript lang -> Script lang
Script.PlutusScript PlutusScriptVersion PlutusScriptV1
Script.PlutusScriptV1
  (PlutusScript PlutusScriptV1 -> Script PlutusScriptV1)
-> (Script -> PlutusScript PlutusScriptV1)
-> Script
-> Script PlutusScriptV1
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> PlutusScript PlutusScriptV1
forall lang. ShortByteString -> PlutusScript lang
Script.PlutusScriptSerialised
  (ShortByteString -> PlutusScript PlutusScriptV1)
-> (Script -> ShortByteString)
-> Script
-> PlutusScript PlutusScriptV1
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 :: PV1.MintingPolicy -> PV1.CurrencySymbol
scriptCurrencySymbol :: MintingPolicy -> CurrencySymbol
scriptCurrencySymbol MintingPolicy
scrpt =
    let (PV1.MintingPolicyHash BuiltinByteString
hsh) = MintingPolicy -> MintingPolicyHash
mintingPolicyHash MintingPolicy
scrpt in BuiltinByteString -> CurrencySymbol
PV1.CurrencySymbol BuiltinByteString
hsh