{-# OPTIONS_GHC -Wno-orphans #-}

-- Mirrors the equivalent V1 module in plutus-ledger-api
module Plutarch.LedgerApi.V1.Tx (
  PTxId (..),
  PTxOutRef (..),
  txIdByteSize,
) where

import GHC.Generics (Generic)
import Generics.SOP qualified as SOP
import Plutarch.Prelude
import PlutusLedgerApi.V1 qualified as Plutus

{- | Hashed with @BLAKE2b-256@.

@since 3.1.0
-}
newtype PTxId (s :: S) = PTxId (Term s (PAsData PByteString))
  deriving stock
    ( -- | @since 2.0.0
      (forall x. PTxId s -> Rep (PTxId s) x)
-> (forall x. Rep (PTxId s) x -> PTxId s) -> Generic (PTxId s)
forall x. Rep (PTxId s) x -> PTxId s
forall x. PTxId s -> Rep (PTxId s) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (s :: S) x. Rep (PTxId s) x -> PTxId s
forall (s :: S) x. PTxId s -> Rep (PTxId s) x
$cfrom :: forall (s :: S) x. PTxId s -> Rep (PTxId s) x
from :: forall x. PTxId s -> Rep (PTxId s) x
$cto :: forall (s :: S) x. Rep (PTxId s) x -> PTxId s
to :: forall x. Rep (PTxId s) x -> PTxId s
Generic
    )
  deriving anyclass
    ( -- | @since 3.3.0
      All SListI (Code (PTxId s))
All SListI (Code (PTxId s)) =>
(PTxId s -> Rep (PTxId s))
-> (Rep (PTxId s) -> PTxId s) -> Generic (PTxId s)
Rep (PTxId s) -> PTxId s
PTxId s -> Rep (PTxId s)
forall a.
All SListI (Code a) =>
(a -> Rep a) -> (Rep a -> a) -> Generic a
forall (s :: S). All SListI (Code (PTxId s))
forall (s :: S). Rep (PTxId s) -> PTxId s
forall (s :: S). PTxId s -> Rep (PTxId s)
$cfrom :: forall (s :: S). PTxId s -> Rep (PTxId s)
from :: PTxId s -> Rep (PTxId s)
$cto :: forall (s :: S). Rep (PTxId s) -> PTxId s
to :: Rep (PTxId s) -> PTxId s
SOP.Generic
    , -- | @since 2.0.0
      (forall (s :: S). Term s (PAsData PTxId) -> Term s PTxId)
-> (forall (s :: S). Term s PTxId -> Term s PData) -> PIsData PTxId
forall (s :: S). Term s (PAsData PTxId) -> Term s PTxId
forall (s :: S). Term s PTxId -> Term s PData
forall (a :: S -> Type).
(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 PTxId) -> Term s PTxId
pfromDataImpl :: forall (s :: S). Term s (PAsData PTxId) -> Term s PTxId
$cpdataImpl :: forall (s :: S). Term s PTxId -> Term s PData
pdataImpl :: forall (s :: S). Term s PTxId -> Term s PData
PIsData
    , -- | @since 2.0.0
      (forall (s :: S). Term s PTxId -> Term s PTxId -> Term s PBool)
-> PEq PTxId
forall (s :: S). Term s PTxId -> Term s PTxId -> Term s PBool
forall (t :: S -> Type).
(forall (s :: S). Term s t -> Term s t -> Term s PBool) -> PEq t
$c#== :: forall (s :: S). Term s PTxId -> Term s PTxId -> Term s PBool
#== :: forall (s :: S). Term s PTxId -> Term s PTxId -> Term s PBool
PEq
    , -- , -- | @since 2.0.0
      --   POrd

      -- | @since 2.0.0
      (forall (s :: S). Bool -> Term s PTxId -> Term s PString)
-> PShow PTxId
forall (s :: S). Bool -> Term s PTxId -> Term s PString
forall (t :: S -> Type).
(forall (s :: S). Bool -> Term s t -> Term s PString) -> PShow t
$cpshow' :: forall (s :: S). Bool -> Term s PTxId -> Term s PString
pshow' :: forall (s :: S). Bool -> Term s PTxId -> Term s PString
PShow
    )
  deriving
    ( -- | @since 3.3.0
      (forall (s :: S). PTxId s -> Term s (PInner PTxId))
-> (forall (s :: S) (b :: S -> Type).
    Term s (PInner PTxId) -> (PTxId s -> Term s b) -> Term s b)
-> PlutusType PTxId
forall (s :: S). PTxId s -> Term s (PInner PTxId)
forall (s :: S) (b :: S -> Type).
Term s (PInner PTxId) -> (PTxId s -> Term s b) -> Term s b
forall (a :: S -> Type).
(forall (s :: S). a s -> Term s (PInner a))
-> (forall (s :: S) (b :: S -> Type).
    Term s (PInner a) -> (a s -> Term s b) -> Term s b)
-> PlutusType a
$cpcon' :: forall (s :: S). PTxId s -> Term s (PInner PTxId)
pcon' :: forall (s :: S). PTxId s -> Term s (PInner PTxId)
$cpmatch' :: forall (s :: S) (b :: S -> Type).
Term s (PInner PTxId) -> (PTxId s -> Term s b) -> Term s b
pmatch' :: forall (s :: S) (b :: S -> Type).
Term s (PInner PTxId) -> (PTxId s -> Term s b) -> Term s b
PlutusType
    )
    via (DeriveAsDataStruct PTxId)

-- | @since 3.3.0
deriving via
  DeriveDataPLiftable PTxId Plutus.TxId
  instance
    PLiftable PTxId

-- | @since 3.4.0
instance PTryFrom PData (PAsData PTxId)

{- | Checks that we have a 'PTxId' of valid length. The underlying
'PByteString' must be exactly 32 bytes, as Cardano transactions are hashed
with BLAKE2b-256.

@since 3.6.0
-}
instance PValidateData PTxId where
  pwithValidated :: forall (s :: S).
Term s PData -> forall (r :: S -> Type). Term s r -> Term s r
pwithValidated Term s PData
opq Term s r
x =
    -- FIXME: Why is it wrapped in Constr 0?
    Term s (PBuiltinPair PInteger (PBuiltinList PData))
-> (PBuiltinPair PInteger (PBuiltinList PData) s -> Term s r)
-> Term s r
forall (a :: S -> Type) (s :: S) (b :: S -> Type).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch (Term s (PData :--> PBuiltinPair PInteger (PBuiltinList PData))
forall (s :: S).
Term s (PData :--> PBuiltinPair PInteger (PBuiltinList PData))
pasConstr Term s (PData :--> PBuiltinPair PInteger (PBuiltinList PData))
-> Term s PData
-> Term s (PBuiltinPair PInteger (PBuiltinList PData))
forall (s :: S) (a :: S -> Type) (b :: S -> Type).
Term s (a :--> b) -> Term s a -> Term s b
# Term s PData
opq) ((PBuiltinPair PInteger (PBuiltinList PData) s -> Term s r)
 -> Term s r)
-> (PBuiltinPair PInteger (PBuiltinList PData) s -> Term s r)
-> Term s r
forall a b. (a -> b) -> a -> b
$ \(PBuiltinPair Term s PInteger
constrIdx Term s (PBuiltinList PData)
fields) ->
      Term s PBool -> Term s r -> Term s r -> Term s r
forall (a :: S -> Type) (s :: S).
Term s PBool -> Term s a -> Term s a -> Term s a
pif
        ((Term s PInteger
constrIdx Term s PInteger -> Term s PInteger -> Term s PBool
forall (s :: S). Term s PInteger -> Term s PInteger -> Term s PBool
forall (t :: S -> Type) (s :: S).
PEq t =>
Term s t -> Term s t -> Term s PBool
#== Term s PInteger
0) Term s PBool -> Term s PBool -> Term s PBool
forall (s :: S). Term s PBool -> Term s PBool -> Term s PBool
#&& ((Term s (PBuiltinList PData :--> PInteger)
forall (list :: (S -> Type) -> S -> Type) (a :: S -> Type)
       (s :: S).
PIsListLike list a =>
Term s (list a :--> PInteger)
plength Term s (PBuiltinList PData :--> PInteger)
-> Term s (PBuiltinList PData) -> Term s PInteger
forall (s :: S) (a :: S -> Type) (b :: S -> Type).
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList PData)
fields) Term s PInteger -> Term s PInteger -> Term s PBool
forall (s :: S). Term s PInteger -> Term s PInteger -> Term s PBool
forall (t :: S -> Type) (s :: S).
PEq t =>
Term s t -> Term s t -> Term s PBool
#== Term s PInteger
1))
        ( Term s PInteger -> (Term s PInteger -> Term s r) -> Term s r
forall (s :: S) (a :: S -> Type) (b :: S -> Type).
Term s a -> (Term s a -> Term s b) -> Term s b
plet (Term s (PByteString :--> PInteger)
forall (s :: S). Term s (PByteString :--> PInteger)
plengthBS Term s (PByteString :--> PInteger)
-> Term s PByteString -> Term s PInteger
forall (s :: S) (a :: S -> Type) (b :: S -> Type).
Term s (a :--> b) -> Term s a -> Term s b
#$ Term s (PAsData PByteString) -> Term s PByteString
forall (a :: S -> Type) (s :: S).
PIsData a =>
Term s (PAsData a) -> Term s a
pfromData (Term s (PAsData PByteString) -> Term s PByteString)
-> Term s (PAsData PByteString) -> Term s PByteString
forall a b. (a -> b) -> a -> b
$ forall (a :: S -> Type) (s :: S).
(PIsData a, PValidateData a) =>
Term s PData -> Term s (PAsData a)
pparseData @PByteString (Term s PData -> Term s (PAsData PByteString))
-> Term s PData -> Term s (PAsData PByteString)
forall a b. (a -> b) -> a -> b
$ Term s (PBuiltinList PData :--> PData)
forall (a :: S -> Type) (s :: S).
PElemConstraint PBuiltinList a =>
Term s (PBuiltinList a :--> a)
forall (list :: (S -> Type) -> S -> Type) (a :: S -> Type)
       (s :: S).
(PListLike list, PElemConstraint list a) =>
Term s (list a :--> a)
phead Term s (PBuiltinList PData :--> PData)
-> Term s (PBuiltinList PData) -> Term s PData
forall (s :: S) (a :: S -> Type) (b :: S -> Type).
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList PData)
fields) ((Term s PInteger -> Term s r) -> Term s r)
-> (Term s PInteger -> Term s r) -> Term s r
forall a b. (a -> b) -> a -> b
$ \Term s PInteger
bsSize ->
            Term s PBool -> Term s r -> Term s r -> Term s r
