-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Please see the README on GitHub at
--   <a>https://github.com/githubuser/cardano-shell#readme</a>
@package cardano-shell
@version 0.1.0.0


-- | NodeJS <tt>child_process()</tt> IPC message protocol.
--   
--   See
--   <a>https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options</a>
--   for more information about the message protocol.
module Cardano.Shell.NodeIPC.General

-- | A h to the NodeJS parent process.
data NodeChannel

-- | Possible reasons why the node channel can't be set up.
data NodeChannelError

-- | This process has not been started as a nodejs <tt><tt>ipc</tt></tt>
--   child_process.
NodeChannelDisabled :: NodeChannelError

-- | The <tt>NODE_CHANNEL_FD</tt> environment variable has an incorrect
--   value.
NodeChannelBadFD :: Text -> NodeChannelError

-- | The only way a node channel finishes on its own is if there is some
--   error reading or writing to its file descriptor.
newtype NodeChannelFinished
NodeChannelFinished :: IOError -> NodeChannelFinished

-- | Parse the <tt>NODE_CHANNEL_FD</tt> variable, if it's set, and returns
--   a h for communicating with the parent process.
setupNodeChannel :: IO (Either NodeChannelError NodeChannel)

-- | Communicate with a parent process using a NodeJS-specific protocol.
--   This process must have been spawned with one of <tt>stdio</tt> array
--   entries set to <tt><tt>ipc</tt></tt>.
runNodeChannel :: (FromJSON msgin, ToJSON msgout) => (Either Text msgin -> IO (Maybe msgout)) -> ((msgout -> IO ()) -> IO a) -> NodeChannel -> IO (Either NodeChannelFinished a)
instance GHC.Classes.Eq Cardano.Shell.NodeIPC.General.NodeChannelError
instance GHC.Show.Show Cardano.Shell.NodeIPC.General.NodeChannelError


-- | Daedalus <a>-</a> Wallet child process port discovery protocol.
--   Provides a mechanism for Daedalus to discover what port the
--   cardano-wallet server is listening on.
--   
--   See
--   <a>https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options</a>
--   for more information about the message protocol.
module Cardano.Shell.DaedalusIPC

-- | Start up the Daedalus IPC process. It's called <a>daedalusIPC</a>, but
--   this could be any nodejs program that needs to start cardano-wallet.
--   All it does is reply with a port number when asked, using a very
--   nodejs-specific IPC method.
--   
--   If the IPC channel was successfully set up, this function won't return
--   until the parent process exits. Otherwise, it will return immediately.
--   Before returning, it will log an message about why it has exited.
--   
--   TODO(KS): If you want to use TRACE here, you need to provide the trace
--   functions as params OR provide a record of trace functions.
daedalusIPC :: Int -> IO ()
instance GHC.Classes.Eq Cardano.Shell.DaedalusIPC.MsgIn
instance GHC.Show.Show Cardano.Shell.DaedalusIPC.MsgIn
instance GHC.Classes.Eq Cardano.Shell.DaedalusIPC.MsgOut
instance GHC.Show.Show Cardano.Shell.DaedalusIPC.MsgOut
instance Data.Aeson.Types.ToJSON.ToJSON Cardano.Shell.DaedalusIPC.MsgOut
instance Data.Aeson.Types.FromJSON.FromJSON Cardano.Shell.DaedalusIPC.MsgIn


-- | Node IPC module. For details please read the spec:
--   
--   
--   <a>https://github.com/input-output-hk/cardano-shell/blob/develop/specs/CardanoShellSpec.pdf</a>
module Cardano.Shell.NodeIPC

-- | Port that is used to communicate between Cardano-node and Daedalus
--   (e.g <tt>8090</tt>)
newtype Port
Port :: Word16 -> Port
[getPort] :: Port -> Word16

-- | Message from the server being sent to the client.
data MsgIn

-- | Ask which port to use
QueryPort :: MsgIn

-- | Ping
Ping :: MsgIn

-- | Shutdown message from the server
Shutdown :: MsgIn
MessageInFailure :: MessageSendFailure -> MsgIn

-- | Message which is send out from Cardano-node
data MsgOut

-- | Notify Daedalus that the node has started
Started :: MsgOut

-- | Reply of QueryPort
ReplyPort :: Word16 -> MsgOut

-- | Reply of Ping
Pong :: MsgOut

-- | Reply of shutdown
ShutdownInitiated :: MsgOut
MessageOutFailure :: MessageSendFailure -> MsgOut

-- | Read-only handle
newtype ReadHandle
ReadHandle :: Handle -> ReadHandle
[getReadHandle] :: ReadHandle -> Handle

