module Cooked.Skeleton.Output
  ( TxSkelOut (..),
    receives,
    txSkelOutValueL,
    txSkelOutDatumL,
    txSkelOutValue,
    txSkelOutValidator,
    txSkelOutOwnerTypeP,
    txSkelOutputDatumTypeAT,
  )
where

import Cooked.Conversion
import Cooked.Output
import Cooked.Skeleton.Datum
import Cooked.Skeleton.Payable
import Cooked.Skeleton.Value
import Cooked.Wallet
import Data.Either.Combinators
import Data.Function
import Optics.Core
import Plutus.Script.Utils.Scripts qualified as Script
import Plutus.Script.Utils.Typed qualified as Script (TypedValidator (..))
import PlutusLedgerApi.V3 qualified as Api
import Type.Reflection

class IsTxSkelOutAllowedOwner a where
  toPKHOrValidator :: a -> Either Api.PubKeyHash (Script.Versioned Script.Validator)

instance IsTxSkelOutAllowedOwner Api.PubKeyHash where
  toPKHOrValidator :: PubKeyHash -> Either PubKeyHash (Versioned Validator)
toPKHOrValidator = PubKeyHash -> Either PubKeyHash (Versioned Validator)
forall a b. a -> Either a b
Left

instance IsTxSkelOutAllowedOwner Wallet where
  toPKHOrValidator :: Wallet -> Either PubKeyHash (Versioned Validator)
toPKHOrValidator = PubKeyHash -> Either PubKeyHash (Versioned Validator)
forall a b. a -> Either a b
Left (PubKeyHash -> Either PubKeyHash (Versioned Validator))
-> (Wallet -> PubKeyHash)
-> Wallet
-> Either PubKeyHash (Versioned Validator)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Wallet -> PubKeyHash
forall a. ToPubKeyHash a => a -> PubKeyHash
toPubKeyHash

instance IsTxSkelOutAllowedOwner (Script.Versioned Script.Validator) where
  toPKHOrValidator :: Versioned Validator -> Either PubKeyHash (Versioned Validator)
toPKHOrValidator = Versioned Validator -> Either PubKeyHash (Versioned Validator)
forall a b. b -> Either a b
Right

instance IsTxSkelOutAllowedOwner (Script.TypedValidator a) where
  toPKHOrValidator :: TypedValidator a -> Either PubKeyHash (Versioned Validator)
toPKHOrValidator = Versioned Validator -> Either PubKeyHash (Versioned Validator)
forall a b. b -> Either a b
Right (Versioned Validator -> Either PubKeyHash (Versioned Validator))
-> (TypedValidator a -> Versioned Validator)
-> TypedValidator a
-> Either PubKeyHash (Versioned Validator)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypedValidator a -> Versioned Validator
forall a. TypedValidator a -> Versioned Validator
Script.tvValidator

instance IsTxSkelOutAllowedOwner (Either Api.PubKeyHash (Script.Versioned Script.Validator)) where
  toPKHOrValidator :: Either PubKeyHash (Versioned Validator)
-> Either PubKeyHash (Versioned Validator)
toPKHOrValidator = Either PubKeyHash (Versioned Validator)
-> Either PubKeyHash (Versioned Validator)
forall a. a -> a
id

-- | Transaction outputs. The 'Pays' constructor is really general, and you'll
-- probably want to use the 'receives' smart constructor in most cases.
data TxSkelOut where
  Pays ::
    ( Show o, -- This is needed only for the 'Show' instance of 'TxSkel', which
    -- in turn is only needed in tests.
      Typeable o,
      IsTxInfoOutput o,
      IsTxSkelOutAllowedOwner (OwnerType o),
      ToCredential (OwnerType o),
      Typeable (OwnerType o),
      DatumType o ~ TxSkelOutDatum,
      ValueType o ~ TxSkelOutValue,
      ToVersionedScript (ReferenceScriptType o),
      Show (OwnerType o),
      Show (ReferenceScriptType o),
      Typeable (ReferenceScriptType o)
    ) =>
    o ->
    TxSkelOut

instance Eq TxSkelOut where
  Pays o
a == :: TxSkelOut -> TxSkelOut -> Bool
== Pays o
b = case o -> TypeRep o
forall a. Typeable a => a -> TypeRep a
typeOf o
a TypeRep o -> TypeRep o -> Maybe (o :~~: o)
forall k1 k2 (a :: k1) (b :: k2).
TypeRep a -> TypeRep b -> Maybe (a :~~: b)
`eqTypeRep` o -> TypeRep o
forall a. Typeable a => a -> TypeRep a
typeOf o
b of
    Just o :~~: o
