zenith/src/Zenith/RPC.hs

85 lines
2.8 KiB
Haskell
Raw Normal View History

2024-07-23 18:46:37 +00:00
{-# LANGUAGE TypeOperators #-}
2024-07-24 21:03:49 +00:00
{-# LANGUAGE DeriveGeneric #-}
2024-07-23 18:46:37 +00:00
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
2024-07-24 21:03:49 +00:00
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
2024-07-23 18:46:37 +00:00
module Zenith.RPC where
2024-08-03 12:01:11 +00:00
import Control.Exception (try)
import Control.Monad.IO.Class (liftIO)
2024-07-23 18:46:37 +00:00
import Data.Aeson
import qualified Data.Text as T
import Servant
2024-08-03 12:01:11 +00:00
import ZcashHaskell.Types (ZebraGetBlockChainInfo(..), ZebraGetInfo(..))
import Zenith.Core (checkBlockChain, checkZebra)
2024-07-24 21:03:49 +00:00
import Zenith.Types
( Config(..)
, RpcCall(..)
2024-08-03 12:01:11 +00:00
, ZenithInfo(..)
2024-07-24 21:03:49 +00:00
, ZenithMethod(..)
, ZenithParams(..)
2024-08-03 12:01:11 +00:00
, ZenithResponse(..)
2024-07-24 21:03:49 +00:00
)
2024-07-23 18:46:37 +00:00
type ZenithRPC
2024-07-24 21:13:13 +00:00
= "status" :> Get '[ JSON] Value :<|> BasicAuth "zenith-realm" Bool :> ReqBody
2024-07-23 18:46:37 +00:00
'[ JSON]
2024-08-03 12:01:11 +00:00
RpcCall :> Post '[ JSON] ZenithResponse
2024-07-23 18:46:37 +00:00
2024-07-24 21:03:49 +00:00
zenithServer :: Config -> Server ZenithRPC
zenithServer config = getinfo :<|> handleRPC
2024-07-23 18:46:37 +00:00
where
getinfo :: Handler Value
getinfo =
return $
object
[ "version" .= ("0.7.0.0-beta" :: String)
, "network" .= ("testnet" :: String)
]
2024-08-03 12:01:11 +00:00
handleRPC :: Bool -> RpcCall -> Handler ZenithResponse
2024-07-24 21:13:13 +00:00
handleRPC isAuth req =
2024-07-23 18:46:37 +00:00
case method req of
2024-07-24 21:03:49 +00:00
UnknownMethod ->
2024-08-03 12:01:11 +00:00
return $ ErrorResponse (callId req) (-32601) "Method not found"
2024-07-23 18:46:37 +00:00
GetInfo ->
case parameters req of
2024-08-03 12:01:11 +00:00
BlankParams -> do
let host = c_zebraHost config
let port = c_zebraPort config
zInfo <-
liftIO $ try $ checkZebra host port :: Handler
(Either IOError ZebraGetInfo)
case zInfo of
Left e ->
return $
ErrorResponse (callId req) (-32000) "Zebra not available"
Right zI -> do
bInfo <-
liftIO $ try $ checkBlockChain host port :: Handler
(Either IOError ZebraGetBlockChainInfo)
case bInfo of
Left e1 ->
return $
ErrorResponse (callId req) (-32000) "Zebra not available"
Right bI ->
return $
InfoResponse
(callId req)
(ZenithInfo "0.7.0.0-beta" (zgb_net bI) (zgi_build zI))
2024-07-23 18:46:37 +00:00
_anyOtherParams ->
2024-08-03 12:01:11 +00:00
return $ ErrorResponse (callId req) (-32602) "Invalid params"
2024-07-24 21:03:49 +00:00
authenticate :: Config -> BasicAuthCheck Bool
authenticate config = BasicAuthCheck check
where
check (BasicAuthData username password) =
if username == c_zenithUser config && password == c_zenithPwd config
then return $ Authorized True
else return Unauthorized