forall (a :: S -> Type) (s :: S).
Term s PBool -> Term s a -> Term s a -> Term s a
pif
              (Term s PInteger
bsSize Term s PInteger -> Term s PInteger -> Term s PBool
forall (s :: S). Term s PInteger -> Term s PInteger -> Term s PBool
forall (t :: S -> Type) (s :: S).
PEq t =>
Term s t -> Term s t -> Term s PBool
#== Term s PInteger
forall (s :: S). Term s PInteger
txIdByteSize)
              Term s r
x
              Term s r
forall (s :: S) (a :: S -> Type). Term s a
perror
        )
        Term s r
forall (s :: S) (a :: S -> Type). Term s a
perror

txIdByteSize :: forall (s :: S). Term s PInteger
txIdByteSize :: forall (s :: S). Term s PInteger
txIdByteSize = Term s PInteger
32

{- | Reference to a transaction output, with an index referencing which exact
output we mean.

@since 2.0.0
-}
data PTxOutRef (s :: S) = PTxOutRef
  { forall (s :: S). PTxOutRef s -> Term s PTxId
ptxOutRef'id :: Term s PTxId
  , forall (s :: S). PTxOutRef s -> Term s (PAsData PInteger)
ptxOutRef'idx :: Term s (PAsData PInteger)
  }
  deriving stock
    ( -- | @since 2.0.0
      (forall x. PTxOutRef s -> Rep (PTxOutRef s) x)
-> (forall x. Rep (PTxOutRef s) x -> PTxOutRef s)
-> Generic (PTxOutRef s)
forall x. Rep (PTxOutRef s) x -> PTxOutRef s
forall x. PTxOutRef s -> Rep (PTxOutRef s) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (s :: S) x. Rep (PTxOutRef s) x -> PTxOutRef s
forall (s :: S) x. PTxOutRef s -> Rep (PTxOutRef s) x
$cfrom :: forall (s :: S) x. PTxOutRef s -> Rep (PTxOutRef s) x
from :: forall x. PTxOutRef s -> Rep (PTxOutRef s) x
$cto :: forall (s :: S) x. Rep (PTxOutRef s) x -> PTxOutRef s
to :: forall x. Rep (PTxOutRef s) x -> PTxOutRef s
Generic
    )
  deriving anyclass
    ( -- | @since 3.3.0
      All SListI (Code (PTxOutRef s))
All SListI (Code (PTxOutRef s)) =>
(PTxOutRef s -> Rep (PTxOutRef s))
-> (Rep (PTxOutRef s) -> PTxOutRef s) -> Generic (PTxOutRef s)
Rep (PTxOutRef s) -> PTxOutRef s
PTxOutRef s -> Rep (PTxOutRef s)
forall a.
All SListI (Code a) =>
(a -> Rep a) -> (Rep a -> a) -> Generic a
forall (s :: S). All SListI (Code (PTxOutRef s))
forall (s :: S). Rep (PTxOutRef s) -> PTxOutRef s
forall (s :: S). PTxOutRef s -> Rep (PTxOutRef s)
$cfrom :: forall (s :: S). PTxOutRef s -> Rep (PTxOutRef s)
from :: PTxOutRef s -> Rep (PTxOutRef s)
$cto :: forall (s :: S). Rep (PTxOutRef s) -> PTxOutRef s
to :: Rep (PTxOutRef s) -> PTxOutRef s
SOP.Generic
    , -- | @since 2.0.0
      (forall (s :: S). Term s (PAsData PTxOutRef) -> Term s PTxOutRef)
-> (forall (s :: S). Term s PTxOutRef -> Term s PData)
-> PIsData PTxOutRef
forall (s :: S). Term s (PAsData PTxOutRef) -> Term s PTxOutRef
forall (s :: S). Term s PTxOutRef -> Term s PData
forall (a :: S -> Type).
(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 PTxOutRef) -> Term s PTxOutRef
pfromDataImpl :: forall (s :: S). Term s (PAsData PTxOutRef) -> Term s PTxOutRef
$cpdataImpl :: forall (s :: S). Term s PTxOutRef -> Term s PData
pdataImpl :: forall (s :: S). Term s PTxOutRef -> Term s PData
PIsData
    , -- | @since 2.0.0
      (forall (s :: S).
 Term s PTxOutRef -> Term s PTxOutRef -> Term s PBool)
-> PEq PTxOutRef
forall (s :: S).
Term s PTxOutRef -> Term s PTxOutRef -> Term s PBool
forall (t :: S -> Type).
(forall (s :: S). Term s t -> Term s t -> Term s PBool) -> PEq t
$c#== :: forall (s :: S).
Term s PTxOutRef -> Term s PTxOutRef -> Term s PBool
#== :: forall (s :: S).
Term s PTxOutRef -> Term s PTxOutRef -> Term s PBool
PEq
    , -- , -- | @since 2.0.0
      --   POrd

      -- | @since 2.0.0
      (forall (s :: S). Bool -> Term s PTxOutRef -> Term s PString)
-> PShow PTxOutRef
forall (s :: S). Bool -> Term s PTxOutRef -> Term s PString
forall (t :: S -> Type).
(forall (s :: S). Bool -> Term s t -> Term s PString) -> PShow t
$cpshow' :: forall (s :: S). Bool -> Term s PTxOutRef -> Term s PString
pshow' :: forall (s :: S). Bool -> Term s PTxOutRef -> Term s PString
PShow
    )
  deriving
    ( -- | @since 3.3.0
      (forall (s :: S). PTxOutRef s -> Term s (PInner PTxOutRef))
-> (forall (s :: S) (b :: S -> Type).
    Term s (PInner PTxOutRef) -> (PTxOutRef s -> Term s b) -> Term s b)
-> PlutusType PTxOutRef
forall (s :: S). PTxOutRef s -> Term s (PInner PTxOutRef)
forall (s :: S) (b :: S -> Type).
Term s (PInner PTxOutRef) -> (PTxOutRef s -> Term s b) -> Term s b
forall (a :: S -> Type).
(forall (s :: S). a s -> Term s (PInner a))
-> (forall (s :: S) (b :: S -> Type).
    Term s (PInner a) -> (a s -> Term s b) -> Term s b)
-> PlutusType a
$cpcon' :: forall (s :: S). PTxOutRef s -> Term s (PInner PTxOutRef)
pcon' :: forall (s :: S). PTxOutRef s -> Term s (PInner PTxOutRef)
$cpmatch' :: forall (s :: S) (b :: S -> Type).
Term s (PInner PTxOutRef) -> (PTxOutRef s -> Term s b) -> Term s b
pmatch' :: forall (s :: S) (b :: S -> Type).
Term s (PInner PTxOutRef) -> (PTxOutRef s -> Term s b) -> Term s b
PlutusType
    )
    via (DeriveAsDataStruct PTxOutRef)