-- | Write-only handle
newtype WriteHandle
WriteHandle :: Handle -> WriteHandle
[getWriteHandle] :: WriteHandle -> Handle

-- | When using pipes, <b>the write doesn't block, but the read blocks</b>!
--   As a consequence, we eiter need to use IDs to keep track of the
--   client/server pair, or (read) block so we know which message pair
--   arrived. This might seems an overkill for this task, but it's actually
--   required if we want to reason about it and test it properly.
--   
--   <pre>
--   &gt;&gt;&gt; (readEnd, writeEnd) &lt;- createPipe
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; replicateM 100 $ sendMessage (WriteHandle writeEnd) Cardano.Shell.NodeIPC.Ping
--   [(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),()]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; mesg &lt;- replicateM 100 ((readMessage (ReadHandle readEnd)) :: IO MsgIn)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; mesg &lt;- (readMessage (ReadHandle readEnd)) :: IO MsgIn
--   </pre>
--   
--   Blocked!
--   
--   The way the IPC protocol works - it either responds to a single
--   <b>IPC</b> message or it remains in a loop responding to multiple
--   messages.
data ProtocolDuration

-- | Responds to a single message and exits
SingleMessage :: ProtocolDuration

-- | Runs forever responding to messages
MultiMessage :: ProtocolDuration

-- | Start IPC with NodeJS
--   
--   This only works if NodeJS spawns the Haskell executable as child
--   process (See <tt>server.js</tt> as an example)
startNodeJsIPC :: ProtocolDuration -> Port -> IO (Either NodeIPCError ())

-- | Start IPC with given <a>ReadHandle</a>, <a>WriteHandle</a> and
--   <a>Port</a>
startIPC :: ProtocolDuration -> ReadHandle -> WriteHandle -> Port -> IO (Either NodeIPCError ())

-- | Function for handling the protocol
handleIPCProtocol :: Port -> MsgIn -> IO MsgOut

-- | Client side IPC protocol.
clientIPCListener :: ProtocolDuration -> ClientHandles -> Port -> IO (Either NodeIPCError ())

-- | Test <a>startIPC</a>
testStartNodeIPC :: ToJSON msg => Port -> msg -> IO (MsgOut, MsgOut)

-- | The set of handles for the server, the halves of one pipe.
data ServerHandles
ServerHandles :: !ReadHandle -> !WriteHandle -> ServerHandles
[getServerReadHandle] :: ServerHandles -> !ReadHandle
[getServerWriteHandle] :: ServerHandles -> !WriteHandle

-- | The set of handles for the client, the halves of one pipe.
data ClientHandles
ClientHandles :: !ReadHandle -> !WriteHandle -> ClientHandles
[getClientReadHandle] :: ClientHandles -> !ReadHandle
[getClientWriteHandle] :: ClientHandles -> !WriteHandle

-- | Close the pipe handles.
closeFullDuplexAnonPipesHandles :: (ServerHandles, ClientHandles) -> IO ()

-- | Creation of a two-way communication between the server and the client.
--   Full-duplex (two-way) communication normally requires two anonymous
--   pipes. TODO(KS): Bracket this!
createFullDuplexAnonPipesHandles :: IO (ServerHandles, ClientHandles)

-- | A bracket function that can be useful.
bracketFullDuplexAnonPipesHandles :: ((ServerHandles, ClientHandles) -> IO ()) -> IO ()

-- | This is a <b>blocking call</b> that sends the message to the client
--   and returns it's response, <b>after the client response arrives</b>.
serverReadWrite :: ServerHandles -> MsgIn -> IO (Either NodeIPCError MsgOut)

-- | Exception thrown from Node IPC protocol
data NodeIPCError

-- | Node channel was not found
NodeChannelNotFound :: Text -> NodeIPCError

-- | Unable to parse given <a>Text</a> as File descriptor
UnableToParseNodeChannel :: Text -> NodeIPCError

-- | Exception thrown when there's something wrong with IPC
IPCError :: NodeIPCError

-- | Given handle is closed therefore cannot be used
HandleClosed :: Handle -> NodeIPCError

-- | Given handle End Of File
HandleEOF :: Handle -> NodeIPCError

-- | Given handle cannot be used to read
UnreadableHandle :: Handle -> NodeIPCError

-- | Given handle cannot be used to write
UnwritableHandle :: Handle -> NodeIPCError
NoStdIn :: NodeIPCError

-- | Message that can be used to let the other know the that exception had
--   occured
data MessageSendFailure
ParseError :: Text -> MessageSendFailure
GeneralFailure :: MessageSendFailure

