-- | This module provides a convenient framework to look through UTxOs and
-- search relevant ones based on predicates. For instance, it makes it very
-- convenient to gather all UTxOs at a certain address.
module Cooked.MockChain.UtxoSearch
  ( UtxoSearch,
    runUtxoSearch,
    allUtxosSearch,
    utxosAtSearch,
    utxosFromCardanoTxSearch,
    txOutByRefSearch,
    filterWith,
    filterWithPure,
    filterWithOptic,
    filterWithPred,
    filterWithValuePred,
    filterWithOnlyAda,
    filterWithNotOnlyAda,
    onlyValueOutputsAtSearch,
    vanillaOutputsAtSearch,
    filterWithAlways,
    scriptOutputsSearch,
    referenceScriptOutputsSearch,
  )
where

import Control.Monad
import Cooked.Conversion.ToAddress
import Cooked.Conversion.ToScriptHash
import Cooked.MockChain.BlockChain
import Cooked.Output
import Data.Maybe
import Ledger.Tx qualified as Ledger
import ListT (ListT (..))
import ListT qualified
import Optics.Core
import Plutus.Script.Utils.Ada qualified as Script
import Plutus.Script.Utils.Value qualified as Script
import PlutusLedgerApi.V3 qualified as Api

-- * The type of UTxO searches

-- | If a UTxO is a 'TxOutRef' with some additional information, this type
-- captures a "stream" of UTxOs.
type UtxoSearch m a = ListT m (Api.TxOutRef, a)

-- | Given a UTxO search, we can run it to obtain a list of UTxOs.
runUtxoSearch :: (Monad m) => UtxoSearch m a -> m [(Api.TxOutRef, a)]
runUtxoSearch :: forall (m :: * -> *) a.
Monad m =>
UtxoSearch m a -> m [(TxOutRef, a)]
runUtxoSearch = ListT m (TxOutRef, a) -> m [(TxOutRef, a)]
forall (m :: * -> *) a. Monad m => ListT m a -> m [a]
ListT.toList

-- | Search all currently known 'TxOutRef's together with their corresponding
-- 'TxInfo'-'TxOut'.
allUtxosSearch :: (MonadBlockChain m) => UtxoSearch m Api.TxOut
allUtxosSearch :: forall (m :: * -> *). MonadBlockChain m => UtxoSearch m TxOut
allUtxosSearch = ListT m [(TxOutRef, TxOut)]
forall (m :: * -> *).
MonadBlockChainWithoutValidation m =>
m [(TxOutRef, TxOut)]
allUtxos ListT m [(TxOutRef, TxOut)]
-> ([(TxOutRef, TxOut)] -> ListT m (TxOutRef, TxOut))
-> ListT m (TxOutRef, TxOut)
forall a b. ListT m a -> (a -> ListT m b) -> ListT m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [(TxOutRef, TxOut)] -> ListT m (TxOutRef, TxOut)
forall (m :: * -> *) (f :: * -> *) a.
(Monad m, Foldable f) =>
f a -> ListT m a
ListT.fromFoldable