HRefl -> o -> TxOut
forall o. IsTxInfoOutput o => o -> TxOut
outputTxOut o
a TxOut -> TxOut -> Bool
forall a. Eq a => a -> a -> Bool
== o -> TxOut
forall o. IsTxInfoOutput o => o -> TxOut
outputTxOut o
b
    Maybe (o :~~: o)
Nothing -> Bool
False

deriving instance Show TxSkelOut

-- | Smart constructor to build @TxSkelOut@ from an owner and payment. This
-- should be the main way of building outputs.
receives :: (Show owner, Typeable owner, IsTxSkelOutAllowedOwner owner, ToCredential owner) => owner -> Payable els -> TxSkelOut
receives :: forall owner (els :: [Symbol]).
(Show owner, Typeable owner, IsTxSkelOutAllowedOwner owner,
 ToCredential owner) =>
owner -> Payable els -> TxSkelOut
receives owner
owner =
  TxSkelOut -> Payable els -> TxSkelOut
forall (els :: [Symbol]). TxSkelOut -> Payable els -> TxSkelOut
go (TxSkelOut -> Payable els -> TxSkelOut)
-> TxSkelOut -> Payable els -> TxSkelOut
forall a b. (a -> b) -> a -> b
$
    ConcreteOutput
  owner TxSkelOutDatum TxSkelOutValue (Versioned Script)
-> TxSkelOut
forall o.
(Show o, Typeable o, IsTxInfoOutput o,
 IsTxSkelOutAllowedOwner (OwnerType o), ToCredential (OwnerType o),
 Typeable (OwnerType o), DatumType o ~ TxSkelOutDatum,
 ValueType o ~ TxSkelOutValue,
 ToVersionedScript (ReferenceScriptType o), Show (OwnerType o),
 Show (ReferenceScriptType o), Typeable (ReferenceScriptType o)) =>
o -> TxSkelOut
Pays (ConcreteOutput
   owner TxSkelOutDatum TxSkelOutValue (Versioned Script)
 -> TxSkelOut)
-> ConcreteOutput
     owner TxSkelOutDatum TxSkelOutValue (Versioned Script)
-> TxSkelOut
forall a b. (a -> b) -> a -> b
$
      owner
-> Maybe StakingCredential
-> TxSkelOutDatum
-> TxSkelOutValue
-> Maybe (Versioned Script)
-> ConcreteOutput
     owner TxSkelOutDatum TxSkelOutValue (Versioned Script)
forall ownerType datumType valueType referenceScriptType.
ownerType
-> Maybe StakingCredential
-> datumType
-> valueType
-> Maybe referenceScriptType
-> ConcreteOutput ownerType datumType valueType referenceScriptType
ConcreteOutput
        owner
owner
        Maybe StakingCredential
forall a. Maybe a
Nothing -- No staking credential by default
        TxSkelOutDatum
TxSkelOutNoDatum -- No datum by default
        (Value -> Bool -> TxSkelOutValue
TxSkelOutValue Value
forall a. Monoid a => a
mempty Bool
True) -- Empty value by default, adjustable to min ada
        (forall a. Maybe a
Nothing @(Script.Versioned Script.Script)) -- No reference script by default
  where
    go :: TxSkelOut -> Payable els -> TxSkelOut
    go :: forall (els :: [Symbol]). TxSkelOut -> Payable els -> TxSkelOut
go (Pays o
output) (VisibleHashedDatum a1
dat) = ConcreteOutput
  (OwnerType o) TxSkelOutDatum TxSkelOutValue (ReferenceScriptType o)
-> TxSkelOut
forall o.
(Show o, Typeable o, IsTxInfoOutput o,
 IsTxSkelOutAllowedOwner (OwnerType o), ToCredential (OwnerType o),
 Typeable (OwnerType o), DatumType o ~ TxSkelOutDatum,
 ValueType o ~ TxSkelOutValue,
 ToVersionedScript (ReferenceScriptType o), Show (OwnerType o),
 Show (ReferenceScriptType o), Typeable (ReferenceScriptType o)) =>
o -> TxSkelOut
Pays (ConcreteOutput
   (OwnerType o) TxSkelOutDatum TxSkelOutValue (ReferenceScriptType o)
 -> TxSkelOut)
-> ConcreteOutput
     (OwnerType o) TxSkelOutDatum TxSkelOutValue (ReferenceScriptType o)
-> TxSkelOut
forall a b. (a -> b) -> a -> b
$ o
-> TxSkelOutDatum
-> ConcreteOutput
     (OwnerType o) TxSkelOutDatum (ValueType o) (ReferenceScriptType o)
forall out dat.
IsAbstractOutput out =>
out
-> dat
-> ConcreteOutput
     (OwnerType out) dat (ValueType out) (ReferenceScriptType out)
setDatum o
output (TxSkelOutDatum
 -> ConcreteOutput
      (OwnerType o) TxSkelOutDatum (ValueType o) (ReferenceScriptType o))