-- | @since 3.3.0
deriving via
  DeriveDataPLiftable PTxOutRef Plutus.TxOutRef
  instance
    PLiftable PTxOutRef

-- | @since 3.4.0
instance PTryFrom PData (PAsData PTxOutRef)

{- | Checks that we have a valid 'PTxOutRef'. The underlying 'PTxId' must be
exactly 32 bytes, as Cardano transactions are hashed with BLAKE2b-256, and
the output index must be a non-negative 'PInteger'.

@since 3.6.0
-}
instance PValidateData PTxOutRef where
  pwithValidated :: forall (s :: S).
Term s PData -> forall (r :: S -> Type). Term s r -> Term s r
pwithValidated Term s PData
opq Term s r
x =
    Term s (PBuiltinPair PInteger (PBuiltinList PData))
-> (PBuiltinPair PInteger (PBuiltinList PData) s -> Term s r)
-> Term s r
forall (a :: S -> Type) (s :: S) (b :: S -> Type).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch (Term s (PData :--> PBuiltinPair PInteger (PBuiltinList PData))
forall (s :: S).
Term s (PData :--> PBuiltinPair PInteger (PBuiltinList PData))
pasConstr Term s (PData :--> PBuiltinPair PInteger (PBuiltinList PData))
-> Term s PData
-> Term s (PBuiltinPair PInteger (PBuiltinList PData))
forall (s :: S) (a :: S -> Type) (b :: S -> Type).
Term s (a :--> b) -> Term s a -> Term s b
# Term s PData
opq) ((PBuiltinPair PInteger (PBuiltinList PData) s -> Term s r)
 -> Term s r)