-- | Search all 'TxOutRef's at a certain address, together with their
-- 'TxInfo'-'TxOut'.
utxosAtSearch :: (MonadBlockChainBalancing m, ToAddress addr) => addr -> UtxoSearch m Api.TxOut
utxosAtSearch :: forall (m :: * -> *) addr.
(MonadBlockChainBalancing m, ToAddress addr) =>
addr -> UtxoSearch m TxOut
utxosAtSearch = Address -> ListT m [(TxOutRef, TxOut)]
forall (m :: * -> *).
MonadBlockChainBalancing m =>
Address -> m [(TxOutRef, TxOut)]
utxosAt (Address -> ListT m [(TxOutRef, TxOut)])
-> (addr -> Address) -> addr -> ListT m [(TxOutRef, TxOut)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. addr -> Address
forall a. ToAddress a => a -> Address
toAddress (addr -> ListT m [(TxOutRef, TxOut)])
-> ([(TxOutRef, TxOut)] -> ListT m (TxOutRef, TxOut))
-> addr
-> ListT m (TxOutRef, TxOut)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> [(TxOutRef, TxOut)] -> ListT m (TxOutRef, TxOut)
forall (m :: * -> *) (f :: * -> *) a.
(Monad m, Foldable f) =>
f a -> ListT m a
ListT.fromFoldable

-- | Search all 'TxOutRef's of a transaction, together with their
-- 'TxInfo'-'TxOut'.
utxosFromCardanoTxSearch :: (Monad m) => Ledger.CardanoTx -> UtxoSearch m Api.TxOut
utxosFromCardanoTxSearch :: forall (m :: * -> *). Monad m => CardanoTx -> UtxoSearch m TxOut
utxosFromCardanoTxSearch = [(TxOutRef, TxOut)] -> ListT m (TxOutRef, TxOut)
forall (m :: * -> *) (f :: * -> *) a.
(Monad m, Foldable f) =>
f a -> ListT m a
ListT.fromFoldable ([(TxOutRef, TxOut)] -> ListT m (TxOutRef, TxOut))
-> (CardanoTx -> [(TxOutRef, TxOut)])
-> CardanoTx
-> ListT m (TxOutRef, TxOut)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CardanoTx -> [(TxOutRef, TxOut)]
utxosFromCardanoTx

-- | Search all 'TxInfo'-'TxOut's corresponding to given the list of
-- 'TxOutRef's. Any 'TxOutRef' that doesn't correspond to a known output will be
-- filtered out.
txOutByRefSearch :: (MonadBlockChainBalancing m) => [Api.TxOutRef] -> UtxoSearch m Api.TxOut
txOutByRefSearch :: forall (m :: * -> *).
MonadBlockChainBalancing m =>
[TxOutRef] -> UtxoSearch m TxOut
txOutByRefSearch [TxOutRef]
orefs =
  (TxOutRef -> m (TxOutRef, TxOutRef))
-> ListT m TxOutRef -> ListT m (TxOutRef, TxOutRef)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> ListT m a -> ListT m b
ListT.traverse (\TxOutRef
o -> (TxOutRef, TxOutRef) -> m (TxOutRef, TxOutRef)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (TxOutRef
o, TxOutRef
o)) ([TxOutRef] -> ListT m TxOutRef
forall (m :: * -> *) (f :: * -> *) a.
(Monad m, Foldable f) =>
f a -> ListT m a
ListT.fromFoldable [TxOutRef]
orefs)
    ListT m (TxOutRef, TxOutRef)
-> (TxOutRef -> m (Maybe TxOut)) -> UtxoSearch m TxOut
forall (m :: * -> *) a b.
Monad m =>
UtxoSearch m a -> (a -> m (Maybe b)) -> UtxoSearch m b
`filterWith` TxOutRef -> m (Maybe TxOut)
forall (m :: * -> *).
MonadBlockChainBalancing m =>
TxOutRef -> m (Maybe TxOut)
txOutByRef

-- * filtering UTxO searches

-- | Transform a 'UtxoSearch' by applying a possibly failing monadic "lookup" on
-- every output.
filterWith :: (Monad m) => UtxoSearch m a -> (a -> m (Maybe b)) -> UtxoSearch m b
filterWith :: forall (m :: * -> *) a b.
Monad m =>
UtxoSearch m a -> (a -> m (Maybe b)) -> UtxoSearch m b
filterWith (ListT m (Maybe ((TxOutRef, a), ListT m (TxOutRef, a)))
as) a -> m (Maybe b)
f =
  m (Maybe ((TxOutRef, b), ListT m (TxOutRef, b)))
-> ListT m (TxOutRef, b)
forall (m :: * -> *) a. m (Maybe (a, ListT m a)) -> ListT m a
ListT (m (Maybe ((TxOutRef, b), ListT m (TxOutRef, b)))
 -> ListT m (TxOutRef, b))
-> m (Maybe ((TxOutRef, b), ListT m (TxOutRef, b)))
-> ListT m (TxOutRef, b)
forall a b. (a -> b) -> a -> b
$
    m (Maybe ((TxOutRef, a), ListT m (TxOutRef, a)))
as m (Maybe ((TxOutRef, a), ListT m (TxOutRef, a)))
-> (Maybe ((TxOutRef, a), ListT m (TxOutRef, a))
    -> m (Maybe ((TxOutRef, b), ListT m (TxOutRef, b))))
-> m (Maybe ((TxOutRef, b), ListT m (TxOutRef, b)))
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      Maybe ((TxOutRef, a), ListT m (TxOutRef, a))
Nothing -> Maybe ((TxOutRef, b), ListT m (TxOutRef, b))
-> m (Maybe ((TxOutRef, b), ListT m (TxOutRef, b)))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe ((TxOutRef, b), ListT m (TxOutRef, b))
forall a. Maybe a
Nothing
      Just ((TxOutRef
oref, a
a), ListT m (TxOutRef, a)
rest) ->
        let filteredRest :: ListT m (TxOutRef, b)
filteredRest@(ListT m (Maybe ((TxOutRef, b), ListT m (TxOutRef, b)))
bs) = ListT m (TxOutRef, a)
-> (a -> m (Maybe b)) -> ListT m (TxOutRef, b)
forall (m :: * -> *) a b.
Monad m =>
UtxoSearch m a -> (a -> m (Maybe b)) -> UtxoSearch m b
filterWith ListT m (TxOutRef, a)
rest a -> m (Maybe b)
f
         in a -> m (Maybe b)
f a
a m (Maybe b)
-> (Maybe b -> m (Maybe ((TxOutRef, b), ListT m (TxOutRef, b))))
-> m (Maybe ((TxOutRef, b), ListT m (TxOutRef, b)))
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
              Maybe b
Nothing -> m (Maybe ((TxOutRef, b), ListT m (TxOutRef, b)))
bs
              Just b
b -> Maybe ((TxOutRef, b), ListT m (TxOutRef, b))
-> m (Maybe ((TxOutRef, b), ListT m (TxOutRef, b)))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe ((TxOutRef, b), ListT m (TxOutRef, b))
 -> m (Maybe ((TxOutRef, b), ListT m (TxOutRef, b))))