-> TxSkelOutDatum
-> ConcreteOutput
     (OwnerType o) TxSkelOutDatum (ValueType o) (ReferenceScriptType o)
forall a b. (a -> b) -> a -> b
$ a1 -> TxSkelOutDatum
forall a. TxSkelOutDatumConstrs a => a -> TxSkelOutDatum
TxSkelOutDatum a1
dat
    go (Pays o
output) (InlineDatum a1
dat) = ConcreteOutput
  (OwnerType o) TxSkelOutDatum TxSkelOutValue (ReferenceScriptType o)
-> TxSkelOut
forall o.
(Show o, Typeable o, IsTxInfoOutput o,
 IsTxSkelOutAllowedOwner (OwnerType o), ToCredential (OwnerType o),
 Typeable (OwnerType o), DatumType o ~ TxSkelOutDatum,
 ValueType o ~ TxSkelOutValue,
 ToVersionedScript (ReferenceScriptType o), Show (OwnerType o),
 Show (ReferenceScriptType o), Typeable (ReferenceScriptType o)) =>
o -> TxSkelOut
Pays (ConcreteOutput
   (OwnerType o) TxSkelOutDatum TxSkelOutValue (ReferenceScriptType o)
 -> TxSkelOut)
-> ConcreteOutput
     (OwnerType o) TxSkelOutDatum TxSkelOutValue (ReferenceScriptType o)
-> TxSkelOut
forall a b. (a -> b) -> a -> b
$ o
-> TxSkelOutDatum
-> ConcreteOutput
     (OwnerType o) TxSkelOutDatum (ValueType o) (ReferenceScriptType o)
forall out dat.
IsAbstractOutput out =>
out
-> dat
-> ConcreteOutput
     (OwnerType out) dat (ValueType out) (ReferenceScriptType out)
setDatum o
output (TxSkelOutDatum
 -> ConcreteOutput
      (OwnerType o) TxSkelOutDatum (ValueType o) (ReferenceScriptType o))
-> TxSkelOutDatum
-> ConcreteOutput
     (OwnerType o) TxSkelOutDatum (ValueType o) (ReferenceScriptType o)
forall a b. (a -> b) -> a -> b
$ a1 -> TxSkelOutDatum
forall a. TxSkelOutDatumConstrs a => a -> TxSkelOutDatum
TxSkelOutInlineDatum a1
dat
    go (Pays o
output) (HiddenHashedDatum a1
dat) = ConcreteOutput
  (OwnerType o) TxSkelOutDatum TxSkelOutValue (ReferenceScriptType o)
-> TxSkelOut
forall o.
(Show o, Typeable o, IsTxInfoOutput o,
 IsTxSkelOutAllowedOwner (OwnerType o), ToCredential (OwnerType o),
 Typeable (OwnerType o), DatumType o ~ TxSkelOutDatum,
 ValueType o ~ TxSkelOutValue,
 ToVersionedScript (ReferenceScriptType o), Show (OwnerType o),
 Show (ReferenceScriptType o), Typeable (ReferenceScriptType o)) =>
o -> TxSkelOut
Pays (ConcreteOutput
   (OwnerType o) TxSkelOutDatum TxSkelOutValue (ReferenceScriptType o)
 -> TxSkelOut)
-> ConcreteOutput
     (OwnerType o) TxSkelOutDatum TxSkelOutValue (ReferenceScriptType o)
-> TxSkelOut
forall a b. (a -> b) -> a -> b
$ o
-> TxSkelOutDatum
-> ConcreteOutput
     (OwnerType o) TxSkelOutDatum (ValueType o) (ReferenceScriptType o)
forall out dat.
IsAbstractOutput out =>
out
-> dat
-> ConcreteOutput
     (OwnerType out) dat (ValueType out) (ReferenceScriptType out)
setDatum o
output (TxSkelOutDatum
 -> ConcreteOutput
      (OwnerType o) TxSkelOutDatum (ValueType o) (ReferenceScriptType o))
-> TxSkelOutDatum
-> ConcreteOutput
     (OwnerType o) TxSkelOutDatum (ValueType o) (ReferenceScriptType o)
forall a b. (a -> b) -> a -> b
$ a1 -> TxSkelOutDatum
forall a. TxSkelOutDatumConstrs a => a -> TxSkelOutDatum
TxSkelOutDatumHash a1
dat
    go (Pays o
output) (FixedValue a1
v) = ConcreteOutput
  (OwnerType o) TxSkelOutDatum TxSkelOutValue (ReferenceScriptType o)
