-- | This module exposes the outputs constructs used in a
-- 'Cooked.Skeleton.TxSkel' and their associated utilities. To build payments in
-- a skeleton, the usual way is to invoke @txSkelIns = [pk `receives` Value v,
-- script `receives` (InlineDatum dat <&&> ReferenceScript script)]@
module Cooked.Skeleton.Output
  ( -- * Type constraints
    IsTxSkelOutAllowedOwner (..),

    -- * Data types
    PayableKind (..),
    Payable (..),
    TxSkelOut (..),

    -- * Optics
    txSkelOutValueL,
    txSkelOutValueAutoAdjustL,
    txSkelOutDatumL,
    txSkelOutMReferenceScriptL,
    txSkelOutReferenceScriptAT,
    txSkelOutMStakingCredentialL,
    txSkelOutStakingCredentialAT,
    txSkelOutCredentialG,
    txSkelOutAddressG,
    txSkelOutReferenceScriptHashAF,
    txSkelOutOwnerL,

    -- * Smart constructors
    (<&&>),
    receives,
  )
where

import Cooked.Skeleton.Datum
import Cooked.Skeleton.Families
import Cooked.Skeleton.User
import Cooked.Skeleton.Value ()
import Cooked.Wallet
import Data.Kind
import Data.Typeable
import Optics.Core
import Optics.TH (makeLensesFor)
import Plutus.Script.Utils.Address qualified as Script
import Plutus.Script.Utils.Scripts qualified as Script
import Plutus.Script.Utils.V1.Typed qualified as Script (TypedValidator (..))
import Plutus.Script.Utils.V3.Typed qualified as Script
import Plutus.Script.Utils.Value qualified as Script
import PlutusLedgerApi.V1.Value qualified as Api
import PlutusLedgerApi.V3 qualified as Api

-- * Definition of 'Cooked.Skeleton.TxSkel' outputs

-- | An output to be put into a 'Cooked.Skeleton.TxSkel'
data TxSkelOut where
  TxSkelOut ::
    { -- The owner of this payment
      TxSkelOut -> User 'IsEither 'Allocation
txSkelOutOwner :: User IsEither Allocation,
      -- What staking credential should be attached to this payment
      TxSkelOut -> Maybe StakingCredential
txSkelOutStakingCredential :: Maybe Api.StakingCredential,
      -- What datum should be placed in this payment
      TxSkelOut -> TxSkelOutDatum
txSkelOutDatum :: TxSkelOutDatum,
      -- What value should be paid
      TxSkelOut -> Value
txSkelOutValue :: Api.Value,
      -- Whether the paid value can be auto-adjusted for min ADA
      TxSkelOut -> Bool
txSkelOutValueAutoAdjust :: Bool,
      -- What reference script should be attached to this payment
      TxSkelOut -> Maybe VScript
txSkelOutReferenceScript :: Maybe VScript
    } ->
    TxSkelOut
  deriving (TxSkelOut -> TxSkelOut -> Bool
(TxSkelOut -> TxSkelOut -> Bool)
-> (TxSkelOut -> TxSkelOut -> Bool) -> Eq TxSkelOut
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TxSkelOut -> TxSkelOut -> Bool
== :: TxSkelOut -> TxSkelOut -> Bool
$c/= :: TxSkelOut -> TxSkelOut -> Bool
/= :: TxSkelOut -> TxSkelOut -> Bool
Eq, Eq TxSkelOut
Eq TxSkelOut =>
(TxSkelOut -> TxSkelOut -> Ordering)
-> (TxSkelOut -> TxSkelOut -> Bool)
-> (TxSkelOut -> TxSkelOut -> Bool)
-> (TxSkelOut -> TxSkelOut -> Bool)
-> (TxSkelOut -> TxSkelOut -> Bool)
-> (TxSkelOut -> TxSkelOut -> TxSkelOut)
-> (TxSkelOut -> TxSkelOut -> TxSkelOut)
-> Ord TxSkelOut
TxSkelOut -> TxSkelOut -> Bool
TxSkelOut -> TxSkelOut -> Ordering
TxSkelOut -> TxSkelOut -> TxSkelOut
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: TxSkelOut -> TxSkelOut -> Ordering
compare :: TxSkelOut -> TxSkelOut -> Ordering
$c< :: TxSkelOut -> TxSkelOut -> Bool
< :: TxSkelOut -> TxSkelOut -> Bool
$c<= :: TxSkelOut -> TxSkelOut -> Bool
<= :: TxSkelOut -> TxSkelOut -> Bool
$c> :: TxSkelOut -> TxSkelOut -> Bool
> :: TxSkelOut -> TxSkelOut -> Bool
$c>= :: TxSkelOut -> TxSkelOut -> Bool
>= :: TxSkelOut -> TxSkelOut -> Bool
$cmax :: TxSkelOut -> TxSkelOut -> TxSkelOut
max :: TxSkelOut -> TxSkelOut -> TxSkelOut
$cmin :: TxSkelOut -> TxSkelOut -> TxSkelOut
min :: TxSkelOut -> TxSkelOut -> TxSkelOut
Ord, Int -> TxSkelOut -> ShowS
[TxSkelOut] -> ShowS
TxSkelOut -> String
(Int -> TxSkelOut -> ShowS)
-> (TxSkelOut -> String)
-> ([TxSkelOut] -> ShowS)
-> Show TxSkelOut
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TxSkelOut -> ShowS
showsPrec :: Int -> TxSkelOut -> ShowS
$cshow :: TxSkelOut -> String
show :: TxSkelOut -> String
$cshowList :: [TxSkelOut] -> ShowS
showList :: [TxSkelOut] -> ShowS
Show)