-> Maybe ((TxOutRef, b), ListT m (TxOutRef, b))
-> m (Maybe ((TxOutRef, b), ListT m (TxOutRef, b)))
forall a b. (a -> b) -> a -> b
$ ((TxOutRef, b), ListT m (TxOutRef, b))
-> Maybe ((TxOutRef, b), ListT m (TxOutRef, b))
forall a. a -> Maybe a
Just ((TxOutRef
oref, b
b), ListT m (TxOutRef, b)
filteredRest)

filterWithPure :: (Monad m) => UtxoSearch m a -> (a -> Maybe b) -> UtxoSearch m b
filterWithPure :: forall (m :: * -> *) a b.
Monad m =>
UtxoSearch m a -> (a -> Maybe b) -> UtxoSearch m b
filterWithPure UtxoSearch m a
as a -> Maybe b
f = UtxoSearch m a -> (a -> m (Maybe b)) -> UtxoSearch m b
forall (m :: * -> *) a b.
Monad m =>
UtxoSearch m a -> (a -> m (Maybe b)) -> UtxoSearch m b
filterWith UtxoSearch m a
as (Maybe b -> m (Maybe b)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe b -> m (Maybe b)) -> (a -> Maybe b) -> a -> m (Maybe b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Maybe b
f)

filterWithAlways :: (Monad m) => UtxoSearch m a -> (a -> b) -> UtxoSearch m b
filterWithAlways :: forall (m :: * -> *) a b.
Monad m =>
UtxoSearch m a -> (a -> b) -> UtxoSearch m b
filterWithAlways UtxoSearch m a
as a -> b
f = UtxoSearch m a -> (a -> Maybe b) -> UtxoSearch m b
forall (m :: * -> *) a b.
Monad m =>
UtxoSearch m a -> (a -> Maybe b) -> UtxoSearch m b
filterWithPure UtxoSearch m a
as (b -> Maybe b
forall a. a -> Maybe a
Just (b -> Maybe b) -> (a -> b) -> a -> Maybe b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f)

filterWithOptic :: (Is k An_AffineFold, Monad m) => UtxoSearch m a -> Optic' k is a b -> UtxoSearch m b
filterWithOptic :: forall k (m :: * -> *) a (is :: IxList) b.
(Is k An_AffineFold, Monad m) =>
UtxoSearch m a -> Optic' k is a b -> UtxoSearch m b
filterWithOptic UtxoSearch m a
as Optic' k is a b
optic = UtxoSearch m a -> (a -> Maybe b) -> UtxoSearch m b
forall (m :: * -> *) a b.
Monad m =>
UtxoSearch m a -> (a -> Maybe b) -> UtxoSearch m b
filterWithPure UtxoSearch m a
as (a -> Optic' k is a b -> Maybe b
forall k s (is :: IxList) a.
Is k An_AffineFold =>
s -> Optic' k is s a -> Maybe a
^? Optic' k is a b
optic)

