11{-# LANGUAGE AllowAmbiguousTypes #-}
22{-# LANGUAGE RankNTypes #-}
3+ {-# OPTIONS_GHC -Wno-orphans #-}
34
45module BotPlutusInterface.Contract (runContract , handleContract ) where
56
@@ -12,9 +13,10 @@ import BotPlutusInterface.Effects (
1213 callCommand ,
1314 createDirectoryIfMissing ,
1415 estimateBudget ,
16+ handleContractLog ,
1517 handlePABEffect ,
1618 logToContract ,
17- printLog ,
19+ printBpiLog ,
1820 queryChainIndex ,
1921 readFileTextEnvelope ,
2022 saveBudget ,
@@ -34,19 +36,20 @@ import Control.Lens (preview, (^.))
3436import Control.Monad (join , void , when )
3537import Control.Monad.Freer (Eff , Member , interpret , reinterpret , runM , subsume , type (~> ))
3638import Control.Monad.Freer.Error (runError )
37- import Control.Monad.Freer.Extras.Log (handleLogIgnore )
3839import Control.Monad.Freer.Extras.Modify (raiseEnd )
3940import Control.Monad.Freer.Writer (Writer (Tell ))
4041import Control.Monad.Trans.Class (lift )
4142import Control.Monad.Trans.Either (EitherT , eitherT , firstEitherT , newEitherT )
42- import Data.Aeson (ToJSON , Value )
43+ import Data.Aeson (ToJSON , Value ( Array , Bool , Null , Number , Object , String ) )
4344import Data.Aeson.Extras (encodeByteString )
4445import Data.Either (fromRight )
46+ import Data.HashMap.Strict qualified as HM
4547import Data.Kind (Type )
4648import Data.Map qualified as Map
4749import Data.Row (Row )
4850import Data.Text (Text )
4951import Data.Text qualified as Text
52+ import Data.Vector qualified as V
5053import Ledger (POSIXTime )
5154import Ledger qualified
5255import Ledger.Address (PaymentPubKeyHash (PaymentPubKeyHash ))
@@ -69,6 +72,8 @@ import Plutus.Contract.Effects (
6972import Plutus.Contract.Resumable (Resumable (.. ))
7073import Plutus.Contract.Types (Contract (.. ), ContractEffs )
7174import PlutusTx.Builtins (fromBuiltin )
75+ import Prettyprinter (Pretty (pretty ), (<+>) )
76+ import Prettyprinter qualified as PP
7277import Wallet.Emulator.Error (WalletAPIError (.. ))
7378import Prelude
7479
@@ -92,10 +97,29 @@ handleContract contractEnv =
9297 . handleResumable contractEnv
9398 . handleCheckpointIgnore
9499 . handleWriter
95- . handleLogIgnore @ Value
100+ . handleContractLog @ w
96101 . runError
97102 . raiseEnd
98103
104+ instance Pretty Value where
105+ pretty (String s) = pretty s
106+ pretty (Number n) = pretty $ show n
107+ pretty (Bool b) = pretty b
108+ pretty (Array arr) = PP. list $ pretty <$> V. toList arr
109+ pretty (Object obj) =
110+ PP. group
111+ . PP. encloseSep (PP. flatAlt " { " " {" ) (PP. flatAlt " }" " }" ) " , "
112+ . map
113+ ( \ (k, v) ->
114+ PP. hang 2 $
115+ PP. sep
116+ [ pretty k <+> " : "
117+ , pretty v
118+ ]
119+ )
120+ $ HM. toList obj
121+ pretty Null = " null"
122+
99123handleWriter ::
100124 forall (w :: Type ) (effs :: [Type -> Type ]).
101125 (ToJSON w , Monoid w ) =>
@@ -140,7 +164,7 @@ handlePABReq ::
140164 PABReq ->
141165 Eff effs PABResp
142166handlePABReq contractEnv req = do
143- printLog @ w Debug $ show req
167+ printBpiLog @ w Debug $ pretty req
144168 resp <- case req of
145169 ----------------------
146170 -- Handled requests --
@@ -176,7 +200,7 @@ handlePABReq contractEnv req = do
176200 -- YieldUnbalancedTxReq UnbalancedTx
177201 unsupported -> error (" Unsupported PAB effect: " ++ show unsupported)
178202
179- printLog @ w Debug $ show resp
203+ printBpiLog @ w Debug $ pretty resp
180204 pure resp
181205
182206awaitTxStatusChange ::
@@ -193,7 +217,7 @@ awaitTxStatusChange contractEnv txId = do
193217 case mTx of
194218 Nothing -> pure Unknown
195219 Just txState -> do
196- printLog @ w Debug $ " Found transaction in node, waiting " ++ show chainConstant ++ " blocks for it to settle."
220+ printBpiLog @ w Debug $ " Found transaction in node, waiting" <+> pretty chainConstant <+> " blocks for it to settle."
197221 awaitNBlocks @ w contractEnv (chainConstant + 1 )
198222 -- Check if the tx is still present in chain-index, in case of a rollback
199223 -- we might not find it anymore.
@@ -268,12 +292,15 @@ writeBalancedTx contractEnv (Right tx) = do
268292 if signable
269293 then newEitherT $ CardanoCLI. signTx @ w pabConf tx requiredSigners
270294 else
271- lift . printLog @ w Warn . Text. unpack . Text. unlines $
295+ lift . printBpiLog @ w Warn . PP. vsep $
272296 [ " Not all required signatures have signing key files. Please sign and submit the tx manually:"
273- , " Tx file: " <> Files. txFilePath pabConf " raw" (Tx. txId tx)
274- , " Signatories (pkh): " <> Text. unwords (map pkhToText requiredSigners)
297+ , " Tx file:" <+> pretty ( Files. txFilePath pabConf " raw" (Tx. txId tx) )
298+ , " Signatories (pkh):" <+> pretty ( Text. unwords (map pkhToText requiredSigners) )
275299 ]
276300
301+ when (pabConf. pcCollectStats && signable) $
302+ collectBudgetStats (Tx. txId tx) pabConf
303+
277304 when (not pabConf. pcDryRun && signable) $ do
278305 newEitherT $ CardanoCLI. submitTx @ w pabConf tx
279306
@@ -284,9 +311,6 @@ writeBalancedTx contractEnv (Right tx) = do
284311 mvFiles (Files. txFilePath pabConf " raw" (Tx. txId tx)) (Files. txFilePath pabConf " raw" cardanoTxId)
285312 when signable $ mvFiles signedSrcPath signedDstPath
286313
287- when contractEnv. cePABConfig. pcCollectStats $
288- collectBudgetStats cardanoTxId signedDstPath
289-
290314 pure cardanoTx
291315 where
292316 mvFiles :: Text -> Text -> EitherT Text (Eff effs ) ()
@@ -299,10 +323,17 @@ writeBalancedTx contractEnv (Right tx) = do
299323 , cmdOutParser = const ()
300324 }
301325
302- collectBudgetStats txId txPath = do
303- let path = Text. unpack txPath
304- b <- firstEitherT (Text. pack . show ) $ newEitherT $ estimateBudget @ w (Signed path)
305- void $ newEitherT (Right <$> saveBudget @ w txId b)
326+ collectBudgetStats txId pabConf = do
327+ let path = Text. unpack (Files. txFilePath pabConf " signed" (Tx. txId tx))
328+ txBudget <-
329+ firstEitherT toBudgetSaveError $
330+ newEitherT $ estimateBudget @ w (Signed path)
331+ void $ newEitherT (Right <$> saveBudget @ w txId txBudget)
332+
333+ toBudgetSaveError =
334+ Text. pack
335+ . (" Failed to save Tx budgets statistics: " ++ )
336+ . show
306337
307338pkhToText :: Ledger. PubKey -> Text
308339pkhToText = encodeByteString . fromBuiltin . Ledger. getPubKeyHash . Ledger. pubKeyHash
0 commit comments