-> TxSkelOut
forall o.
(Show o, Typeable o, IsTxInfoOutput o,
 IsTxSkelOutAllowedOwner (OwnerType o), ToCredential (OwnerType o),
 Typeable (OwnerType o), DatumType o ~ TxSkelOutDatum,
 ValueType o ~ TxSkelOutValue,
 ToVersionedScript (ReferenceScriptType o), Show (OwnerType o),
 Show (ReferenceScriptType o), Typeable (ReferenceScriptType o)) =>
o -> TxSkelOut
Pays (ConcreteOutput
   (OwnerType o) TxSkelOutDatum TxSkelOutValue (ReferenceScriptType o)
 -> TxSkelOut)
-> ConcreteOutput
     (OwnerType o) TxSkelOutDatum TxSkelOutValue (ReferenceScriptType o)
-> TxSkelOut
forall a b. (a -> b) -> a -> b
$ o
-> TxSkelOutValue
-> ConcreteOutput
     (OwnerType o) (DatumType o) TxSkelOutValue (ReferenceScriptType o)
forall out val.
IsAbstractOutput out =>
out
-> val
-> ConcreteOutput
     (OwnerType out) (DatumType out) val (ReferenceScriptType out)
setValue o
output (TxSkelOutValue
 -> ConcreteOutput
      (OwnerType o) (DatumType o) TxSkelOutValue (ReferenceScriptType o))
-> TxSkelOutValue
-> ConcreteOutput
     (OwnerType o) (DatumType o) TxSkelOutValue (ReferenceScriptType o)
forall a b. (a -> b) -> a -> b
$ Value -> Bool -> TxSkelOutValue
TxSkelOutValue (a1 -> Value
forall a. ToValue a => a -> Value
toValue a1
v) Bool
False
    go (Pays o
output) (Value a1
v) = ConcreteOutput
  (OwnerType o) TxSkelOutDatum TxSkelOutValue (ReferenceScriptType o)
-> TxSkelOut
forall o.
(Show o, Typeable o, IsTxInfoOutput o,
 IsTxSkelOutAllowedOwner (OwnerType o), ToCredential (OwnerType o),
 Typeable (OwnerType o), DatumType o ~ TxSkelOutDatum,
 ValueType o ~ TxSkelOutValue,
 ToVersionedScript (ReferenceScriptType o), Show (OwnerType o),
 Show (ReferenceScriptType o), Typeable (ReferenceScriptType o)) =>
o -> TxSkelOut
Pays (ConcreteOutput
   (OwnerType o) TxSkelOutDatum TxSkelOutValue (ReferenceScriptType o)
 -> TxSkelOut)
-> ConcreteOutput
     (OwnerType o) TxSkelOutDatum TxSkelOutValue (ReferenceScriptType o)
-> TxSkelOut
forall a b. (a -> b) -> a -> b
$ o
-> TxSkelOutValue
-> ConcreteOutput
     (OwnerType o) (DatumType o) TxSkelOutValue (ReferenceScriptType o)
forall out val.
IsAbstractOutput out =>
out
-> val
-> ConcreteOutput
     (OwnerType out) (DatumType out) val (ReferenceScriptType out)
setValue o
output (TxSkelOutValue
 -> ConcreteOutput
      (OwnerType o) (DatumType o) TxSkelOutValue (ReferenceScriptType o))
-> TxSkelOutValue
-> ConcreteOutput
     (OwnerType o) (DatumType o) TxSkelOutValue (ReferenceScriptType o)
forall a b. (a -> b) -> a -> b
$ Value -> Bool -> TxSkelOutValue
TxSkelOutValue (a1 -> Value
forall a. ToValue a => a -> Value
toValue a1
v) Bool
True
    go (Pays o
output) (ReferenceScript s
script) = ConcreteOutput
  (OwnerType o) TxSkelOutDatum TxSkelOutValue (Versioned Script)
-> TxSkelOut
forall o.
(Show o, Typeable o, IsTxInfoOutput o,
 IsTxSkelOutAllowedOwner (OwnerType o), ToCredential (OwnerType o),
 Typeable (OwnerType o), DatumType o ~ TxSkelOutDatum,
 ValueType o ~ TxSkelOutValue,
 ToVersionedScript (ReferenceScriptType o), Show (OwnerType o),
 Show (ReferenceScriptType o), Typeable (ReferenceScriptType o)) =>
o -> TxSkelOut
Pays (ConcreteOutput
   (OwnerType o) TxSkelOutDatum TxSkelOutValue (Versioned Script)
 -> TxSkelOut)
-> ConcreteOutput
     (OwnerType o) TxSkelOutDatum TxSkelOutValue (Versioned Script)
-> TxSkelOut
forall a b. (a -> b) -> a -> b
$ o
-> Versioned Script
-> ConcreteOutput
     (OwnerType o) (DatumType o) (ValueType o) (Versioned Script)
