module Plutus.Script.Utils.V2.Address
    ( mkValidatorAddress
    , mkValidatorCardanoAddress
    , mkMintingPolicyCardanoAddress
    , mkStakeValidatorCardanoAddress
    ) where

import Cardano.Api qualified as Script

import Plutus.Script.Utils.V2.Scripts qualified as PV2
import Plutus.V2.Ledger.Api (Address (Address), Credential (ScriptCredential), Script, Validator, getMintingPolicy,
                             getStakeValidator, getValidator)

{-# INLINABLE mkValidatorAddress #-}
-- | The address that should be used by a transaction output locked by the given
-- Plutus V2 validator script.
mkValidatorAddress :: Validator -> Address
mkValidatorAddress :: Validator -> Address
mkValidatorAddress Validator
validator = Credential -> Maybe StakingCredential -> Address
Address (ValidatorHash -> Credential
ScriptCredential (Validator -> ValidatorHash
PV2.validatorHash Validator
validator)) Maybe StakingCredential
forall a. Maybe a
Nothing

-- | Cardano address of a 'PV1.Validator' script.
mkValidatorCardanoAddress :: Script.NetworkId -> PV2.Validator -> Script.AddressInEra Script.BabbageEra
mkValidatorCardanoAddress :: NetworkId -> Validator -> AddressInEra BabbageEra
mkValidatorCardanoAddress NetworkId
networkId = NetworkId -> Script -> AddressInEra BabbageEra
toScriptAddress NetworkId
networkId (Script -> AddressInEra BabbageEra)
-> (Validator -> Script) -> Validator -> AddressInEra BabbageEra
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Validator -> Script
getValidator

-- | Cardano address of a 'PV1.MintingPolicy' script.
mkMintingPolicyCardanoAddress :: Script.NetworkId -> PV2.MintingPolicy -> Script.AddressInEra Script.BabbageEra
mkMintingPolicyCardanoAddress :: NetworkId -> MintingPolicy -> AddressInEra BabbageEra
mkMintingPolicyCardanoAddress NetworkId
networkId = NetworkId -> Script -> AddressInEra BabbageEra
toScriptAddress NetworkId
networkId (Script -> AddressInEra BabbageEra)
-> (MintingPolicy -> Script)
-> MintingPolicy
-> AddressInEra BabbageEra
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MintingPolicy -> Script
getMintingPolicy

-- | Cardano address of a 'PV1.MintingPolicy' script.
mkStakeValidatorCardanoAddress :: Script.NetworkId -> PV2.StakeValidator -> Script.AddressInEra Script.BabbageEra
mkStakeValidatorCardanoAddress :: NetworkId -> StakeValidator -> AddressInEra BabbageEra
mkStakeValidatorCardanoAddress NetworkId
networkId = NetworkId -> Script -> AddressInEra BabbageEra
toScriptAddress NetworkId
networkId (Script -> AddressInEra BabbageEra)
-> (StakeValidator -> Script)
-> StakeValidator
-> AddressInEra BabbageEra
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StakeValidator -> Script
getStakeValidator

-- | Convert a 'Script' to a 'cardano-api' address.
--
-- For why we depend on `cardano-api`,
-- see note [Hash computation of datums, redeemers and scripts]
toScriptAddress :: Script.NetworkId -> Script -> Script.AddressInEra Script.BabbageEra
toScriptAddress :: NetworkId -> Script -> AddressInEra BabbageEra
toScriptAddress NetworkId
networkId Script
script = NetworkId
-> PaymentCredential
-> StakeAddressReference
-> AddressInEra BabbageEra
forall era.
IsShelleyBasedEra era =>
NetworkId
-> PaymentCredential -> StakeAddressReference -> AddressInEra era
Script.makeShelleyAddressInEra
  NetworkId
networkId
  ( ScriptHash -> PaymentCredential
Script.PaymentCredentialByScript
    (ScriptHash -> PaymentCredential)
-> (Script PlutusScriptV2 -> ScriptHash)
-> Script PlutusScriptV2
-> PaymentCredential
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Script PlutusScriptV2 -> ScriptHash
forall lang. Script lang -> ScriptHash
Script.hashScript
    (Script PlutusScriptV2 -> PaymentCredential)
-> Script PlutusScriptV2 -> PaymentCredential
forall a b. (a -> b) -> a -> b
$ Script -> Script PlutusScriptV2
PV2.toCardanoApiScript Script
script)
  StakeAddressReference
Script.NoStakeAddress