-> (PBuiltinPair PInteger (PBuiltinList PData) s -> Term s r)
-> Term s r
forall a b. (a -> b) -> a -> b
$ \(PBuiltinPair Term s PInteger
constrIdx Term s (PBuiltinList PData)
fields) ->
      Term s PBool -> Term s r -> Term s r -> Term s r
forall (a :: S -> Type) (s :: S).
Term s PBool -> Term s a -> Term s a -> Term s a
pif
        ((Term s PInteger
constrIdx Term s PInteger -> Term s PInteger -> Term s PBool
forall (s :: S). Term s PInteger -> Term s PInteger -> Term s PBool
forall (t :: S -> Type) (s :: S).
PEq t =>
Term s t -> Term s t -> Term s PBool
#== Term s PInteger
0) Term s PBool -> Term s PBool -> Term s PBool
forall (s :: S). Term s PBool -> Term s PBool -> Term s PBool
#&& ((Term s (PBuiltinList PData :--> PInteger)
forall (list :: (S -> Type) -> S -> Type) (a :: S -> Type)
       (s :: S).
PIsListLike list a =>
Term s (list a :--> PInteger)
plength Term s (PBuiltinList PData :--> PInteger)
-> Term s (PBuiltinList PData) -> Term s PInteger
forall (s :: S) (a :: S -> Type) (b :: S -> Type).
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList PData)
fields) Term s PInteger -> Term s PInteger -> Term s PBool
forall (s :: S). Term s PInteger -> Term s PInteger -> Term s PBool
forall (t :: S -> Type) (s :: S).
PEq t =>
Term s t -> Term s t -> Term s PBool
#== Term s PInteger
2))
        ( forall (a :: S -> Type) (s :: S).
PValidateData a =>
Term s PData -> forall (r :: S -> Type). Term s r -> Term s r
pwithValidated @PTxId (Natural -> Term s (PBuiltinList PData) -> Term s PData
forall (list :: (S -> Type) -> S -> Type) (a :: S -> Type)
       (s :: S).
PIsListLike list a =>
Natural -> Term s (list a) -> Term s a
ptryIndex Natural
0 Term s (PBuiltinList PData)
fields) (Term s r -> Term s r) -> Term s r -> Term s r
forall a b. (a -> b) -> a -> b
$
            Term s PInteger -> (Term s PInteger -> Term s r) -> Term s r
forall (s :: S) (a :: S -> Type) (b :: S -> Type).
Term s a -> (Term s a -> Term s b) -> Term s b
plet (Term s (PData :--> PInteger)
forall (s :: S). Term s (PData :--> PInteger)
pasInt Term s (PData :--> PInteger) -> Term s PData -> Term s PInteger
forall (s :: S) (a :: S -> Type) (b :: S -> Type).
Term s (a :--> b) -> Term s a -> Term s b
# Natural -> Term s (PBuiltinList PData) -> Term s PData
forall (list :: (S -> Type) -> S -> Type) (a :: S -> Type)
       (s :: S).
PIsListLike list a =>
Natural -> Term s (list a) -> Term s a
ptryIndex Natural
1 Term s (PBuiltinList PData)
fields) ((Term s PInteger -> Term s r) -> Term s r)
-> (Term s PInteger -> Term s r) -> Term s r
forall a b. (a -> b) -> a -> b
$ \Term s PInteger
outIdx ->
              Term s PBool -> Term s r -> Term s r -> Term s r
forall (a :: S -> Type) (s :: S).
Term s PBool -> Term s a -> Term s a -> Term s a
pif
                (Term s PInteger
outIdx Term s PInteger -> Term s PInteger -> Term s PBool
forall (s :: S). Term s PInteger -> Term s PInteger -> Term s PBool
forall (t :: S -> Type) (s :: S).
POrd t =>
Term s t -> Term s t -> Term s PBool
#< Term s PInteger
0)
                Term s r
forall (s :: S) (a :: S -> Type). Term s a
perror
                Term s r
x
        )
        Term s r
forall (s :: S) (a :: S -> Type). Term s a
perror