forall out ref.
IsAbstractOutput out =>
out
-> ref
-> ConcreteOutput
     (OwnerType out) (DatumType out) (ValueType out) ref
setReferenceScript o
output (Versioned Script
 -> ConcreteOutput
      (OwnerType o) (DatumType o) (ValueType o) (Versioned Script))
-> Versioned Script
-> ConcreteOutput
     (OwnerType o) (DatumType o) (ValueType o) (Versioned Script)
forall a b. (a -> b) -> a -> b
$ s -> Versioned Script
forall a. ToVersionedScript a => a -> Versioned Script
toVersionedScript s
script
    go (Pays o
output) (StakingCredential (cred -> Maybe StakingCredential
forall a.
ToMaybeStakingCredential a =>
a -> Maybe StakingCredential
toMaybeStakingCredential -> Just StakingCredential
stCred)) = ConcreteOutput
  (OwnerType o) TxSkelOutDatum TxSkelOutValue (ReferenceScriptType o)
-> TxSkelOut
forall o.
(Show o, Typeable o, IsTxInfoOutput o,
 IsTxSkelOutAllowedOwner (OwnerType o), ToCredential (OwnerType o),
 Typeable (OwnerType o), DatumType o ~ TxSkelOutDatum,
 ValueType o ~ TxSkelOutValue,
 ToVersionedScript (ReferenceScriptType o), Show (OwnerType o),
 Show (ReferenceScriptType o), Typeable (ReferenceScriptType o)) =>
o -> TxSkelOut
Pays (ConcreteOutput
   (OwnerType o) TxSkelOutDatum TxSkelOutValue (ReferenceScriptType o)
 -> TxSkelOut)
-> ConcreteOutput
     (OwnerType o) TxSkelOutDatum TxSkelOutValue (ReferenceScriptType o)
-> TxSkelOut
forall a b. (a -> b) -> a -> b
$ o
-> StakingCredential
-> ConcreteOutput
     (OwnerType o) (DatumType o) (ValueType o) (ReferenceScriptType o)
forall out.
IsAbstractOutput out =>
out
-> StakingCredential
-> ConcreteOutput
     (OwnerType out)
     (DatumType out)
     (ValueType out)
     (ReferenceScriptType out)
setStakingCredential o
output StakingCredential
stCred
    go TxSkelOut
pays (StakingCredential cred
_) = TxSkelOut
pays
    go TxSkelOut
pays (PayableAnd Payable els
p1 Payable els'
p2) = TxSkelOut -> Payable els' -> TxSkelOut
forall (els :: [Symbol]). TxSkelOut -> Payable els -> TxSkelOut
go (TxSkelOut -> Payable els -> TxSkelOut
forall (els :: [Symbol]). TxSkelOut -> Payable els -> TxSkelOut
go TxSkelOut
pays Payable els
p1) Payable els'
p2

txSkelOutDatumL :: Lens' TxSkelOut TxSkelOutDatum
txSkelOutDatumL :: Lens' TxSkelOut TxSkelOutDatum
txSkelOutDatumL =
  (TxSkelOut -> TxSkelOutDatum)
-> (TxSkelOut -> TxSkelOutDatum -> TxSkelOut)
-> Lens' TxSkelOut TxSkelOutDatum
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens
    (\(Pays o
output) -> o
output o -> Optic' A_Lens NoIx o TxSkelOutDatum -> TxSkelOutDatum
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Lens' o (DatumType o)
Optic' A_Lens NoIx o TxSkelOutDatum
forall o. IsAbstractOutput o => Lens' o (DatumType o)
outputDatumL)
    (\(Pays o
output) TxSkelOutDatum
newDatum -> o -> TxSkelOut
forall o.
(Show o, Typeable o, IsTxInfoOutput o,
 IsTxSkelOutAllowedOwner (OwnerType o), ToCredential (OwnerType o),
 Typeable (OwnerType o), DatumType o ~ TxSkelOutDatum,
 ValueType o ~ TxSkelOutValue,
 ToVersionedScript (ReferenceScriptType o), Show (OwnerType o),
 Show (ReferenceScriptType o), Typeable (ReferenceScriptType o)) =>
o -> TxSkelOut
Pays (o -> TxSkelOut) -> o -> TxSkelOut
forall a b. (a -> b) -> a -> b
$ o
output o -> (o -> o) -> o
forall a b. a -> (a -> b) -> b
& Lens' o (DatumType o)
Optic A_Lens NoIx o o TxSkelOutDatum TxSkelOutDatum
forall o. IsAbstractOutput o => Lens' o (DatumType o)
outputDatumL Optic A_Lens NoIx o o TxSkelOutDatum TxSkelOutDatum
-> TxSkelOutDatum -> o -> o
forall k (is :: IxList) s t a b.
Is k A_Setter =>
Optic k is s t a b -> b -> s -> t
.~ TxSkelOutDatum
newDatum)