-- * Optics focusing on the reference script of a 'TxSkelOut'

-- | Focuses on the @Maybe VScript@ corresponding to the possible reference
-- script contained in this 'TxSkelOut'
makeLensesFor [("txSkelOutReferenceScript", "txSkelOutMReferenceScriptL")] ''TxSkelOut

-- | Focuses on the reference script of this 'TxSkelOut'
txSkelOutReferenceScriptAT :: AffineTraversal' TxSkelOut VScript
txSkelOutReferenceScriptAT :: AffineTraversal' TxSkelOut VScript
txSkelOutReferenceScriptAT = Lens' TxSkelOut (Maybe VScript)
txSkelOutMReferenceScriptL Lens' TxSkelOut (Maybe VScript)
-> Optic
     A_Prism NoIx (Maybe VScript) (Maybe VScript) VScript VScript
-> AffineTraversal' TxSkelOut VScript
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_Prism NoIx (Maybe VScript) (Maybe VScript) VScript VScript
forall a b. Prism (Maybe a) (Maybe b) a b
_Just

-- | Returns the possible reference script has of this 'TxSkelOut'
txSkelOutReferenceScriptHashAF :: AffineFold TxSkelOut Api.ScriptHash
txSkelOutReferenceScriptHashAF :: AffineFold TxSkelOut ScriptHash
txSkelOutReferenceScriptHashAF = AffineTraversal' TxSkelOut VScript
txSkelOutReferenceScriptAT AffineTraversal' TxSkelOut VScript
-> Optic A_Getter NoIx VScript VScript ScriptHash ScriptHash
-> AffineFold TxSkelOut ScriptHash
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
% (VScript -> ScriptHash)
-> Optic A_Getter NoIx VScript VScript ScriptHash ScriptHash
forall s a. (s -> a) -> Getter s a
to VScript -> ScriptHash
forall a. ToScriptHash a => a -> ScriptHash
Script.toScriptHash

-- * Optics focusing on the staking credential of a 'TxSkelOut'

-- | Focuses on the @Maybe StakingCredential@ of this 'TxSkelOut'
makeLensesFor [("txSkelOutStakingCredential", "txSkelOutMStakingCredentialL")] ''TxSkelOut

-- | Focuses on the staking credential of this 'TxSkelOut'
txSkelOutStakingCredentialAT :: AffineTraversal' TxSkelOut Api.StakingCredential
txSkelOutStakingCredentialAT :: AffineTraversal' TxSkelOut StakingCredential
txSkelOutStakingCredentialAT = Lens' TxSkelOut (Maybe StakingCredential)
txSkelOutMStakingCredentialL Lens' TxSkelOut (Maybe StakingCredential)
-> Optic
     A_Prism
     NoIx
     (Maybe StakingCredential)
     (Maybe StakingCredential)
     StakingCredential
     StakingCredential
-> AffineTraversal' TxSkelOut StakingCredential
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_Prism
  NoIx
  (Maybe StakingCredential)
  (Maybe StakingCredential)
  StakingCredential
  StakingCredential
forall a b. Prism (Maybe a) (Maybe b) a b
_Just

-- | Optics focusing on the datum of a 'TxSkelOut'