filterWithPred :: (Monad m) => UtxoSearch m a -> (a -> Bool) -> UtxoSearch m a
filterWithPred :: forall (m :: * -> *) a.
Monad m =>
UtxoSearch m a -> (a -> Bool) -> UtxoSearch m a
filterWithPred UtxoSearch m a
as a -> Bool
f = UtxoSearch m a -> (a -> Maybe a) -> UtxoSearch m a
forall (m :: * -> *) a b.
Monad m =>
UtxoSearch m a -> (a -> Maybe b) -> UtxoSearch m b
filterWithPure UtxoSearch m a
as ((a -> Maybe a) -> UtxoSearch m a)
-> (a -> Maybe a) -> UtxoSearch m a
forall a b. (a -> b) -> a -> b
$ \a
a -> if a -> Bool
f a
a then a -> Maybe a
forall a. a -> Maybe a
Just a
a else Maybe a
forall a. Maybe a
Nothing

filterWithValuePred :: (Monad m) => UtxoSearch m Api.TxOut -> (Api.Value -> Bool) -> UtxoSearch m Api.Value
filterWithValuePred :: forall (m :: * -> *).
Monad m =>
UtxoSearch m TxOut -> (Value -> Bool) -> UtxoSearch m Value
filterWithValuePred UtxoSearch m TxOut
as Value -> Bool
p = UtxoSearch m TxOut -> (TxOut -> Maybe Value) -> UtxoSearch m Value
forall (m :: * -> *) a b.
Monad m =>
UtxoSearch m a -> (a -> Maybe b) -> UtxoSearch m b
filterWithPure UtxoSearch m TxOut
as ((TxOut -> Maybe Value) -> UtxoSearch m Value)
-> (TxOut -> Maybe Value) -> UtxoSearch m Value
forall a b. (a -> b) -> a -> b
$
  \TxOut
txOut -> let val :: Value
val = TxOut -> Value
Api.txOutValue TxOut
txOut in if Value -> Bool
p Value
val then Value -> Maybe Value
forall a. a -> Maybe a
Just Value
val else Maybe Value
forall a. Maybe a
Nothing

filterWithOnlyAda :: (Monad m) => UtxoSearch m Api.TxOut -> UtxoSearch m Api.Value
filterWithOnlyAda :: forall (m :: * -> *).
Monad m =>
UtxoSearch m TxOut -> UtxoSearch m Value
filterWithOnlyAda UtxoSearch m TxOut
as = UtxoSearch m TxOut -> (Value -> Bool) -> UtxoSearch m Value
forall (m :: * -> *).
Monad m =>
UtxoSearch m TxOut -> (Value -> Bool) -> UtxoSearch m Value
filterWithValuePred UtxoSearch m TxOut
as ((Value -> Bool) -> UtxoSearch m Value)
-> (Value -> Bool) -> UtxoSearch m Value
forall a b. (a -> b) -> a -> b
$ (Int
1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==) (Int -> Bool) -> (Value -> Int) -> Value -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(CurrencySymbol, TokenName, Integer)] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([(CurrencySymbol, TokenName, Integer)] -> Int)
-> (Value -> [(CurrencySymbol, TokenName, Integer)])
-> Value
-> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> [(CurrencySymbol, TokenName, Integer)]
Script.flattenValue

filterWithNotOnlyAda :: (Monad m) => UtxoSearch m Api.TxOut -> UtxoSearch m Api.Value
filterWithNotOnlyAda :: forall (m :: * -> *).
Monad m =>
UtxoSearch m TxOut -> UtxoSearch m Value
filterWithNotOnlyAda UtxoSearch m TxOut
as = UtxoSearch m TxOut -> (Value -> Bool) -> UtxoSearch m Value
forall (m :: * -> *).
Monad m =>
UtxoSearch m TxOut -> (Value -> Bool) -> UtxoSearch m Value
filterWithValuePred UtxoSearch m TxOut
as ((Value -> Bool) -> UtxoSearch m Value)
-> (Value -> Bool) -> UtxoSearch m Value
forall a b. (a -> b) -> a -> b
$ (Int
1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<) (Int -> Bool) -> (Value -> Int) -> Value -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(CurrencySymbol, TokenName, Integer)] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([(CurrencySymbol, TokenName, Integer)] -> Int)
-> (Value -> [(CurrencySymbol, TokenName, Integer)])
-> Value
-> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> [(CurrencySymbol, TokenName, Integer)]
Script.flattenValue