txSkelOutValueL :: Lens' TxSkelOut TxSkelOutValue
txSkelOutValueL :: Lens' TxSkelOut TxSkelOutValue
txSkelOutValueL =
  (TxSkelOut -> TxSkelOutValue)
-> (TxSkelOut -> TxSkelOutValue -> TxSkelOut)
-> Lens' TxSkelOut TxSkelOutValue
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens
    (\(Pays o
output) -> o
output o -> Optic' A_Lens NoIx o TxSkelOutValue -> TxSkelOutValue
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx o TxSkelOutValue
Lens' o (ValueType o)
forall o. IsAbstractOutput o => Lens' o (ValueType o)
outputValueL)
    (\(Pays o
output) TxSkelOutValue
newValue -> o -> TxSkelOut
forall o.
(Show o, Typeable o, IsTxInfoOutput o,
 IsTxSkelOutAllowedOwner (OwnerType o), ToCredential (OwnerType o),
 Typeable (OwnerType o), DatumType o ~ TxSkelOutDatum,
 ValueType o ~ TxSkelOutValue,
 ToVersionedScript (ReferenceScriptType o), Show (OwnerType o),
 Show (ReferenceScriptType o), Typeable (ReferenceScriptType o)) =>
o -> TxSkelOut
Pays (o -> TxSkelOut) -> o -> TxSkelOut
forall a b. (a -> b) -> a -> b
$ o
output o -> (o -> o) -> o
forall a b. a -> (a -> b) -> b
& Optic A_Lens NoIx o o TxSkelOutValue TxSkelOutValue
Lens' o (ValueType o)
forall o. IsAbstractOutput o => Lens' o (ValueType o)
outputValueL Optic A_Lens NoIx o o TxSkelOutValue TxSkelOutValue
-> TxSkelOutValue -> o -> o
forall k (is :: IxList) s t a b.
Is k A_Setter =>
Optic k is s t a b -> b -> s -> t
.~ TxSkelOutValue
newValue)

txSkelOutValue :: TxSkelOut -> Api.Value
txSkelOutValue :: TxSkelOut -> Value
txSkelOutValue = (TxSkelOut -> Optic' A_Lens NoIx TxSkelOut Value -> Value
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. (Lens' TxSkelOut TxSkelOutValue
txSkelOutValueL Lens' TxSkelOut TxSkelOutValue
-> Optic A_Lens NoIx TxSkelOutValue TxSkelOutValue Value Value
-> Optic' A_Lens NoIx TxSkelOut Value
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Optic A_Lens NoIx TxSkelOutValue TxSkelOutValue Value Value
txSkelOutValueContentL))

txSkelOutValidator :: TxSkelOut -> Maybe (Script.Versioned Script.Validator)
txSkelOutValidator :: TxSkelOut -> Maybe (Versioned Validator)
txSkelOutValidator (Pays o
output) = Either PubKeyHash (Versioned Validator)
-> Maybe (Versioned Validator)
forall a b. Either a b -> Maybe b
rightToMaybe (OwnerType o -> Either PubKeyHash (Versioned Validator)
forall a.
IsTxSkelOutAllowedOwner a =>
a -> Either PubKeyHash (Versioned Validator)
toPKHOrValidator (OwnerType o -> Either PubKeyHash (Versioned Validator))
-> OwnerType o -> Either PubKeyHash (Versioned Validator)
forall a b. (a -> b) -> a -> b
$ o
output o -> Optic' A_Lens NoIx o (OwnerType o) -> OwnerType o
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx o (OwnerType o)
forall o. IsAbstractOutput o => Lens' o (OwnerType o)
outputOwnerL)

-- | Decide if a transaction output has a certain owner and datum type.
txSkelOutOwnerTypeP ::
  forall ownerType.
  ( ToCredential ownerType,
    Show ownerType,
    IsTxSkelOutAllowedOwner ownerType,
    Typeable ownerType
  ) =>
  Prism' TxSkelOut (ConcreteOutput ownerType TxSkelOutDatum TxSkelOutValue (Script.Versioned Script.Script))
txSkelOutOwnerTypeP :: forall ownerType.
(ToCredential ownerType, Show ownerType,
 IsTxSkelOutAllowedOwner ownerType, Typeable ownerType) =>
Prism'
  TxSkelOut
  (ConcreteOutput
     ownerType TxSkelOutDatum TxSkelOutValue (Versioned Script))
txSkelOutOwnerTypeP =
  (ConcreteOutput
   ownerType TxSkelOutDatum TxSkelOutValue (Versioned Script)
 -> TxSkelOut)
