{-# LANGUAGE AllowAmbiguousTypes  #-}
{-# LANGUAGE DeriveAnyClass       #-}
{-# LANGUAGE DerivingStrategies   #-}
{-# LANGUAGE FlexibleInstances    #-}
{-# LANGUAGE LambdaCase           #-}
{-# LANGUAGE NamedFieldPuns       #-}
{-# LANGUAGE RankNTypes           #-}
{-# LANGUAGE TypeApplications     #-}
{-# LANGUAGE UndecidableInstances #-}
{-| Glue code
-}
module Convex.Devnet.Wallet(
  faucet,
  sendFaucetFundsTo,
  createSeededWallet,
  walletUtxos,
  balanceAndSubmit,
  balanceAndSubmitReturn,
  WalletLog(..),
  -- * Tracer / MonadLog interop
  TracerMonadLogT(..),
  runTracerMonadLogT,
  runningNodeBlockchain
) where

import           Cardano.Api               (AddressInEra, BabbageEra, BuildTx,
                                            Lovelace, Tx, TxBodyContent)
import qualified Cardano.Api               as C
import           Control.Monad             (replicateM)
import           Control.Monad.IO.Class    (MonadIO (..))
import           Control.Monad.Reader      (ReaderT (..), ask, lift)
import           Control.Tracer            (Tracer, traceWith)
import qualified Convex.BuildTx            as BuildTx
import           Convex.Class              (MonadBlockchain (networkId),
                                            runMonadBlockchainCardanoNodeT,
                                            sendTx)
import qualified Convex.CoinSelection      as CoinSelection
import           Convex.Devnet.CardanoNode (RunningNode (..))
import qualified Convex.Devnet.NodeQueries as NodeQueries
import           Convex.Devnet.Utils       (keysFor)
import           Convex.Lenses             (emptyTxOut)
import           Convex.MonadLog           (MonadLog (..))
import           Convex.Utxos              (UtxoSet)
import qualified Convex.Utxos              as Utxos
import           Convex.Wallet             (Wallet (..), address)
import qualified Convex.Wallet             as Wallet
import           Data.Aeson                (FromJSON, ToJSON)
import           Data.Text                 (Text)
import           GHC.Generics              (Generic)
import           Prettyprinter             (defaultLayoutOptions, layoutPretty)
import qualified Prettyprinter.Render.Text as Render

faucet :: IO Wallet
faucet :: IO Wallet
faucet = SigningKey PaymentKey -> Wallet
Wallet forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO (VerificationKey PaymentKey, SigningKey PaymentKey)
keysFor String
"faucet"

{-| Query the node for UTXOs that belong to the wallet
-}
walletUtxos :: RunningNode -> Wallet -> IO (UtxoSet C.CtxUTxO ())
walletUtxos :: RunningNode -> Wallet -> IO (UtxoSet CtxUTxO ())
walletUtxos RunningNode{String
rnNodeSocket :: RunningNode -> String
rnNodeSocket :: String
rnNodeSocket, NetworkId
rnNetworkId :: RunningNode -> NetworkId
rnNetworkId :: NetworkId
rnNetworkId} Wallet
wllt =
  UTxO BabbageEra -> UtxoSet CtxUTxO ()
Utxos.fromApiUtxo forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NetworkId
-> String -> [Address ShelleyAddr] -> IO (UTxO BabbageEra)
NodeQueries.queryUTxO NetworkId
rnNetworkId String
rnNodeSocket [NetworkId -> Wallet -> Address ShelleyAddr
address NetworkId
rnNetworkId Wallet
wllt]

{-| Send @n@ times the given amount of lovelace to the address
-}
sendFaucetFundsTo :: Tracer IO WalletLog -> RunningNode -> AddressInEra BabbageEra -> Int -> Lovelace -> IO (Tx BabbageEra)
sendFaucetFundsTo :: Tracer IO WalletLog
-> RunningNode
-> AddressInEra BabbageEra
-> Int
-> Lovelace
-> IO (Tx BabbageEra)
sendFaucetFundsTo Tracer IO WalletLog
tracer RunningNode
node AddressInEra BabbageEra
destination Int
n Lovelace
amount = do
  Wallet
fct <- IO Wallet
faucet
  Tracer IO WalletLog
-> RunningNode
-> Wallet
-> TxBodyContent BuildTx BabbageEra
-> IO (Tx BabbageEra)
balanceAndSubmit Tracer IO WalletLog
tracer RunningNode
node Wallet
fct forall a b. (a -> b) -> a -> b
$ forall a. BuildTxT Identity a -> TxBodyContent BuildTx BabbageEra
BuildTx.execBuildTx' forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
n (forall (m :: * -> *).
MonadBuildTx m =>
AddressInEra BabbageEra -> Value -> m ()
BuildTx.payToAddress AddressInEra BabbageEra
destination (Lovelace -> Value
C.lovelaceToValue Lovelace
amount))

{-| Create a new wallet and send @n@ times the given amount of lovelace to it. Returns when the seed txn has been registered
on the chain.
-}
createSeededWallet :: Tracer IO WalletLog -> RunningNode -> Int -> Lovelace -> IO Wallet
createSeededWallet :: Tracer IO WalletLog -> RunningNode -> Int -> Lovelace -> IO Wallet
createSeededWallet Tracer IO WalletLog
tracer node :: RunningNode
node@RunningNode{NetworkId
rnNetworkId :: NetworkId
rnNetworkId :: RunningNode -> NetworkId
rnNetworkId, String
rnNodeSocket :: String
rnNodeSocket :: RunningNode -> String
rnNodeSocket} Int
n Lovelace
amount = do
  Wallet
wallet <- IO Wallet
Wallet.generateWallet
  forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer IO WalletLog
tracer (Wallet -> WalletLog
GeneratedWallet Wallet
wallet)
  Tracer IO WalletLog
-> RunningNode
-> AddressInEra BabbageEra
-> Int
-> Lovelace
-> IO (Tx BabbageEra)
sendFaucetFundsTo Tracer IO WalletLog
tracer RunningNode
node (forall era.
IsShelleyBasedEra era =>
NetworkId -> Wallet -> AddressInEra era
Wallet.addressInEra NetworkId
rnNetworkId Wallet
wallet) Int
n Lovelace
amount forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= NetworkId -> String -> Tx BabbageEra -> IO ()
NodeQueries.waitForTxn NetworkId
rnNetworkId String
rnNodeSocket
  forall (f :: * -> *) a. Applicative f => a -> f a
pure Wallet
wallet

{-| Run a 'MonadBlockchain' action, using the @Tracer@ for log messages and the
@RunningNode@ for blockchain stuff
-}
runningNodeBlockchain ::
 forall e a. (Show e)
  => Tracer IO WalletLog
  -> RunningNode
  -> (forall m. (MonadFail m, MonadLog m, MonadBlockchain m) => m a)
  -> IO a
runningNodeBlockchain :: forall e a.
Show e =>
Tracer IO WalletLog
-> RunningNode
-> (forall (m :: * -> *).
    (MonadFail m, MonadLog m, MonadBlockchain m) =>
    m a)
-> IO a
runningNodeBlockchain Tracer IO WalletLog
tracer RunningNode{String
rnNodeSocket :: String
rnNodeSocket :: RunningNode -> String
rnNodeSocket, NetworkId
rnNetworkId :: NetworkId
rnNetworkId :: RunningNode -> NetworkId
rnNetworkId} forall (m :: * -> *).
(MonadFail m, MonadLog m, MonadBlockchain m) =>
m a
h =
  let info :: LocalNodeConnectInfo CardanoMode
info = NetworkId -> String -> LocalNodeConnectInfo CardanoMode
NodeQueries.localNodeConnectInfo NetworkId
rnNetworkId String
rnNodeSocket
  in forall (m :: * -> *) a.
Tracer m WalletLog -> TracerMonadLogT m a -> m a
runTracerMonadLogT Tracer IO WalletLog
tracer forall a b. (a -> b) -> a -> b
$ do
      forall e (m :: * -> *) a.
LocalNodeConnectInfo CardanoMode
-> MonadBlockchainCardanoNodeT e m a
-> m (Either (MonadBlockchainError e) a)
runMonadBlockchainCardanoNodeT @e LocalNodeConnectInfo CardanoMode
info forall (m :: * -> *).
(MonadFail m, MonadLog m, MonadBlockchain m) =>
m a
h forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show) forall (f :: * -> *) a. Applicative f => a -> f a
pure

{-| Balance and submit the transaction using the wallet's UTXOs
-}
balanceAndSubmit :: Tracer IO WalletLog -> RunningNode -> Wallet -> TxBodyContent BuildTx BabbageEra -> IO (Tx BabbageEra)
balanceAndSubmit :: Tracer IO WalletLog
-> RunningNode
-> Wallet
-> TxBodyContent BuildTx BabbageEra
-> IO (Tx BabbageEra)
balanceAndSubmit Tracer IO WalletLog
tracer RunningNode
node Wallet
wallet TxBodyContent BuildTx BabbageEra
tx = do
  NetworkId
n <- forall e a.
Show e =>
Tracer IO WalletLog
-> RunningNode
-> (forall (m :: * -> *).
    (MonadFail m, MonadLog m, MonadBlockchain m) =>
    m a)
-> IO a
runningNodeBlockchain @String Tracer IO WalletLog
tracer RunningNode
node forall (m :: * -> *). MonadBlockchain m => m NetworkId
networkId
  let walletAddress :: AddressInEra BabbageEra
walletAddress = forall era.
IsShelleyBasedEra era =>
NetworkId -> Wallet -> AddressInEra era
Wallet.addressInEra NetworkId
n Wallet
wallet
      txOut :: TxOut CtxTx BabbageEra
txOut = AddressInEra BabbageEra -> TxOut CtxTx BabbageEra
emptyTxOut AddressInEra BabbageEra
walletAddress
  Tracer IO WalletLog
-> RunningNode
-> Wallet
-> TxOut CtxTx BabbageEra
-> TxBodyContent BuildTx BabbageEra
-> IO (Tx BabbageEra)
balanceAndSubmitReturn Tracer IO WalletLog
tracer RunningNode
node Wallet
wallet TxOut CtxTx BabbageEra
txOut TxBodyContent BuildTx BabbageEra
tx

{-| Balance and submit the transaction using the wallet's UTXOs
-}
balanceAndSubmitReturn :: Tracer IO WalletLog -> RunningNode -> Wallet -> C.TxOut C.CtxTx C.BabbageEra -> TxBodyContent BuildTx BabbageEra -> IO (Tx BabbageEra)
balanceAndSubmitReturn :: Tracer IO WalletLog
-> RunningNode
-> Wallet
-> TxOut CtxTx BabbageEra
-> TxBodyContent BuildTx BabbageEra
-> IO (Tx BabbageEra)
balanceAndSubmitReturn Tracer IO WalletLog
tracer RunningNode
node Wallet
wallet TxOut CtxTx BabbageEra
returnOutput TxBodyContent BuildTx BabbageEra
tx = do
  UtxoSet CtxUTxO ()
utxos <- RunningNode -> Wallet -> IO (UtxoSet CtxUTxO ())
walletUtxos RunningNode
node Wallet
wallet
  forall e a.
Show e =>
Tracer IO WalletLog
-> RunningNode
-> (forall (m :: * -> *).
    (MonadFail m, MonadLog m, MonadBlockchain m) =>
    m a)
-> IO a
runningNodeBlockchain @String Tracer IO WalletLog
tracer RunningNode
node forall a b. (a -> b) -> a -> b
$ do
    (Tx BabbageEra
tx', BalanceChanges
_) <- forall (m :: * -> *) a.
(MonadBlockchain m, MonadFail m) =>
Wallet
-> UtxoSet CtxUTxO a
-> TxOut CtxTx BabbageEra
-> TxBodyContent BuildTx BabbageEra
-> m (Tx BabbageEra, BalanceChanges)
CoinSelection.balanceForWalletReturn Wallet
wallet UtxoSet CtxUTxO ()
utxos TxOut CtxTx BabbageEra
returnOutput TxBodyContent BuildTx BabbageEra
tx
    TxId
_ <- forall (m :: * -> *). MonadBlockchain m => Tx BabbageEra -> m TxId
sendTx Tx BabbageEra
tx'
    forall (f :: * -> *) a. Applicative f => a -> f a
pure Tx BabbageEra
tx'

data WalletLog =
  WalletLogInfo Text
  | WalletLogWarn Text
  | GeneratedWallet Wallet
  deriving stock (Int -> WalletLog -> ShowS
[WalletLog] -> ShowS
WalletLog -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [WalletLog] -> ShowS
$cshowList :: [WalletLog] -> ShowS
show :: WalletLog -> String
$cshow :: WalletLog -> String
showsPrec :: Int -> WalletLog -> ShowS
$cshowsPrec :: Int -> WalletLog -> ShowS
Show, forall x. Rep WalletLog x -> WalletLog
forall x. WalletLog -> Rep WalletLog x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep WalletLog x -> WalletLog
$cfrom :: forall x. WalletLog -> Rep WalletLog x
Generic)
  deriving anyclass ([WalletLog] -> Encoding
[WalletLog] -> Value
WalletLog -> Encoding
WalletLog -> Value
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [WalletLog] -> Encoding
$ctoEncodingList :: [WalletLog] -> Encoding
toJSONList :: [WalletLog] -> Value
$ctoJSONList :: [WalletLog] -> Value
toEncoding :: WalletLog -> Encoding
$ctoEncoding :: WalletLog -> Encoding
toJSON :: WalletLog -> Value
$ctoJSON :: WalletLog -> Value
ToJSON, Value -> Parser [WalletLog]
Value -> Parser WalletLog
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [WalletLog]
$cparseJSONList :: Value -> Parser [WalletLog]
parseJSON :: Value -> Parser WalletLog
$cparseJSON :: Value -> Parser WalletLog
FromJSON)

newtype TracerMonadLogT m a = TracerMonadLogT{forall (m :: * -> *) a.
TracerMonadLogT m a -> ReaderT (Tracer m WalletLog) m a
unTracerMonadLogT :: ReaderT (Tracer m WalletLog) m a}
  deriving newtype (forall a b. a -> TracerMonadLogT m b -> TracerMonadLogT m a
forall a b. (a -> b) -> TracerMonadLogT m a -> TracerMonadLogT m b
forall (m :: * -> *) a b.
Functor m =>
a -> TracerMonadLogT m b -> TracerMonadLogT m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> TracerMonadLogT m a -> TracerMonadLogT m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> TracerMonadLogT m b -> TracerMonadLogT m a
$c<$ :: forall (m :: * -> *) a b.
Functor m =>
a -> TracerMonadLogT m b -> TracerMonadLogT m a
fmap :: forall a b. (a -> b) -> TracerMonadLogT m a -> TracerMonadLogT m b
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> TracerMonadLogT m a -> TracerMonadLogT m b
Functor, forall a. a -> TracerMonadLogT m a
forall a b.
TracerMonadLogT m a -> TracerMonadLogT m b -> TracerMonadLogT m a
forall a b.
TracerMonadLogT m a -> TracerMonadLogT m b -> TracerMonadLogT m b
forall a b.
TracerMonadLogT m (a -> b)
-> TracerMonadLogT m a -> TracerMonadLogT m b
forall a b c.
(a -> b -> c)
-> TracerMonadLogT m a
-> TracerMonadLogT m b
-> TracerMonadLogT m c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
forall {m :: * -> *}. Applicative m => Functor (TracerMonadLogT m)
forall (m :: * -> *) a. Applicative m => a -> TracerMonadLogT m a
forall (m :: * -> *) a b.
Applicative m =>
TracerMonadLogT m a -> TracerMonadLogT m b -> TracerMonadLogT m a
forall (m :: * -> *) a b.
Applicative m =>
TracerMonadLogT m a -> TracerMonadLogT m b -> TracerMonadLogT m b
forall (m :: * -> *) a b.
Applicative m =>
TracerMonadLogT m (a -> b)
-> TracerMonadLogT m a -> TracerMonadLogT m b
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> TracerMonadLogT m a
-> TracerMonadLogT m b
-> TracerMonadLogT m c
<* :: forall a b.
TracerMonadLogT m a -> TracerMonadLogT m b -> TracerMonadLogT m a
$c<* :: forall (m :: * -> *) a b.
Applicative m =>
TracerMonadLogT m a -> TracerMonadLogT m b -> TracerMonadLogT m a
*> :: forall a b.
TracerMonadLogT m a -> TracerMonadLogT m b -> TracerMonadLogT m b
$c*> :: forall (m :: * -> *) a b.
Applicative m =>
TracerMonadLogT m a -> TracerMonadLogT m b -> TracerMonadLogT m b
liftA2 :: forall a b c.
(a -> b -> c)
-> TracerMonadLogT m a
-> TracerMonadLogT m b
-> TracerMonadLogT m c
$cliftA2 :: forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> TracerMonadLogT m a
-> TracerMonadLogT m b
-> TracerMonadLogT m c
<*> :: forall a b.
TracerMonadLogT m (a -> b)
-> TracerMonadLogT m a -> TracerMonadLogT m b
$c<*> :: forall (m :: * -> *) a b.
Applicative m =>
TracerMonadLogT m (a -> b)
-> TracerMonadLogT m a -> TracerMonadLogT m b
pure :: forall a. a -> TracerMonadLogT m a
$cpure :: forall (m :: * -> *) a. Applicative m => a -> TracerMonadLogT m a
Applicative, forall a. a -> TracerMonadLogT m a
forall a b.
TracerMonadLogT m a -> TracerMonadLogT m b -> TracerMonadLogT m b
forall a b.
TracerMonadLogT m a
-> (a -> TracerMonadLogT m b) -> TracerMonadLogT m b
forall {m :: * -> *}. Monad m => Applicative (TracerMonadLogT m)
forall (m :: * -> *) a. Monad m => a -> TracerMonadLogT m a
forall (m :: * -> *) a b.
Monad m =>
TracerMonadLogT m a -> TracerMonadLogT m b -> TracerMonadLogT m b
forall (m :: * -> *) a b.
Monad m =>
TracerMonadLogT m a
-> (a -> TracerMonadLogT m b) -> TracerMonadLogT m b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: forall a. a -> TracerMonadLogT m a
$creturn :: forall (m :: * -> *) a. Monad m => a -> TracerMonadLogT m a
>> :: forall a b.
TracerMonadLogT m a -> TracerMonadLogT m b -> TracerMonadLogT m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
TracerMonadLogT m a -> TracerMonadLogT m b -> TracerMonadLogT m b
>>= :: forall a b.
TracerMonadLogT m a
-> (a -> TracerMonadLogT m b) -> TracerMonadLogT m b
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
TracerMonadLogT m a
-> (a -> TracerMonadLogT m b) -> TracerMonadLogT m b
Monad, forall a. String -> TracerMonadLogT m a
forall (m :: * -> *).
Monad m -> (forall a. String -> m a) -> MonadFail m
forall {m :: * -> *}. MonadFail m => Monad (TracerMonadLogT m)
forall (m :: * -> *) a.
MonadFail m =>
String -> TracerMonadLogT m a
fail :: forall a. String -> TracerMonadLogT m a
$cfail :: forall (m :: * -> *) a.
MonadFail m =>
String -> TracerMonadLogT m a
MonadFail, forall a. IO a -> TracerMonadLogT m a
forall (m :: * -> *).
Monad m -> (forall a. IO a -> m a) -> MonadIO m
forall {m :: * -> *}. MonadIO m => Monad (TracerMonadLogT m)
forall (m :: * -> *) a. MonadIO m => IO a -> TracerMonadLogT m a
liftIO :: forall a. IO a -> TracerMonadLogT m a
$cliftIO :: forall (m :: * -> *) a. MonadIO m => IO a -> TracerMonadLogT m a
MonadIO)

runTracerMonadLogT :: Tracer m WalletLog -> TracerMonadLogT m a -> m a
runTracerMonadLogT :: forall (m :: * -> *) a.
Tracer m WalletLog -> TracerMonadLogT m a -> m a
runTracerMonadLogT Tracer m WalletLog
t (TracerMonadLogT ReaderT (Tracer m WalletLog) m a
r) = forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT (Tracer m WalletLog) m a
r Tracer m WalletLog
t

instance Monad m => MonadLog (TracerMonadLogT m) where
  logInfo' :: Doc Void -> TracerMonadLogT m ()
logInfo' Doc Void
msg = forall (m :: * -> *) a.
ReaderT (Tracer m WalletLog) m a -> TracerMonadLogT m a
TracerMonadLogT forall a b. (a -> b) -> a -> b
$ do
    Tracer m WalletLog
tr <- forall r (m :: * -> *). MonadReader r m => m r
ask
    let rendered :: Text
rendered = forall ann. SimpleDocStream ann -> Text
Render.renderStrict (forall ann. LayoutOptions -> Doc ann -> SimpleDocStream ann
layoutPretty LayoutOptions
defaultLayoutOptions Doc Void
msg)
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m WalletLog
tr (Text -> WalletLog
WalletLogInfo Text
rendered))
  logWarn' :: Doc Void -> TracerMonadLogT m ()
logWarn' Doc Void
msg = forall (m :: * -> *) a.
ReaderT (Tracer m WalletLog) m a -> TracerMonadLogT m a
TracerMonadLogT forall a b. (a -> b) -> a -> b
$ do
    Tracer m WalletLog
tr <- forall r (m :: * -> *). MonadReader r m => m r
ask
    let rendered :: Text
rendered = forall ann. SimpleDocStream ann -> Text
Render.renderStrict (forall ann. LayoutOptions -> Doc ann -> SimpleDocStream ann
layoutPretty LayoutOptions
defaultLayoutOptions Doc Void
msg)
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m WalletLog
tr (Text -> WalletLog
WalletLogWarn Text
rendered))
  logDebug' :: Doc Void -> TracerMonadLogT m ()
logDebug' Doc Void
msg = forall (m :: * -> *) a.
ReaderT (Tracer m WalletLog) m a -> TracerMonadLogT m a
TracerMonadLogT forall a b. (a -> b) -> a -> b
$ do
    Tracer m WalletLog
tr <- forall r (m :: * -> *). MonadReader r m => m r
ask
    let rendered :: Text
rendered = forall ann. SimpleDocStream ann -> Text
Render.renderStrict (forall ann. LayoutOptions -> Doc ann -> SimpleDocStream ann
layoutPretty LayoutOptions
defaultLayoutOptions Doc Void
msg)
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m WalletLog
tr (Text -> WalletLog
WalletLogWarn Text
rendered))