-- | Search for UTxOs which only carry address and value information (no datum, staking credential, or reference script).
onlyValueOutputsAtSearch ::
  (MonadBlockChainBalancing m, ToAddress addr) =>
  addr ->
  UtxoSearch m (ConcreteOutput Api.Credential () Api.Value Api.ScriptHash)
onlyValueOutputsAtSearch :: forall (m :: * -> *) addr.
(MonadBlockChainBalancing m, ToAddress addr) =>
addr
-> UtxoSearch m (ConcreteOutput Credential () Value ScriptHash)
onlyValueOutputsAtSearch addr
addr =
  addr -> UtxoSearch m TxOut
forall (m :: * -> *) addr.
(MonadBlockChainBalancing m, ToAddress addr) =>
addr -> UtxoSearch m TxOut
utxosAtSearch addr
addr
    UtxoSearch m TxOut
-> (TxOut
    -> ConcreteOutput Credential OutputDatum Value ScriptHash)
-> UtxoSearch
     m (ConcreteOutput Credential OutputDatum Value ScriptHash)
forall (m :: * -> *) a b.
Monad m =>
UtxoSearch m a -> (a -> b) -> UtxoSearch m b
`filterWithAlways` TxOut -> ConcreteOutput Credential OutputDatum Value ScriptHash
TxOut
-> ConcreteOutput
     (OwnerType TxOut)
     (DatumType TxOut)
     (ValueType TxOut)
     (ReferenceScriptType TxOut)
forall out.
IsAbstractOutput out =>
out
-> ConcreteOutput
     (OwnerType out)
     (DatumType out)
     (ValueType out)
     (ReferenceScriptType out)
fromAbstractOutput
    UtxoSearch
  m (ConcreteOutput Credential OutputDatum Value ScriptHash)
-> (ConcreteOutput Credential OutputDatum Value ScriptHash
    -> Maybe (ConcreteOutput Credential () Value ScriptHash))
-> UtxoSearch m (ConcreteOutput Credential () Value ScriptHash)
forall (m :: * -> *) a b.
Monad m =>
UtxoSearch m a -> (a -> Maybe b) -> UtxoSearch m b
`filterWithPure` ConcreteOutput Credential OutputDatum Value ScriptHash
-> Maybe (ConcreteOutput Credential () Value ScriptHash)
ConcreteOutput Credential OutputDatum Value ScriptHash
-> Maybe
     (ConcreteOutput
        (OwnerType
           (ConcreteOutput Credential OutputDatum Value ScriptHash))
        ()
        (ValueType
           (ConcreteOutput Credential OutputDatum Value ScriptHash))
        (ReferenceScriptType
           (ConcreteOutput Credential OutputDatum Value ScriptHash)))
forall out.
IsTxInfoOutput out =>
out
-> Maybe
     (ConcreteOutput
        (OwnerType out) () (ValueType out) (ReferenceScriptType out))
isOutputWithoutDatum
    UtxoSearch m (ConcreteOutput Credential () Value ScriptHash)
-> (ConcreteOutput Credential () Value ScriptHash
    -> Maybe (ConcreteOutput Credential () Value ScriptHash))
-> UtxoSearch m (ConcreteOutput Credential () Value ScriptHash)
forall (m :: * -> *) a b.
Monad m =>
UtxoSearch m a -> (a -> Maybe b) -> UtxoSearch m b
`filterWithPure` ConcreteOutput Credential () Value ScriptHash
-> Maybe (ConcreteOutput Credential () Value ScriptHash)
ConcreteOutput Credential () Value ScriptHash
-> Maybe
     (ConcreteOutput
        (OwnerType (ConcreteOutput Credential () Value ScriptHash))
        (DatumType (ConcreteOutput Credential () Value ScriptHash))
        (ValueType (ConcreteOutput Credential () Value ScriptHash))
        (ReferenceScriptType
           (ConcreteOutput Credential () Value ScriptHash)))
forall out.
IsTxInfoOutput out =>
out
-> Maybe
     (ConcreteOutput
        (OwnerType out)
        (DatumType out)
        (ValueType out)
        (ReferenceScriptType out))
isEmptyStakingCredentialOutput
    UtxoSearch m (ConcreteOutput Credential () Value ScriptHash)