-- | Exception
data MessageException
DecodeFail :: ByteString -> MessageException

-- | Send JSON message with given <a>WriteHandle</a>
sendMessage :: (MonadIO m, ToJSON msg) => WriteHandle -> msg -> m ()

-- | Read JSON message with given <a>ReadHandle</a>
readMessage :: (MonadIO m, MonadThrow m, FromJSON msg) => ReadHandle -> m msg

-- | Example using file descriptor
exampleWithFD :: MsgIn -> IO (MsgOut, MsgOut)

-- | Example of an IPC server that is using haskell executable as an
--   server.
--   
--   This will be the server, the one which sends the message (such as
--   <tt>Ping</tt>, <tt>QueryPort</tt>) to get the response from the
--   client. The client is executed via <tt>stack exec node-ipc
--   haskell</tt>
exampleServerWithProcess :: MsgIn -> IO (Either NodeIPCError (MsgOut, MsgOut))

-- | Create a pipe for interprocess communication and return a
--   (<a>ReadHandle</a>, <a>WriteHandle</a>) Handle pair.
getReadWriteHandles :: IO (ReadHandle, WriteHandle)

-- | Acquire a Handle that can be used for IPC from Environment
getHandleFromEnv :: String -> IO (Either NodeIPCError Handle)

-- | Checks if given <a>NodeIPCError</a> is <a>IPCError</a>
isIPCError :: NodeIPCError -> Bool

-- | Checks if given <a>NodeIPCError</a> is <a>HandleClosed</a>
isHandleClosed :: NodeIPCError -> Bool

-- | Checks if given <a>NodeIPCError</a> is <a>UnreadableHandle</a>
isUnreadableHandle :: NodeIPCError -> Bool

-- | Checks if given <a>NodeIPCError</a> is <a>UnwritableHandle</a>
isUnwritableHandle :: NodeIPCError -> Bool

-- | Checks if given <a>NodeIPCError</a> is <a>NodeChannelNotFound</a>
isNodeChannelCannotBeFound :: NodeIPCError -> Bool

module Cardano.Shell.Types

-- | The interface for the running feature, the high-level interface we use
--   for running it.
data CardanoFeature
CardanoFeature :: Text -> (forall m. (MonadIO m, MonadConc m) => m ()) -> (forall m. (MonadIO m, MonadConc m) => m ()) -> CardanoFeature

-- | The name of the feature.
[featureName] :: CardanoFeature -> Text

-- | What we call when we start the feature.
[featureStart] :: CardanoFeature -> forall m. (MonadIO m, MonadConc m) => m ()

-- | What we call when we shut down the feature.
[featureShutdown] :: CardanoFeature -> forall m. (MonadIO m, MonadConc m) => m ()

-- | Cardano feature initialization. We are saying "you have the
--   responsibility to make sure you use the right context!".
data CardanoFeatureInit env dependency cardanoConfiguration featureConfiguration layer
CardanoFeatureInit :: !Text -> (env -> dependency -> cardanoConfiguration -> featureConfiguration -> IO layer) -> (layer -> IO ()) -> CardanoFeatureInit env dependency cardanoConfiguration featureConfiguration layer

-- | The type of the feature that we use.
[featureType] :: CardanoFeatureInit env dependency cardanoConfiguration featureConfiguration layer -> !Text

-- | Again, we are not sure how is the user going to run the actual
--   feature, so we provide him with the most flexible/powerful context we
--   have, <tt>IO</tt>. Notice the arrangement of the parameters -
--   specific, general, specific, general, result.
[featureInit] :: CardanoFeatureInit env dependency cardanoConfiguration featureConfiguration layer -> env -> dependency -> cardanoConfiguration -> featureConfiguration -> IO layer

-- | If the user wants to clean up the resources after the module has
--   completed running, there is an option to do so.
[featureCleanup] :: CardanoFeatureInit env dependency cardanoConfiguration featureConfiguration layer -> layer -> IO ()

-- | The option to not have any additional dependency for the
--   <tt>CardanoFeature</tt>.
data NoDependency
NoDependency :: NoDependency

-- | The application environment.
data ApplicationEnvironment
Development :: ApplicationEnvironment
Production :: ApplicationEnvironment

-- | The top level module we use to run the key functions.
newtype CardanoApplication
CardanoApplication :: IO () -> CardanoApplication
[runCardanoApplication] :: CardanoApplication -> IO ()