-> (TxSkelOut
    -> Maybe
         (ConcreteOutput
            ownerType TxSkelOutDatum TxSkelOutValue (Versioned Script)))
-> Prism
     TxSkelOut
     TxSkelOut
     (ConcreteOutput
        ownerType TxSkelOutDatum TxSkelOutValue (Versioned Script))
     (ConcreteOutput
        ownerType TxSkelOutDatum TxSkelOutValue (Versioned Script))
forall b s a. (b -> s) -> (s -> Maybe a) -> Prism s s a b
prism'
    ConcreteOutput
  ownerType TxSkelOutDatum TxSkelOutValue (Versioned Script)
-> TxSkelOut
forall o.
(Show o, Typeable o, IsTxInfoOutput o,
 IsTxSkelOutAllowedOwner (OwnerType o), ToCredential (OwnerType o),
 Typeable (OwnerType o), DatumType o ~ TxSkelOutDatum,
 ValueType o ~ TxSkelOutValue,
 ToVersionedScript (ReferenceScriptType o), Show (OwnerType o),
 Show (ReferenceScriptType o), Typeable (ReferenceScriptType o)) =>
o -> TxSkelOut
Pays
    ( \(Pays o
output) ->
        case OwnerType o -> TypeRep (OwnerType o)
forall a. Typeable a => a -> TypeRep a
typeOf (o
output o -> Optic' A_Lens NoIx o (OwnerType o) -> OwnerType o
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx o (OwnerType o)
forall o. IsAbstractOutput o => Lens' o (OwnerType o)
outputOwnerL) TypeRep (OwnerType o)
-> TypeRep ownerType -> Maybe (OwnerType o :~~: ownerType)
forall k1 k2 (a :: k1) (b :: k2).
TypeRep a -> TypeRep b -> Maybe (a :~~: b)
`eqTypeRep` forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @ownerType of
          Just OwnerType o :~~: ownerType
HRefl ->
            let cOut :: ConcreteOutput
  (OwnerType o) (DatumType o) (ValueType o) (ReferenceScriptType o)
cOut = o
-> ConcreteOutput
     (OwnerType o) (DatumType o) (ValueType o) (ReferenceScriptType o)
forall out.
IsAbstractOutput out =>
out
-> ConcreteOutput
     (OwnerType out)
     (DatumType out)
     (ValueType out)
     (ReferenceScriptType out)
fromAbstractOutput o
output
             in ConcreteOutput
  ownerType TxSkelOutDatum TxSkelOutValue (Versioned Script)
-> Maybe
     (ConcreteOutput
        ownerType TxSkelOutDatum TxSkelOutValue (Versioned Script))
forall a. a -> Maybe a
Just (ConcreteOutput
   ownerType TxSkelOutDatum TxSkelOutValue (Versioned Script)
 -> Maybe
      (ConcreteOutput
         ownerType TxSkelOutDatum TxSkelOutValue (Versioned Script)))
-> ConcreteOutput
     ownerType TxSkelOutDatum TxSkelOutValue (Versioned Script)
-> Maybe
     (ConcreteOutput
        ownerType TxSkelOutDatum TxSkelOutValue (Versioned Script))
forall a b. (a -> b) -> a -> b
$ ConcreteOutput
  (OwnerType o) (DatumType o) (ValueType o) (ReferenceScriptType o)
cOut {concreteOutputReferenceScript = toVersionedScript <$> concreteOutputReferenceScript cOut}
          Maybe (OwnerType o :~~: ownerType)
Nothing -> Maybe
  (ConcreteOutput
     ownerType TxSkelOutDatum TxSkelOutValue (Versioned Script))
forall a. Maybe a
Nothing
    )

txSkelOutputDatumTypeAT ::
  (Api.FromData a, Typeable a) =>
  AffineTraversal' TxSkelOut a
txSkelOutputDatumTypeAT :: forall a. (FromData a, Typeable a) => AffineTraversal' TxSkelOut a
txSkelOutputDatumTypeAT =
  (TxSkelOut -> Either TxSkelOut a)