-> (ConcreteOutput Credential () Value ScriptHash -> Bool)
-> UtxoSearch m (ConcreteOutput Credential () Value ScriptHash)
forall (m :: * -> *) a.
Monad m =>
UtxoSearch m a -> (a -> Bool) -> UtxoSearch m a
`filterWithPred` (Maybe ScriptHash -> Bool
forall a. Maybe a -> Bool
isNothing (Maybe ScriptHash -> Bool)
-> (ConcreteOutput Credential () Value ScriptHash
    -> Maybe ScriptHash)
-> ConcreteOutput Credential () Value ScriptHash
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Optic'
  A_Lens
  NoIx
  (ConcreteOutput Credential () Value ScriptHash)
  (Maybe ScriptHash)
-> ConcreteOutput Credential () Value ScriptHash
-> Maybe ScriptHash
forall k (is :: IxList) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view Optic'
  A_Lens
  NoIx
  (ConcreteOutput Credential () Value ScriptHash)
  (Maybe ScriptHash)
Lens'
  (ConcreteOutput Credential () Value ScriptHash)
  (Maybe
     (ReferenceScriptType
        (ConcreteOutput Credential () Value ScriptHash)))
forall o.
IsAbstractOutput o =>
Lens' o (Maybe (ReferenceScriptType o))
outputReferenceScriptL)

-- | A vanilla output only possesses an ada-only value and does not have a staking
-- credential, a datum or a reference script. A vanilla UTxO is a perfect
-- candidate to be used for fee, balancing or collateral.
vanillaOutputsAtSearch ::
  (MonadBlockChainBalancing m, ToAddress addr) =>
  addr ->
  UtxoSearch m (ConcreteOutput Api.Credential () Script.Ada Api.ScriptHash)
vanillaOutputsAtSearch :: forall (m :: * -> *) addr.
(MonadBlockChainBalancing m, ToAddress addr) =>
addr -> UtxoSearch m (ConcreteOutput Credential () Ada ScriptHash)
vanillaOutputsAtSearch addr
addr =
  addr
-> UtxoSearch m (ConcreteOutput Credential () Value ScriptHash)
forall (m :: * -> *) addr.
(MonadBlockChainBalancing m, ToAddress addr) =>
addr
-> UtxoSearch m (ConcreteOutput Credential () Value ScriptHash)
onlyValueOutputsAtSearch addr
addr
    UtxoSearch m (ConcreteOutput Credential () Value ScriptHash)
-> (ConcreteOutput Credential () Value ScriptHash
    -> Maybe (ConcreteOutput Credential () Ada ScriptHash))
-> UtxoSearch m (ConcreteOutput Credential () Ada ScriptHash)
forall (m :: * -> *) a b.
Monad m =>
UtxoSearch m a -> (a -> Maybe b) -> UtxoSearch m b
`filterWithPure` ConcreteOutput Credential () Value ScriptHash
-> Maybe (ConcreteOutput Credential () Ada ScriptHash)
ConcreteOutput Credential () Value ScriptHash
-> Maybe
     (ConcreteOutput
        (OwnerType (ConcreteOutput Credential () Value ScriptHash))
        (DatumType (ConcreteOutput Credential () Value ScriptHash))
        Ada
        (ReferenceScriptType
           (ConcreteOutput Credential () Value ScriptHash)))
forall out.
IsTxInfoOutput out =>
out
-> Maybe
     (ConcreteOutput
        (OwnerType out) (DatumType out) Ada (ReferenceScriptType out))
isOnlyAdaOutput

scriptOutputsSearch ::
  (MonadBlockChain m, ToScriptHash s) =>
  s ->
  UtxoSearch m (ConcreteOutput s Api.OutputDatum Api.Value Api.ScriptHash)
scriptOutputsSearch :: forall (m :: * -> *) s.
(MonadBlockChain m, ToScriptHash s) =>
s -> UtxoSearch m (ConcreteOutput s OutputDatum Value ScriptHash)
scriptOutputsSearch s
s =
  UtxoSearch m TxOut
forall (m :: * -> *). MonadBlockChain m => UtxoSearch m TxOut
allUtxosSearch
    UtxoSearch m TxOut
-> (TxOut
    -> ConcreteOutput Credential OutputDatum Value ScriptHash)
-> UtxoSearch
     m (ConcreteOutput Credential OutputDatum Value ScriptHash)
