-- | This module exposes the notion of Withdrawal within a
-- 'Cooked.Skeleton.TxSkel'
module Cooked.Skeleton.Withdrawal
  ( TxSkelWithdrawals,
    pkWithdrawal,
    scriptWithdrawal,
  )
where

import Cooked.Skeleton.Redeemer
import Data.Map (Map)
import Data.Map qualified as Map
import Plutus.Script.Utils.Address qualified as Script
import Plutus.Script.Utils.Scripts qualified as Script
import PlutusLedgerApi.V3 qualified as Api

-- | Withdrawals associate either a script or a private key with a redeemer and
-- a certain amount of ada. Note that the redeemer will be ignored in the case
-- of a private key.
type TxSkelWithdrawals =
  Map
    (Either (Script.Versioned Script.Script) Api.PubKeyHash)
    (TxSkelRedeemer, Api.Lovelace)

-- | Creates a 'TxSkelWithdrawals' from a private key hash and amount
pkWithdrawal :: (Script.ToPubKeyHash pkh) => pkh -> Api.Lovelace -> TxSkelWithdrawals
pkWithdrawal :: forall pkh.
ToPubKeyHash pkh =>
pkh -> Lovelace -> TxSkelWithdrawals
pkWithdrawal pkh
pkh Lovelace
amount = Either (Versioned Script) PubKeyHash
-> (TxSkelRedeemer, Lovelace) -> TxSkelWithdrawals
forall k a. k -> a -> Map k a
Map.singleton (PubKeyHash -> Either (Versioned Script) PubKeyHash
forall a b. b -> Either a b
Right (PubKeyHash -> Either (Versioned Script) PubKeyHash)
-> PubKeyHash -> Either (Versioned Script) PubKeyHash
forall a b. (a -> b) -> a -> b
$ pkh -> PubKeyHash
forall a. ToPubKeyHash a => a -> PubKeyHash
Script.toPubKeyHash pkh
pkh) (TxSkelRedeemer
emptyTxSkelRedeemer, Lovelace
amount)

-- | Creates a 'TxSkelWithdrawals' from a script, redeemer and amount
scriptWithdrawal :: (Script.ToVersioned Script.Script script) => script -> TxSkelRedeemer -> Api.Lovelace -> TxSkelWithdrawals
scriptWithdrawal :: forall script.
ToVersioned Script script =>
script -> TxSkelRedeemer -> Lovelace -> TxSkelWithdrawals
scriptWithdrawal script
script TxSkelRedeemer
red Lovelace
amount = Either (Versioned Script) PubKeyHash
-> (TxSkelRedeemer, Lovelace) -> TxSkelWithdrawals
forall k a. k -> a -> Map k a
Map.singleton (Versioned Script -> Either (Versioned Script) PubKeyHash
forall a b. a -> Either a b
Left (Versioned Script -> Either (Versioned Script) PubKeyHash)
-> Versioned Script -> Either (Versioned Script) PubKeyHash
forall a b. (a -> b) -> a -> b
$ script -> Versioned Script
forall s a. ToVersioned s a => a -> Versioned s
Script.toVersioned script
script) (TxSkelRedeemer
red, Lovelace
amount)