-> (TxSkelOut -> a -> TxSkelOut)
-> AffineTraversal TxSkelOut TxSkelOut a a
forall s t a b.
(s -> Either t a) -> (s -> b -> t) -> AffineTraversal s t a b
atraversal
    ( \TxSkelOut
txSkelOut -> case TxSkelOut -> Maybe Datum
txSkelOutDatumComplete TxSkelOut
txSkelOut of
        Maybe Datum
Nothing -> TxSkelOut -> Either TxSkelOut a
forall a b. a -> Either a b
Left TxSkelOut
txSkelOut
        Just (Api.Datum BuiltinData
datum) -> case BuiltinData -> Maybe a
forall a. FromData a => BuiltinData -> Maybe a
Api.fromBuiltinData BuiltinData
datum of
          Just a
tyDatum -> a -> Either TxSkelOut a
forall a b. b -> Either a b
Right a
tyDatum
          Maybe a
Nothing -> TxSkelOut -> Either TxSkelOut a
forall a b. a -> Either a b
Left TxSkelOut
txSkelOut
    )
    ( \(Pays o
output) a
newTyDatum ->
        o -> TxSkelOut
forall o.
(Show o, Typeable o, IsTxInfoOutput o,
 IsTxSkelOutAllowedOwner (OwnerType o), ToCredential (OwnerType o),
 Typeable (OwnerType o), DatumType o ~ TxSkelOutDatum,
 ValueType o ~ TxSkelOutValue,
 ToVersionedScript (ReferenceScriptType o), Show (OwnerType o),
 Show (ReferenceScriptType o), Typeable (ReferenceScriptType o)) =>
o -> TxSkelOut
Pays (o -> TxSkelOut) -> o -> TxSkelOut
forall a b. (a -> b) -> a -> b
$
          Optic A_Lens NoIx o o TxSkelOutDatum TxSkelOutDatum
-> (TxSkelOutDatum -> TxSkelOutDatum) -> o -> o
forall k (is :: IxList) s t a b.
Is k A_Setter =>
Optic k is s t a b -> (a -> b) -> s -> t
over
            Lens' o (DatumType o)
Optic A_Lens NoIx o o TxSkelOutDatum TxSkelOutDatum
forall o. IsAbstractOutput o => Lens' o (DatumType o)
outputDatumL
            ( \case
                TxSkelOutDatum
TxSkelOutNoDatum -> TxSkelOutDatum
TxSkelOutNoDatum
                TxSkelOutDatum a
tyDatum -> a -> TxSkelOutDatum
forall a. TxSkelOutDatumConstrs a => a -> TxSkelOutDatum
TxSkelOutDatum (a -> TxSkelOutDatum) -> a -> TxSkelOutDatum
forall a b. (a -> b) -> a -> b
$ a -> a -> a
forall b a. (Typeable b, Typeable a) => b -> a -> b
replaceDatumOnCorrectType a
tyDatum a
newTyDatum
                TxSkelOutDatumHash a
tyDatum -> a -> TxSkelOutDatum
forall a. TxSkelOutDatumConstrs a => a -> TxSkelOutDatum
TxSkelOutDatumHash (a -> TxSkelOutDatum) -> a -> TxSkelOutDatum
forall a b. (a -> b) -> a -> b
$ a -> a -> a
forall b a. (Typeable b, Typeable a) => b -> a -> b
replaceDatumOnCorrectType a
tyDatum a
newTyDatum
                TxSkelOutInlineDatum a
tyDatum -> a -> TxSkelOutDatum
forall a. TxSkelOutDatumConstrs a => a -> TxSkelOutDatum
TxSkelOutInlineDatum (a -> TxSkelOutDatum) -> a -> TxSkelOutDatum
forall a b. (a -> b) -> a -> b
$ a -> a -> a
forall b a. (Typeable b, Typeable a) => b -> a -> b
replaceDatumOnCorrectType a
tyDatum a
newTyDatum
            )
            o
output
    )
  where
    replaceDatumOnCorrectType :: (Typeable b, Typeable a) => b -> a -> b
    replaceDatumOnCorrectType :: forall b a. (Typeable b, Typeable a) => b -> a -> b
replaceDatumOnCorrectType b
old a
new = case b -> TypeRep b
forall a. Typeable a => a -> TypeRep a
typeOf b
old TypeRep b -> TypeRep a -> Maybe (b :~~: a)
forall k1 k2 (a :: k1) (b :: k2).
TypeRep a -> TypeRep b -> Maybe (a :~~: b)
`eqTypeRep` a -> TypeRep a
forall a. Typeable a => a -> TypeRep a
typeOf a
new of
      Just b :~~: a
HRefl -> b
a
new
      Maybe (b :~~: a)
Nothing -> b
old

    txSkelOutDatumComplete :: TxSkelOut -> Maybe Api.Datum
    txSkelOutDatumComplete :: TxSkelOut -> Maybe Datum
txSkelOutDatumComplete (Pays o
output) = TxSkelOutDatum -> Maybe Datum
txSkelOutUntypedDatum (TxSkelOutDatum -> Maybe Datum) -> TxSkelOutDatum -> Maybe Datum
forall a b. (a -> b) -> a -> b
$ o
output o -> Optic' A_Lens NoIx o TxSkelOutDatum -> TxSkelOutDatum
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Lens' o (DatumType o)
Optic' A_Lens NoIx o TxSkelOutDatum
forall o. IsAbstractOutput o => Lens' o (DatumType o)
outputDatumL