{-# OPTIONS_GHC -Wno-orphans #-}

-- Mirrors the equivalent V2 module in plutus-ledger-api
module Plutarch.LedgerApi.V2.Tx (
  POutputDatum (..),
  PTxOut (..),
) where

import GHC.Generics (Generic)
import Plutarch.LedgerApi.AssocMap qualified as AssocMap
import Plutarch.LedgerApi.Utils (PMaybeData)
import Plutarch.LedgerApi.V1.Address (PAddress)
import Plutarch.LedgerApi.V1.Scripts (PDatum, PDatumHash, PScriptHash)
import Plutarch.LedgerApi.Value qualified as Value
import Plutarch.Prelude
import PlutusLedgerApi.V2 qualified as Plutus

-- | @since 2.0.0
data POutputDatum (s :: S)
  = PNoOutputDatum (Term s (PDataRecord '[]))
  | POutputDatumHash (Term s (PDataRecord '["datumHash" ':= PDatumHash]))
  | -- | Inline datum as per
    -- [CIP-0032](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0032/README.md)
    POutputDatum (Term s (PDataRecord '["outputDatum" ':= PDatum]))
  deriving stock
    ( -- | @since 2.0.0
      (forall x. POutputDatum s -> Rep (POutputDatum s) x)
-> (forall x. Rep (POutputDatum s) x -> POutputDatum s)
-> Generic (POutputDatum s)
forall x. Rep (POutputDatum s) x -> POutputDatum s
forall x. POutputDatum s -> Rep (POutputDatum s) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (s :: S) x. Rep (POutputDatum s) x -> POutputDatum s
forall (s :: S) x. POutputDatum s -> Rep (POutputDatum s) x
$cfrom :: forall (s :: S) x. POutputDatum s -> Rep (POutputDatum s) x
from :: forall x. POutputDatum s -> Rep (POutputDatum s) x
$cto :: forall (s :: S) x. Rep (POutputDatum s) x -> POutputDatum s
to :: forall x. Rep (POutputDatum s) x -> POutputDatum s
Generic
    )
  deriving anyclass
    ( -- | @since 2.0.0
      (forall (s :: S). POutputDatum s -> Term s (PInner POutputDatum))
-> (forall (s :: S) (b :: PType).
    Term s (PInner POutputDatum)
    -> (POutputDatum s -> Term s b) -> Term s b)
-> PlutusType POutputDatum
forall (s :: S). POutputDatum s -> Term s (PInner POutputDatum)
forall (s :: S) (b :: PType).
Term s (PInner POutputDatum)
-> (POutputDatum s -> Term s b) -> Term s b
forall (a :: PType).
(forall (s :: S). a s -> Term s (PInner a))
-> (forall (s :: S) (b :: PType).
    Term s (PInner a) -> (a s -> Term s b) -> Term s b)
-> PlutusType a
$cpcon' :: forall (s :: S). POutputDatum s -> Term s (PInner POutputDatum)
pcon' :: forall (s :: S). POutputDatum s -> Term s (PInner POutputDatum)
$cpmatch' :: forall (s :: S) (b :: PType).
Term s (PInner POutputDatum)
-> (POutputDatum s -> Term s b) -> Term s b
pmatch' :: forall (s :: S) (b :: PType).
Term s (PInner POutputDatum)
-> (POutputDatum s -> Term s b) -> Term s b
PlutusType
    , -- | @since 2.0.0
      (forall (s :: S).
 Term s (PAsData POutputDatum) -> Term s POutputDatum)
-> (forall (s :: S). Term s POutputDatum -> Term s PData)
-> PIsData POutputDatum
forall (s :: S).
Term s (PAsData POutputDatum) -> Term s POutputDatum
forall (s :: S). Term s POutputDatum -> Term s PData
forall (a :: PType).
(forall (s :: S). Term s (PAsData a) -> Term s a)
-> (forall (s :: S). Term s a -> Term s PData) -> PIsData a
$cpfromDataImpl :: forall (s :: S).
Term s (PAsData POutputDatum) -> Term s POutputDatum
pfromDataImpl :: forall (s :: S).
Term s (PAsData POutputDatum) -> Term s POutputDatum
$cpdataImpl :: forall (s :: S). Term s POutputDatum -> Term s PData
pdataImpl :: forall (s :: S). Term s POutputDatum -> Term s PData
PIsData
    , -- | @since 2.0.0
      (forall (s :: S).
 Term s POutputDatum -> Term s POutputDatum -> Term s PBool)
-> PEq POutputDatum
forall (s :: S).
Term s POutputDatum -> Term s POutputDatum -> Term s PBool
forall (t :: PType).
(forall (s :: S). Term s t -> Term s t -> Term s PBool) -> PEq t
$c#== :: forall (s :: S).
Term s POutputDatum -> Term s POutputDatum -> Term s PBool
#== :: forall (s :: S).
Term s POutputDatum -> Term s POutputDatum -> Term s PBool
PEq
    , -- | @since 2.0.0
      (forall (s :: S). Bool -> Term s POutputDatum -> Term s PString)
-> PShow POutputDatum
forall (s :: S). Bool -> Term s POutputDatum -> Term s PString
forall (t :: PType).
(forall (s :: S). Bool -> Term s t -> Term s PString) -> PShow t
$cpshow' :: forall (s :: S). Bool -> Term s POutputDatum -> Term s PString
pshow' :: forall (s :: S). Bool -> Term s POutputDatum -> Term s PString
PShow
    , -- | @since 3.1.0
      PTryFrom PData
    )

-- | @since 2.0.0
instance DerivePlutusType POutputDatum where
  type DPTStrat _ = PlutusTypeData

-- | @since WIP
deriving via
  DeriveDataPLiftable POutputDatum Plutus.OutputDatum
  instance
    PLiftable POutputDatum

-- | @since 3.1.0
instance PTryFrom PData (PAsData POutputDatum)

-- | @since 2.0.0
newtype PTxOut (s :: S)
  = PTxOut
      ( Term
          s
          ( PDataRecord
              '[ "address" ':= PAddress
               , "value" ':= Value.PValue 'AssocMap.Sorted 'Value.Positive
               , "datum" ':= POutputDatum
               , "referenceScript" ':= PMaybeData PScriptHash
               ]
          )
      )
  deriving stock
    ( -- | @since 2.0.0
      (forall x. PTxOut s -> Rep (PTxOut s) x)
-> (forall x. Rep (PTxOut s) x -> PTxOut s) -> Generic (PTxOut s)
forall x. Rep (PTxOut s) x -> PTxOut s
forall x. PTxOut s -> Rep (PTxOut s) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (s :: S) x. Rep (PTxOut s) x -> PTxOut s
forall (s :: S) x. PTxOut s -> Rep (PTxOut s) x
$cfrom :: forall (s :: S) x. PTxOut s -> Rep (PTxOut s) x
from :: forall x. PTxOut s -> Rep (PTxOut s) x
$cto :: forall (s :: S) x. Rep (PTxOut s) x -> PTxOut s
to :: forall x. Rep (PTxOut s) x -> PTxOut s
Generic
    )
  deriving anyclass
    ( -- | @since 2.0.0
      (forall (s :: S). PTxOut s -> Term s (PInner PTxOut))
-> (forall (s :: S) (b :: PType).
    Term s (PInner PTxOut) -> (PTxOut s -> Term s b) -> Term s b)
-> PlutusType PTxOut
forall (s :: S). PTxOut s -> Term s (PInner PTxOut)
forall (s :: S) (b :: PType).
Term s (PInner PTxOut) -> (PTxOut s -> Term s b) -> Term s b
forall (a :: PType).
(forall (s :: S). a s -> Term s (PInner a))
-> (forall (s :: S) (b :: PType).
    Term s (PInner a) -> (a s -> Term s b) -> Term s b)
-> PlutusType a
$cpcon' :: forall (s :: S). PTxOut s -> Term s (PInner PTxOut)
pcon' :: forall (s :: S). PTxOut s -> Term s (PInner PTxOut)
$cpmatch' :: forall (s :: S) (b :: PType).
Term s (PInner PTxOut) -> (PTxOut s -> Term s b) -> Term s b
pmatch' :: forall (s :: S) (b :: PType).
Term s (PInner PTxOut) -> (PTxOut s -> Term s b) -> Term s b
PlutusType
    , -- | @since 2.0.0
      (forall (s :: S). Term s (PAsData PTxOut) -> Term s PTxOut)
-> (forall (s :: S). Term s PTxOut -> Term s PData)
-> PIsData PTxOut
forall (s :: S). Term s (PAsData PTxOut) -> Term s PTxOut
forall (s :: S). Term s PTxOut -> Term s PData
forall (a :: PType).
(forall (s :: S). Term s (PAsData a) -> Term s a)
-> (forall (s :: S). Term s a -> Term s PData) -> PIsData a
$cpfromDataImpl :: forall (s :: S). Term s (PAsData PTxOut) -> Term s PTxOut
pfromDataImpl :: forall (s :: S). Term s (PAsData PTxOut) -> Term s PTxOut
$cpdataImpl :: forall (s :: S). Term s PTxOut -> Term s PData
pdataImpl :: forall (s :: S). Term s PTxOut -> Term s PData
PIsData
    , -- | @since 2.0.0
      (forall (s :: S).
 Term s PTxOut -> Term s (PDataRecord (PFields PTxOut)))
-> PDataFields PTxOut
forall (s :: S).
Term s PTxOut -> Term s (PDataRecord (PFields PTxOut))
forall (a :: PType).
(forall (s :: S). Term s a -> Term s (PDataRecord (PFields a)))
-> PDataFields a
$cptoFields :: forall (s :: S).
Term s PTxOut -> Term s (PDataRecord (PFields PTxOut))
ptoFields :: forall (s :: S).
Term s PTxOut -> Term s (PDataRecord (PFields PTxOut))
PDataFields
    , -- | @since 2.0.0
      (forall (s :: S). Term s PTxOut -> Term s PTxOut -> Term s PBool)
-> PEq PTxOut
forall (s :: S). Term s PTxOut -> Term s PTxOut -> Term s PBool
forall (t :: PType).
(forall (s :: S). Term s t -> Term s t -> Term s PBool) -> PEq t
$c#== :: forall (s :: S). Term s PTxOut -> Term s PTxOut -> Term s PBool
#== :: forall (s :: S). Term s PTxOut -> Term s PTxOut -> Term s PBool
PEq
    , -- | @since 2.0.0
      (forall (s :: S). Bool -> Term s PTxOut -> Term s PString)
-> PShow PTxOut
forall (s :: S). Bool -> Term s PTxOut -> Term s PString
forall (t :: PType).
(forall (s :: S). Bool -> Term s t -> Term s PString) -> PShow t
$cpshow' :: forall (s :: S). Bool -> Term s PTxOut -> Term s PString
pshow' :: forall (s :: S). Bool -> Term s PTxOut -> Term s PString
PShow
    , -- | @since 3.1.0
      PTryFrom PData
    )

-- | @since 2.0.0
instance DerivePlutusType PTxOut where
  type DPTStrat _ = PlutusTypeData

-- | @since WIP
deriving via
  DeriveDataPLiftable PTxOut Plutus.TxOut
  instance
    PLiftable PTxOut

-- | @since 3.1.0
instance PTryFrom PData (PAsData PTxOut)