View on GitHub
File Changes
    ( API
    ) where

                      
-
import           Ledger      (Slot, Tx)
+
import           Data.Map    (Map)
+

                      
+
import           Ledger      (Address, Slot, Tx, TxOutRef, TxOut)
import           Servant.API ((:<|>), (:>), Get, JSON, NoContent, Post, ReqBody)

                      
type API
     = "healthcheck" :> Get '[ JSON] NoContent
       :<|> "mempool" :> ReqBody '[ JSON] Tx :> Post '[ JSON] NoContent
       :<|> "slot" :> Get '[ JSON] Slot
-
       :<|> "random-tx" :> Get '[ JSON] Tx
+
       :<|> "mock" :> MockAPI
+

                      
+
-- Routes that are not guaranteed to exist on the real node
+
type MockAPI =
+
       "random-tx" :> Get '[ JSON] Tx
+
       :<|> "utxo-at" :> ReqBody '[ JSON] Address :> Post '[ JSON] (Map TxOutRef TxOut)
module Cardano.Node.Client where

                      
import           Cardano.Node.API    (API)
+
import           Data.Map            (Map)
import           Data.Proxy          (Proxy (Proxy))
-
import           Ledger              (Slot, Tx)
+
import           Ledger              (Address, Slot, Tx, TxOutRef, TxOut)
import           Network.HTTP.Client (defaultManagerSettings, newManager)
import           Servant             ((:<|>) (..), NoContent)
import           Servant.Client      (ClientM, client, mkClientEnv, parseBaseUrl, runClientM)
getCurrentSlot :: ClientM Slot
addTx :: Tx -> ClientM NoContent
randomTx :: ClientM Tx
-
(healthcheck, addTx, getCurrentSlot, randomTx) =
-
    (healthcheck_, addTx_, getCurrentSlot_, randomTx_)
+
utxoAt :: Address -> ClientM (Map TxOutRef TxOut)
+
(healthcheck, addTx, getCurrentSlot, randomTx, utxoAt) =
+
    (healthcheck_, addTx_, getCurrentSlot_, randomTx_, utxoAt_)
  where
-
    healthcheck_ :<|> addTx_ :<|> getCurrentSlot_ :<|> randomTx_ =
+
    healthcheck_ :<|> addTx_ :<|> getCurrentSlot_ :<|> (randomTx_ :<|> utxoAt_) =
        client (Proxy @API)

                      
main :: IO ()
import           Control.Monad.IO.Class         (MonadIO, liftIO)
import           Control.Monad.Logger           (MonadLogger, logDebugN, logInfoN, runStdoutLoggingT)
import           Data.Foldable                  (traverse_)
+
import           Data.Map                       (Map)
import qualified Data.Map                       as Map
import           Data.Proxy                     (Proxy (Proxy))
import           Data.Text.Prettyprint.Doc      (Pretty (pretty))
import           Language.Plutus.Contract.Trace (InitialDistribution)
import qualified Language.Plutus.Contract.Trace as Trace

                      
-
import           Ledger                         (Slot, Tx)
+
import           Ledger                         (Address, Slot, Tx, TxOut(..), TxOutRef, UtxoIndex (..))
import qualified Ledger

                      
import           Cardano.Node.RandomTx
    simpleLogInfo "Adding slot"
    void Chain.processBlock

                      
+
utxoAt :: (Member (State ChainState) effs) => Address -> Eff effs (Map TxOutRef TxOut)
+
utxoAt addr = do
+
    UtxoIndex idx <- Eff.gets (view EM.index)
+
    pure $ Map.filter (\TxOut{txOutAddress} -> txOutAddress == addr) idx
+

                      
addTx :: (Member SimpleLog effs, Member ChainEffect effs) => Tx -> Eff effs NoContent
addTx tx = do
    simpleLogInfo  $ "Adding tx " <> tshow (Ledger.txId tx)
        (healthcheck
        :<|> addTx
        :<|> getCurrentSlot
-
        :<|> genRandomTx)
+
        :<|> (genRandomTx :<|> utxoAt))

                      
main :: (MonadIO m, MonadLogger m) => MockServerConfig -> m ()
main config = do