{-# LANGUAGE DataKinds          #-}
{-# LANGUAGE GADTs              #-}
{-# LANGUAGE LambdaCase         #-}
{-# LANGUAGE NamedFieldPuns     #-}
{-# LANGUAGE NumericUnderscores #-}
{-# LANGUAGE OverloadedStrings  #-}
module Convex.NodeClient.Types(
  PipelinedLedgerStateClient(..),
  ClientBlock,
  runNodeClient,
  protocols,
  -- * Sync points
  ChainPoint(..),
  fromChainTip
  ) where

import           Cardano.Api                                          (BlockInMode (..),
                                                                       BlockNo (..),
                                                                       CardanoMode,
                                                                       ChainPoint (..),
                                                                       ChainSyncClientPipelined,
                                                                       ChainTip (..),
                                                                       Env (..),
                                                                       InitialLedgerStateError,
                                                                       LocalChainSyncClient (LocalChainSyncClientPipelined),
                                                                       LocalNodeClientProtocols (..),
                                                                       LocalNodeClientProtocolsInMode,
                                                                       LocalNodeConnectInfo (..),
                                                                       connectToLocalNode)
import           Cardano.Slotting.Slot                                (WithOrigin (At, Origin))
import           Control.Monad.IO.Class                               (MonadIO (..))
import           Control.Monad.Trans.Class                            (lift)
import           Control.Monad.Trans.Except                           (ExceptT)
import           Convex.NodeQueries                                   (loadConnectInfo)
import qualified Ouroboros.Network.Protocol.ChainSync.ClientPipelined as CSP

{-|
-}
newtype PipelinedLedgerStateClient =
  PipelinedLedgerStateClient
    { PipelinedLedgerStateClient
-> ChainSyncClientPipelined
     (BlockInMode CardanoMode) ChainPoint ChainTip IO ()
getPipelinedLedgerStateClient :: ChainSyncClientPipelined (BlockInMode CardanoMode) ChainPoint ChainTip IO ()
    }

runNodeClient ::
  -- | Path to the cardano-node config file (e.g. <path to cardano-node project>/configuration/cardano/mainnet-config.json)
  FilePath
  -- | Path to local cardano-node socket. This is the path specified by the @--socket-path@ command line option when running the node.
  -> FilePath
  -- | Client
  -> (LocalNodeConnectInfo CardanoMode -> Env -> IO PipelinedLedgerStateClient)
  -- | Final state
  -> ExceptT InitialLedgerStateError IO ()
runNodeClient :: FilePath
-> FilePath
-> (LocalNodeConnectInfo CardanoMode
    -> Env -> IO PipelinedLedgerStateClient)
-> ExceptT InitialLedgerStateError IO ()
runNodeClient FilePath
nodeConfigFilePath FilePath
socketPath LocalNodeConnectInfo CardanoMode
-> Env -> IO PipelinedLedgerStateClient
client = do
  (LocalNodeConnectInfo CardanoMode
connectInfo, Env
env) <- forall (m :: * -> *).
(MonadError InitialLedgerStateError m, MonadIO m) =>
FilePath -> FilePath -> m (LocalNodeConnectInfo CardanoMode, Env)
loadConnectInfo FilePath
nodeConfigFilePath FilePath
socketPath
  PipelinedLedgerStateClient
c <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (LocalNodeConnectInfo CardanoMode
-> Env -> IO PipelinedLedgerStateClient
client LocalNodeConnectInfo CardanoMode
connectInfo Env
env)
  forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ forall mode.
LocalNodeConnectInfo mode
-> LocalNodeClientProtocolsInMode mode -> IO ()
connectToLocalNode LocalNodeConnectInfo CardanoMode
connectInfo (PipelinedLedgerStateClient
-> LocalNodeClientProtocolsInMode CardanoMode
protocols PipelinedLedgerStateClient
c)

protocols :: PipelinedLedgerStateClient -> LocalNodeClientProtocolsInMode CardanoMode
protocols :: PipelinedLedgerStateClient
-> LocalNodeClientProtocolsInMode CardanoMode
protocols PipelinedLedgerStateClient
client =
  LocalNodeClientProtocols {
    localChainSyncClient :: LocalChainSyncClient
  (BlockInMode CardanoMode) ChainPoint ChainTip IO
localChainSyncClient    = forall block point tip (m :: * -> *).
ChainSyncClientPipelined block point tip m ()
-> LocalChainSyncClient block point tip m
LocalChainSyncClientPipelined (PipelinedLedgerStateClient
-> ChainSyncClientPipelined
     (BlockInMode CardanoMode) ChainPoint ChainTip IO ()
chainSyncClient PipelinedLedgerStateClient
client),
    localTxSubmissionClient :: Maybe
  (LocalTxSubmissionClient
     (TxInMode CardanoMode) (TxValidationErrorInMode CardanoMode) IO ())
localTxSubmissionClient = forall a. Maybe a
Nothing,
    localStateQueryClient :: Maybe
  (LocalStateQueryClient
     (BlockInMode CardanoMode)
     ChainPoint
     (QueryInMode CardanoMode)
     IO
     ())
localStateQueryClient   = forall a. Maybe a
Nothing,
    localTxMonitoringClient :: Maybe
  (LocalTxMonitorClient
     (TxIdInMode CardanoMode) (TxInMode CardanoMode) SlotNo IO ())
localTxMonitoringClient = forall a. Maybe a
Nothing
  }

chainSyncClient :: PipelinedLedgerStateClient -> ChainSyncClientPipelined (BlockInMode CardanoMode) ChainPoint ChainTip IO ()
chainSyncClient :: PipelinedLedgerStateClient
-> ChainSyncClientPipelined
     (BlockInMode CardanoMode) ChainPoint ChainTip IO ()
chainSyncClient PipelinedLedgerStateClient{ChainSyncClientPipelined
  (BlockInMode CardanoMode) ChainPoint ChainTip IO ()
getPipelinedLedgerStateClient :: ChainSyncClientPipelined
  (BlockInMode CardanoMode) ChainPoint ChainTip IO ()
getPipelinedLedgerStateClient :: PipelinedLedgerStateClient
-> ChainSyncClientPipelined
     (BlockInMode CardanoMode) ChainPoint ChainTip IO ()
getPipelinedLedgerStateClient} = forall header point tip (m :: * -> *) a.
m (ClientPipelinedStIdle 'Z header point tip m a)
-> ChainSyncClientPipelined header point tip m a
CSP.ChainSyncClientPipelined forall a b. (a -> b) -> a -> b
$
  let CSP.ChainSyncClientPipelined{IO
  (ClientPipelinedStIdle
     'Z (BlockInMode CardanoMode) ChainPoint ChainTip IO ())
runChainSyncClientPipelined :: forall header point tip (m :: * -> *) a.
ChainSyncClientPipelined header point tip m a
-> m (ClientPipelinedStIdle 'Z header point tip m a)
runChainSyncClientPipelined :: IO
  (ClientPipelinedStIdle
     'Z (BlockInMode CardanoMode) ChainPoint ChainTip IO ())
CSP.runChainSyncClientPipelined} = ChainSyncClientPipelined
  (BlockInMode CardanoMode) ChainPoint ChainTip IO ()
getPipelinedLedgerStateClient
  in IO
  (ClientPipelinedStIdle
     'Z (BlockInMode CardanoMode) ChainPoint ChainTip IO ())
runChainSyncClientPipelined

type ClientBlock = BlockInMode CardanoMode

fromChainTip :: ChainTip -> WithOrigin BlockNo
fromChainTip :: ChainTip -> WithOrigin BlockNo
fromChainTip ChainTip
ct = case ChainTip
ct of
  ChainTip
ChainTipAtGenesis -> forall t. WithOrigin t
Origin
  ChainTip SlotNo
_ Hash BlockHeader
_ BlockNo
bno  -> forall t. t -> WithOrigin t
At BlockNo
bno