-- | A simple function to inform us.
applicationProductionMode :: ApplicationEnvironment -> Bool
instance GHC.Show.Show Cardano.Shell.Types.ApplicationEnvironment
instance GHC.Classes.Eq Cardano.Shell.Types.ApplicationEnvironment
instance GHC.Show.Show Cardano.Shell.Types.NoDependency
instance GHC.Classes.Eq Cardano.Shell.Types.NoDependency
instance GHC.Show.Show Cardano.Shell.Types.NoConfiguration
instance GHC.Classes.Eq Cardano.Shell.Types.NoConfiguration

module Cardano.Shell.Lib
data GeneralException
UnknownFailureException :: GeneralException
FileNotFoundException :: FilePath -> GeneralException
ConfigurationError :: Text -> GeneralException

-- | The top level module we use to run the key functions.
newtype CardanoApplication
CardanoApplication :: IO () -> CardanoApplication
[runCardanoApplication] :: CardanoApplication -> IO ()
runCardanoApplicationWithFeatures :: forall m. MonadIO m => [CardanoFeature] -> CardanoApplication -> m ()
instance GHC.Classes.Eq Cardano.Shell.Lib.GeneralException
instance GHC.Exception.Type.Exception Cardano.Shell.Lib.GeneralException
instance Formatting.Buildable.Buildable Cardano.Shell.Lib.GeneralException
instance GHC.Show.Show Cardano.Shell.Lib.GeneralException

module CardanoShellSpec
data Blockchain
Blockchain :: !Map Epoch [Slot] -> Blockchain
[getBlockchainContents] :: Blockchain -> !Map Epoch [Slot]
data Epoch
Epoch :: Int -> Epoch
data Slot
Slot :: Maybe Block -> Slot
data Block
Block :: BlockHash -> Maybe InstallerVersion -> Block
data BlockHash
BlockHash :: !Text -> BlockHash
data InstallerVersion
InstallerVersion :: InstallerHash -> InstallerVersion
data InstallerHash
InstallerHash :: !Text -> InstallerHash
newtype LatestInstallerVersion
LatestInstallerVersion :: InstallerVersion -> LatestInstallerVersion
[getInstallerVersion] :: LatestInstallerVersion -> InstallerVersion
slotContainsInstaller :: Slot -> Maybe InstallerVersion
type List a = [a]
type Pair a b = (a, b)
pattern Pair :: forall a b. a -> b -> (a, b)
implies :: Bool -> Bool -> Bool
infixr 1 `implies`
data ServerMessage
QueryPort :: ServerMessage
Ping :: ServerMessage
data ClientMessage
Started :: ClientMessage
Pong :: ClientMessage
ReplyPort :: Word16 -> ClientMessage
fullProtocol :: ServerMessage -> ClientMessage
uniqueKeys :: Ord k => Map k v -> Set k
blockchainContents :: Blockchain -> Map Epoch [Slot]
blockchainEpochs :: Blockchain -> Set Epoch
fetchUniqueUpdatesFromBlockchain :: Blockchain -> Set InstallerVersion
instance GHC.Show.Show CardanoShellSpec.Epoch
instance GHC.Classes.Ord CardanoShellSpec.Epoch
instance GHC.Classes.Eq CardanoShellSpec.Epoch
instance GHC.Show.Show CardanoShellSpec.BlockHash
instance GHC.Classes.Eq CardanoShellSpec.BlockHash
instance GHC.Show.Show CardanoShellSpec.InstallerHash
instance GHC.Classes.Ord CardanoShellSpec.InstallerHash
instance GHC.Classes.Eq CardanoShellSpec.InstallerHash
instance GHC.Show.Show CardanoShellSpec.InstallerVersion
instance GHC.Classes.Ord CardanoShellSpec.InstallerVersion
instance GHC.Classes.Eq CardanoShellSpec.InstallerVersion
instance GHC.Show.Show CardanoShellSpec.Block
instance GHC.Classes.Eq CardanoShellSpec.Block
instance GHC.Show.Show CardanoShellSpec.Slot
instance GHC.Classes.Eq CardanoShellSpec.Slot
instance GHC.Show.Show CardanoShellSpec.Blockchain
instance GHC.Classes.Eq CardanoShellSpec.Blockchain
instance GHC.Show.Show CardanoShellSpec.LatestInstallerVersion
instance GHC.Classes.Eq CardanoShellSpec.LatestInstallerVersion
instance GHC.Classes.Eq CardanoShellSpec.ClientMessage
instance GHC.Classes.Ord CardanoShellSpec.ClientMessage
instance GHC.Classes.Eq CardanoShellSpec.ServerMessage
instance GHC.Classes.Ord CardanoShellSpec.ServerMessage