-- | Focuses on the 'TxSkelOutDatum' of this 'TxSkelOut'
makeLensesFor [("txSkelOutDatum", "txSkelOutDatumL")] ''TxSkelOut

-- * Optics focusing on the value of this 'TxSkelOut'

-- | Focuses on the 'Api.Value' of this 'TxSkelOut'
makeLensesFor [("txSkelOutValue", "txSkelOutValueL")] ''TxSkelOut

-- | Focuses on whether the 'Api.Value' contained in this 'TxSkelOut' can be
-- adjusted to min ADA during transaction generation
makeLensesFor [("txSkelOutValueAutoAdjust", "txSkelOutValueAutoAdjustL")] ''TxSkelOut

-- * Optics focusing on the owner of this 'TxSkelOut'

-- | Focuses on the user of this 'TxSkelOut'
makeLensesFor [("txSkelOutOwner", "txSkelOutOwnerL")] ''TxSkelOut

-- * Additional optics around a 'TxSkelOut'

-- | Returns the credential of this 'TxSkelOut'
txSkelOutCredentialG :: Getter TxSkelOut Api.Credential
txSkelOutCredentialG :: Getter TxSkelOut Credential
txSkelOutCredentialG = (TxSkelOut -> Credential) -> Getter TxSkelOut Credential
forall s a. (s -> a) -> Getter s a
to ((TxSkelOut -> Credential) -> Getter TxSkelOut Credential)
-> (TxSkelOut -> Credential) -> Getter TxSkelOut Credential
forall a b. (a -> b) -> a -> b
$ \(TxSkelOut {User 'IsEither 'Allocation
txSkelOutOwner :: TxSkelOut -> User 'IsEither 'Allocation
txSkelOutOwner :: User 'IsEither 'Allocation
txSkelOutOwner}) -> User 'IsEither 'Allocation -> Credential
forall a. ToCredential a => a -> Credential
Script.toCredential User 'IsEither 'Allocation
txSkelOutOwner

-- | Returns the address of this 'TxSkelOut'
txSkelOutAddressG :: Getter TxSkelOut Api.Address
txSkelOutAddressG :: Getter TxSkelOut Address
txSkelOutAddressG = (TxSkelOut -> Address) -> Getter TxSkelOut Address
forall s a. (s -> a) -> Getter s a
to ((TxSkelOut -> Address) -> Getter TxSkelOut Address)
-> (TxSkelOut -> Address) -> Getter TxSkelOut Address
forall a b. (a -> b) -> a -> b
$ \TxSkelOut
txSkelOut ->
  Credential -> Maybe StakingCredential -> Address
Api.Address
    (Getter TxSkelOut Credential -> TxSkelOut -> Credential
forall k (is :: IxList) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view Getter TxSkelOut Credential
txSkelOutCredentialG TxSkelOut
txSkelOut)
    (Lens' TxSkelOut (Maybe StakingCredential)
-> TxSkelOut -> Maybe StakingCredential
forall k (is :: IxList) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view Lens' TxSkelOut (Maybe StakingCredential)
txSkelOutMStakingCredentialL TxSkelOut
txSkelOut)

-- * Instances for 'TxSkelOut'

instance Script.ToCredential TxSkelOut where
  toCredential :: TxSkelOut -> Credential
toCredential = Getter TxSkelOut Credential -> TxSkelOut -> Credential
forall k (is :: IxList) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view Getter TxSkelOut Credential
txSkelOutCredentialG

instance Script.ToAddress TxSkelOut where
  toAddress :: TxSkelOut -> Address
toAddress = Getter TxSkelOut Address -> TxSkelOut -> Address
forall k (is :: IxList) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view Getter TxSkelOut Address
txSkelOutAddressG

-- * Smart constructing the owner of a 'TxSkelOut'

-- | A conveniency typeclass to automated the creation of 'TxSkelOut' owners, to
-- be used alongside 'Payable' with the smart constructor 'receives'.
class IsTxSkelOutAllowedOwner a where
  toPKHOrVScript :: a -> User IsEither Allocation

instance IsTxSkelOutAllowedOwner Api.PubKeyHash where
  toPKHOrVScript :: PubKeyHash -> User 'IsEither 'Allocation
