{-# OPTIONS_GHC -Wno-orphans #-}

module Hydra.Cardano.Api.ScriptData where

import Hydra.Cardano.Api.Prelude hiding (left)

import Cardano.Ledger.Core qualified as Ledger
import Cardano.Ledger.Plutus.Data qualified as Ledger
import PlutusLedgerApi.V3 qualified as Plutus

-- * Extras

-- | Data-types that can be marshalled into a generic 'ScriptData' structure.
type ToScriptData a = Plutus.ToData a

-- | Data-types that can be unmarshalled from a generic 'ScriptData' structure.
type FromScriptData a = Plutus.FromData a

-- | Serialise some type into a generic script data.
toScriptData :: ToScriptData a => a -> HashableScriptData
toScriptData :: forall a. ToScriptData a => a -> HashableScriptData
toScriptData =
  -- NOTE: Safe to use here as the data was not available in serialized form.
  ScriptData -> HashableScriptData
unsafeHashableScriptData (ScriptData -> HashableScriptData)
-> (a -> ScriptData) -> a -> HashableScriptData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Data -> ScriptData
fromPlutusData (Data -> ScriptData) -> (a -> Data) -> a -> ScriptData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Data
forall a. ToData a => a -> Data
Plutus.toData

-- | Deserialise some generic script data into some type.
fromScriptData :: FromScriptData a => HashableScriptData -> Maybe a
fromScriptData :: forall a. FromScriptData a => HashableScriptData -> Maybe a
fromScriptData =
  Data -> Maybe a
forall a. FromData a => Data -> Maybe a
Plutus.fromData (Data -> Maybe a)
-> (HashableScriptData -> Data) -> HashableScriptData -> Maybe a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptData -> Data
toPlutusData (ScriptData -> Data)
-> (HashableScriptData -> ScriptData) -> HashableScriptData -> Data
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashableScriptData -> ScriptData
getScriptData

-- | Get the 'HashableScriptData' associated to the a 'TxOut'. Note that this
-- requires the 'CtxTx' context.
txOutScriptData :: TxOut CtxTx era -> Maybe HashableScriptData
txOutScriptData :: forall era. TxOut CtxTx era -> Maybe HashableScriptData
txOutScriptData (TxOut AddressInEra era
_ TxOutValue era
_ TxOutDatum CtxTx era
d ReferenceScript era
_) =
  case TxOutDatum CtxTx era
d of
    TxOutDatumInline BabbageEraOnwards era
_ HashableScriptData
sd -> HashableScriptData -> Maybe HashableScriptData
forall a. a -> Maybe a
Just HashableScriptData
sd
    TxOutSupplementalDatum AlonzoEraOnwards era
_ HashableScriptData
sd -> HashableScriptData -> Maybe HashableScriptData
forall a. a -> Maybe a
Just HashableScriptData
sd
    TxOutDatum CtxTx era
_ -> Maybe HashableScriptData
forall a. Maybe a
Nothing

-- * Type Conversions

-- | Convert a cardano-ledger script 'Data' into a cardano-api 'ScriptDatum'.
fromLedgerData :: Ledger.Data era -> HashableScriptData
fromLedgerData :: forall era. Data era -> HashableScriptData
fromLedgerData =
  Data era -> HashableScriptData
forall era. Data era -> HashableScriptData
fromAlonzoData

-- | Convert a cardano-api script data into a cardano-ledger script 'Data'.
-- XXX: This is a partial function. Ideally it would fall back to the
-- 'Plutus.Data' portion in 'HashableScriptData'.
toLedgerData :: Ledger.Era era => HashableScriptData -> Ledger.Data era
toLedgerData :: forall era. Era era => HashableScriptData -> Data era
toLedgerData =
  HashableScriptData -> Data era
forall era. Era era => HashableScriptData -> Data era
toAlonzoData