forall (m :: * -> *) a b.
Monad m =>
UtxoSearch m a -> (a -> b) -> UtxoSearch m b
`filterWithAlways` TxOut -> ConcreteOutput Credential OutputDatum Value ScriptHash
TxOut
-> ConcreteOutput
     (OwnerType TxOut)
     (DatumType TxOut)
     (ValueType TxOut)
     (ReferenceScriptType TxOut)
forall out.
IsAbstractOutput out =>
out
-> ConcreteOutput
     (OwnerType out)
     (DatumType out)
     (ValueType out)
     (ReferenceScriptType out)
fromAbstractOutput
    UtxoSearch
  m (ConcreteOutput Credential OutputDatum Value ScriptHash)
-> (ConcreteOutput Credential OutputDatum Value ScriptHash
    -> Maybe (ConcreteOutput s OutputDatum Value ScriptHash))
-> UtxoSearch m (ConcreteOutput s OutputDatum Value ScriptHash)
forall (m :: * -> *) a b.
Monad m =>
UtxoSearch m a -> (a -> Maybe b) -> UtxoSearch m b
`filterWithPure` s
-> ConcreteOutput Credential OutputDatum Value ScriptHash
-> Maybe
     (ConcreteOutput
        s
        (DatumType
           (ConcreteOutput Credential OutputDatum Value ScriptHash))
        (ValueType
           (ConcreteOutput Credential OutputDatum Value ScriptHash))
        (ReferenceScriptType
           (ConcreteOutput Credential OutputDatum Value ScriptHash)))
forall out s.
(IsTxInfoOutput out, ToScriptHash s) =>
s
-> out
-> Maybe
     (ConcreteOutput
        s (DatumType out) (ValueType out) (ReferenceScriptType out))
isScriptOutputFrom s
s

referenceScriptOutputsSearch ::
  (MonadBlockChain m, ToScriptHash s) =>
  s ->
  UtxoSearch m (ConcreteOutput Api.Credential Api.OutputDatum Api.Value Api.ScriptHash)
referenceScriptOutputsSearch :: forall (m :: * -> *) s.
(MonadBlockChain m, ToScriptHash s) =>
s
-> UtxoSearch
     m (ConcreteOutput Credential OutputDatum Value ScriptHash)
referenceScriptOutputsSearch s
s =
  UtxoSearch m TxOut
forall (m :: * -> *). MonadBlockChain m => UtxoSearch m TxOut
allUtxosSearch
    UtxoSearch m TxOut
-> (TxOut
    -> ConcreteOutput Credential OutputDatum Value ScriptHash)
-> UtxoSearch
     m (ConcreteOutput Credential OutputDatum Value ScriptHash)
forall (m :: * -> *) a b.
Monad m =>
UtxoSearch m a -> (a -> b) -> UtxoSearch m b
`filterWithAlways` TxOut -> ConcreteOutput Credential OutputDatum Value ScriptHash
TxOut
-> ConcreteOutput
     (OwnerType TxOut)
     (DatumType TxOut)
     (ValueType TxOut)
     (ReferenceScriptType TxOut)
forall out.
IsAbstractOutput out =>
out
-> ConcreteOutput
     (OwnerType out)
     (DatumType out)
     (ValueType out)
     (ReferenceScriptType out)
fromAbstractOutput
    UtxoSearch
  m (ConcreteOutput Credential OutputDatum Value ScriptHash)
-> (ConcreteOutput Credential OutputDatum Value ScriptHash
    -> Maybe (ConcreteOutput Credential OutputDatum Value ScriptHash))
-> UtxoSearch
     m (ConcreteOutput Credential OutputDatum Value ScriptHash)
forall (m :: * -> *) a b.
Monad m =>
UtxoSearch m a -> (a -> Maybe b) -> UtxoSearch m b
`filterWithPure` s
-> ConcreteOutput Credential OutputDatum Value ScriptHash
-> Maybe
     (ConcreteOutput
        (OwnerType
           (ConcreteOutput Credential OutputDatum Value ScriptHash))
        (DatumType
           (ConcreteOutput Credential OutputDatum Value ScriptHash))
        (ValueType
           (ConcreteOutput Credential OutputDatum Value ScriptHash))
        ScriptHash)
forall out s.
(IsTxInfoOutput out, ToScriptHash s) =>
s
-> out
-> Maybe
     (ConcreteOutput
        (OwnerType out) (DatumType out) (ValueType out) ScriptHash)
isReferenceScriptOutputFrom s
s