toPKHOrVScript = PubKeyHash -> User 'IsEither 'Allocation
forall pkh (a :: UserKind) (b :: UserMode).
(a ∈ '[ 'IsPubKey, 'IsEither], ToPubKeyHash pkh, Typeable pkh) =>
pkh -> User a b
UserPubKey

instance IsTxSkelOutAllowedOwner (User 'IsPubKey 'Allocation) where
  toPKHOrVScript :: User 'IsPubKey 'Allocation -> User 'IsEither 'Allocation
toPKHOrVScript (UserPubKey pkh
pkh) = pkh -> User 'IsEither 'Allocation
forall pkh (a :: UserKind) (b :: UserMode).
(a ∈ '[ 'IsPubKey, 'IsEither], ToPubKeyHash pkh, Typeable pkh) =>
pkh -> User a b
UserPubKey pkh
pkh

instance IsTxSkelOutAllowedOwner Wallet where
  toPKHOrVScript :: Wallet -> User 'IsEither 'Allocation
toPKHOrVScript = Wallet -> User 'IsEither 'Allocation
forall pkh (a :: UserKind) (b :: UserMode).
(a ∈ '[ 'IsPubKey, 'IsEither], ToPubKeyHash pkh, Typeable pkh) =>
pkh -> User a b
UserPubKey

instance IsTxSkelOutAllowedOwner VScript where
  toPKHOrVScript :: VScript -> User 'IsEither 'Allocation
toPKHOrVScript = VScript -> User 'IsEither 'Allocation
forall script (a :: UserKind).
(a ∈ '[ 'IsScript, 'IsEither], ToVScript script,
 Typeable script) =>
script -> User a 'Allocation
UserScript

instance (Typeable a) => IsTxSkelOutAllowedOwner (Script.TypedValidator a) where
  toPKHOrVScript :: TypedValidator a -> User 'IsEither 'Allocation
toPKHOrVScript = TypedValidator a -> User 'IsEither 'Allocation
forall script (a :: UserKind).
(a ∈ '[ 'IsScript, 'IsEither], ToVScript script,
 Typeable script) =>
script -> User a 'Allocation
UserScript

instance IsTxSkelOutAllowedOwner (Script.Versioned Script.Validator) where
  toPKHOrVScript :: Versioned Validator -> User 'IsEither 'Allocation
toPKHOrVScript = Versioned Validator -> User 'IsEither 'Allocation
forall script (a :: UserKind).
(a ∈ '[ 'IsScript, 'IsEither], ToVScript script,
 Typeable script) =>
script -> User a 'Allocation
UserScript

instance (Typeable a) => IsTxSkelOutAllowedOwner (Script.MultiPurposeScript a) where
  toPKHOrVScript :: MultiPurposeScript a -> User 'IsEither 'Allocation
toPKHOrVScript = MultiPurposeScript a -> User 'IsEither 'Allocation
forall script (a :: UserKind).
(a ∈ '[ 'IsScript, 'IsEither], ToVScript script,
 Typeable script) =>
script -> User a 'Allocation
UserScript

instance IsTxSkelOutAllowedOwner (User IsEither Allocation) where
  toPKHOrVScript :: User 'IsEither 'Allocation -> User 'IsEither 'Allocation
toPKHOrVScript = User 'IsEither 'Allocation -> User 'IsEither 'Allocation
forall a. a -> a
id

-- * Smart constructing the payload of a 'TxSkelOut'

-- | The kind of possible components of a 'TxSkelOut', other than the owner
data PayableKind where
  IsDatum :: PayableKind
  IsReferenceScript :: PayableKind
  IsValue :: PayableKind
  IsStakingCredential :: PayableKind

-- | Payable elements. Created from concrete elements or composed. Notice that
-- there is no way of building an element of Type @Payable '[]@ so when using an
-- element of Type @Payable els@ we are sure that something was in fact
-- paid. Also, there is no way of building an element of type @Payable '[a,a]@
-- so we also know at most one occurrence of each type of payment is performed.
data Payable :: [PayableKind] -> Type where
  -- | Hashed datums visible in the transaction are payable
  VisibleHashedDatum :: (DatumConstrs a) => a -> Payable '[IsDatum]
  -- | Inline datums are payable
  InlineDatum :: (DatumConstrs a) => a -> Payable '[IsDatum]
  -- | Hashed datums hidden from the transaction are payable
  HiddenHashedDatum :: (DatumConstrs a) => a -> Payable '[IsDatum]
  -- | Reference scripts are payable
  ReferenceScript :: (ToVScript s) => s -> Payable '[IsReferenceScript]
  -- | Values are payable and are subject to min ada adjustment
  Value :: (Script.ToValue a) => a -> Payable '[IsValue]
  -- | Fixed Values are payable but are NOT subject to min ada adjustment
  FixedValue :: (Script.ToValue a) => a -> Payable '[IsValue]
  -- | Staking credentials are payable
  StakingCredential :: (Script.ToMaybeStakingCredential cred) => cred -> Payable '[IsStakingCredential]
  -- | Payables can be combined as long as their list of tags are disjoint
  PayableAnd :: (els  els') => Payable els -> Payable els' -> Payable (els  els')

-- | An infix-usable alias for 'PayableAnd'
(<&&>) :: (els  els') => Payable els -> Payable els' -> Payable (els  els')
<&&> :: forall (els :: [PayableKind]) (els' :: [PayableKind]).
(els ⩀ els') =>
Payable els -> Payable els' -> Payable (els ∪ els')
(<&&>) = Payable els -> Payable els' -> Payable (els ∪ els')
forall (els :: [PayableKind]) (els' :: [PayableKind]).
(els ⩀ els') =>
Payable els -> Payable els' -> Payable (els ∪ els')
PayableAnd

-- * Smart constructor to build 'TxSkelOut's

infix 1 `receives`

-- | Smart constructor to build a 'TxSkelOut' from an @owner@ and 'Payable'. This
-- should be the main way of building outputs.
receives :: (IsTxSkelOutAllowedOwner owner) => owner -> Payable els -> TxSkelOut
receives :: forall owner (els :: [PayableKind]).
IsTxSkelOutAllowedOwner owner =>
owner -> Payable els -> TxSkelOut
receives (owner -> User 'IsEither 'Allocation
forall a.
IsTxSkelOutAllowedOwner a =>
a -> User 'IsEither 'Allocation
toPKHOrVScript -> User 'IsEither 'Allocation
owner) =
  ( Payable els -> TxSkelOut -> TxSkelOut
forall (els :: [PayableKind]).
Payable els -> TxSkelOut -> TxSkelOut
`go`
      User 'IsEither 'Allocation
-> Maybe StakingCredential
-> TxSkelOutDatum
-> Value
-> Bool
-> Maybe VScript
-> TxSkelOut
TxSkelOut
        User 'IsEither 'Allocation
owner
        Maybe StakingCredential
forall a. Maybe a
Nothing -- No staking credential by default
        TxSkelOutDatum
defaultTxSkelDatum -- Default datum defined below
        Value
forall a. Monoid a => a
mempty -- Empty value by default
        Bool
True -- the value is adjustable to min ADA by default
        Maybe VScript
forall a. Maybe a
Nothing -- No reference script by default)
  )
  where
    go :: Payable els -> TxSkelOut -> TxSkelOut
    go :: forall (els :: [PayableKind]).
Payable els -> TxSkelOut -> TxSkelOut
go (VisibleHashedDatum a
dat) = Lens' TxSkelOut TxSkelOutDatum
-> TxSkelOutDatum -> TxSkelOut -> TxSkelOut
forall k (is :: IxList) s t a b.
Is k A_Setter =>
Optic k is s t a b -> b -> s -> t
set Lens' TxSkelOut TxSkelOutDatum
txSkelOutDatumL (a -> DatumKind -> TxSkelOutDatum
forall dat. DatumConstrs dat => dat -> DatumKind -> TxSkelOutDatum
SomeTxSkelOutDatum a
dat (DatumResolved -> DatumKind
Hashed DatumResolved
Resolved))
    go (InlineDatum a
dat) = Lens' TxSkelOut TxSkelOutDatum
-> TxSkelOutDatum -> TxSkelOut -> TxSkelOut
forall k (is :: IxList) s t a b.
Is k A_Setter =>
Optic k is s t a b -> b -> s -> t
set Lens' TxSkelOut TxSkelOutDatum
txSkelOutDatumL (a -> DatumKind -> TxSkelOutDatum
forall dat. DatumConstrs dat => dat -> DatumKind -> TxSkelOutDatum
SomeTxSkelOutDatum a
dat DatumKind
Inline)
    go (HiddenHashedDatum a
dat) = Lens' TxSkelOut TxSkelOutDatum
-> TxSkelOutDatum -> TxSkelOut -> TxSkelOut
forall k (is :: IxList) s t a b.
Is k A_Setter =>
Optic k is s t a b -> b -> s -> t
set Lens' TxSkelOut TxSkelOutDatum
txSkelOutDatumL (a -> DatumKind -> TxSkelOutDatum
forall dat. DatumConstrs dat => dat -> DatumKind -> TxSkelOutDatum
SomeTxSkelOutDatum a
dat (DatumResolved -> DatumKind
Hashed DatumResolved
NotResolved))
    go (FixedValue (a -> Value
forall a. ToValue a => a -> Value
Script.toValue -> Value
v)) = Lens' TxSkelOut Value -> Value -> TxSkelOut -> TxSkelOut
forall k (is :: IxList) s t a b.
Is k A_Setter =>
Optic k is s t a b -> b -> s -> t
set Lens' TxSkelOut Value
txSkelOutValueL Value
v (TxSkelOut -> TxSkelOut)
-> (TxSkelOut -> TxSkelOut) -> TxSkelOut -> TxSkelOut
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Lens' TxSkelOut Bool -> Bool -> TxSkelOut -> TxSkelOut
forall k (is :: IxList) s t a b.
Is k A_Setter =>
Optic k is s t a b -> b -> s -> t
set Lens' TxSkelOut Bool
txSkelOutValueAutoAdjustL Bool
False
    go (Value (a -> Value
forall a. ToValue a => a -> Value
Script.toValue -> Value
v)) = Lens' TxSkelOut Value -> Value -> TxSkelOut -> TxSkelOut
forall k (is :: IxList) s t a b.
Is k A_Setter =>
Optic k is s t a b -> b -> s -> t
set Lens' TxSkelOut Value
txSkelOutValueL Value
v (TxSkelOut -> TxSkelOut)
-> (TxSkelOut -> TxSkelOut) -> TxSkelOut -> TxSkelOut
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Lens' TxSkelOut Bool -> Bool -> TxSkelOut -> TxSkelOut
forall k (is :: IxList) s t a b.
Is k A_Setter =>
Optic k is s t a b -> b -> s -> t
set Lens' TxSkelOut Bool
txSkelOutValueAutoAdjustL Bool
True
    go (ReferenceScript (s -> VScript
forall script. ToVScript script => script -> VScript
toVScript -> VScript
vScript)) = Lens' TxSkelOut (Maybe VScript)
-> Maybe VScript -> TxSkelOut -> TxSkelOut
forall k (is :: IxList) s t a b.
Is k A_Setter =>
Optic k is s t a b -> b -> s -> t
set Lens' TxSkelOut (Maybe VScript)
txSkelOutMReferenceScriptL (VScript -> Maybe VScript
forall a. a -> Maybe a
Just VScript
vScript)
    go (StakingCredential (cred -> Maybe StakingCredential
forall a.
ToMaybeStakingCredential a =>
a -> Maybe StakingCredential
Script.toMaybeStakingCredential -> Maybe StakingCredential
mStCred)) = Lens' TxSkelOut (Maybe StakingCredential)
-> Maybe StakingCredential -> TxSkelOut -> TxSkelOut
forall k (is :: IxList) s t a b.
Is k A_Setter =>
Optic k is s t a b -> b -> s -> t
set Lens' TxSkelOut (Maybe StakingCredential)
txSkelOutMStakingCredentialL Maybe StakingCredential
mStCred
    go (PayableAnd Payable els
p1 Payable els'
p2) = Payable els' -> TxSkelOut -> TxSkelOut
forall (els :: [PayableKind]).
Payable els -> TxSkelOut -> TxSkelOut
go Payable els'
p2 (TxSkelOut -> TxSkelOut)
-> (TxSkelOut -> TxSkelOut) -> TxSkelOut -> TxSkelOut
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Payable els -> TxSkelOut -> TxSkelOut
forall (els :: [PayableKind]).
Payable els -> TxSkelOut -> TxSkelOut
go Payable els
p1

    defaultTxSkelDatum :: TxSkelOutDatum
defaultTxSkelDatum = case User 'IsEither 'Allocation
owner of
      -- V1 and V2 script always need a datum, even if empty
      UserScript (script -> VScript
forall script. ToVScript script => script -> VScript
toVScript -> Script.Versioned Script
_ Language
v) | Language
v Language -> Language -> Bool
forall a. Ord a => a -> a -> Bool
<= Language
Script.PlutusV2 -> () -> DatumKind -> TxSkelOutDatum
forall dat. DatumConstrs dat => dat -> DatumKind -> TxSkelOutDatum
SomeTxSkelOutDatum () (DatumResolved -> DatumKind
Hashed DatumResolved
NotResolved)
      -- V3 script and PKH do not necessarily need a datum
      User 'IsEither 'Allocation
_ -> TxSkelOutDatum
NoTxSkelOutDatum