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
|