Skip to content

Commit

Permalink
Partially updating ogmios client after breaking changes on v6
Browse files Browse the repository at this point in the history
  • Loading branch information
szg251 committed Sep 21, 2023
1 parent bb80b24 commit 0fd1270
Show file tree
Hide file tree
Showing 12 changed files with 306 additions and 346 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,26 @@ $schema $start
$type
$object
$properties
$property-name "type"
$property-schema jsonWspType
$property-name "version"
$property-schema versionType
$property-name "servicename"
$property-schema serviceType
$property-name "methodname"
$property-name "jsonrpc"
$property-schema jsonRpcType
$property-name "method"
$property-schema methodType
$property-name "result"
$property-schema result
$property-name "reflection"
$property-name "id"
$property-schema mirrorType

$schema jsonWspType
$schema jsonRpcType
$type
$string
$string-values
"jsonwsp/response"

$schema versionType
$type
$string
$string-values
"1.0"

$schema serviceType
$type
$string
$string-values
"ogmios"
"2.0"

$schema methodType
$type
$string
$string-values
"Query"
"queryLedgerState/utxo"

$schema mirrorType
$type
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions src/Internal/Address.purs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ import Data.Maybe (Maybe)
--------------------------------------------------------------------------------
-- Conversion between various address types
--------------------------------------------------------------------------------
-- JsonWsp.Address is a bech32 string, so wrap to Transaction.Types.Bech32
-- | Converts an `JsonWsp.Address` (bech32string) to internal `Address`
-- JsonRpc2.Address is a bech32 string, so wrap to Transaction.Types.Bech32
-- | Converts an `JsonRpc2.Address` (bech32string) to internal `Address`
ogmiosAddressToAddress :: Ogmios.OgmiosAddress -> Maybe Address
ogmiosAddressToAddress = addressFromBech32

-- | Converts an (internal) `Address` to `JsonWsp.Address` (bech32string)
-- | Converts an (internal) `Address` to `JsonRpc2.Address` (bech32string)
addressToOgmiosAddress :: Address -> Ogmios.OgmiosAddress
addressToOgmiosAddress = addressBech32

Expand Down
26 changes: 13 additions & 13 deletions src/Internal/QueryM.purs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ import Ctl.Internal.QueryM.Dispatcher
, newDispatcher
, newPendingRequests
)
import Ctl.Internal.QueryM.JsonWsp as JsonWsp
import Ctl.Internal.QueryM.JsonRpc2 as JsonRpc2
import Ctl.Internal.QueryM.Ogmios
( AdditionalUtxoSet
, DelegationsAndRewardsR
Expand Down Expand Up @@ -301,8 +301,8 @@ getChainTip = ogmiosChainTipToTip <$> mkOgmiosRequest Ogmios.queryChainTipCall
ogmiosChainTipToTip :: Ogmios.ChainTipQR -> Chain.Tip
ogmiosChainTipToTip = case _ of
Ogmios.CtChainOrigin _ -> Chain.TipAtGenesis
Ogmios.CtChainPoint { slot, hash } -> Chain.Tip $ wrap
{ slot, blockHeaderHash: wrap $ unwrap hash }
Ogmios.CtChainPoint { slot, id } -> Chain.Tip $ wrap
{ slot, blockHeaderHash: wrap $ unwrap id }

--------------------------------------------------------------------------------
-- Ogmios Local Tx Submission Protocol
Expand Down Expand Up @@ -806,21 +806,21 @@ mkSubmitTxListenerSet dispatcher pendingRequests =
-- | Builds an Ogmios request action using `QueryM`
mkOgmiosRequest
:: forall (request :: Type) (response :: Type)
. JsonWsp.JsonWspCall request response
. JsonRpc2.JsonRpc2Call request response
-> (OgmiosListeners -> ListenerSet request response)
-> request
-> QueryM response
mkOgmiosRequest jsonWspCall getLs inp = do
mkOgmiosRequest jsonRpc2Call getLs inp = do
listeners' <- asks $ listeners <<< _.ogmiosWs <<< _.runtime
websocket <- asks $ underlyingWebSocket <<< _.ogmiosWs <<< _.runtime
mkRequest listeners' websocket jsonWspCall getLs inp
mkRequest listeners' websocket jsonRpc2Call getLs inp

-- | Builds an Ogmios request action using `Aff`
mkOgmiosRequestAff
:: forall (request :: Type) (response :: Type)
. OgmiosWebSocket
-> Logger
-> JsonWsp.JsonWspCall request response
-> JsonRpc2.JsonRpc2Call request response
-> (OgmiosListeners -> ListenerSet request response)
-> request
-> Aff response
Expand All @@ -832,13 +832,13 @@ mkRequest
:: forall (request :: Type) (response :: Type) (listeners :: Type)
. listeners
-> JsWebSocket
-> JsonWsp.JsonWspCall request response
-> JsonRpc2.JsonRpc2Call request response
-> (listeners -> ListenerSet request response)
-> request
-> QueryM response
mkRequest listeners' ws jsonWspCall getLs inp = do
mkRequest listeners' ws jsonRpc2Call getLs inp = do
logger <- getLogger
liftAff $ mkRequestAff listeners' ws logger jsonWspCall getLs inp
liftAff $ mkRequestAff listeners' ws logger jsonRpc2Call getLs inp

getLogger :: QueryM Logger
getLogger = do
Expand All @@ -851,13 +851,13 @@ mkRequestAff
. listeners
-> JsWebSocket
-> Logger
-> JsonWsp.JsonWspCall request response
-> JsonRpc2.JsonRpc2Call request response
-> (listeners -> ListenerSet request response)
-> request
-> Aff response
mkRequestAff listeners' webSocket logger jsonWspCall getLs input = do
mkRequestAff listeners' webSocket logger jsonRpc2Call getLs input = do
{ body, id } <-
liftEffect $ JsonWsp.buildRequest jsonWspCall input
liftEffect $ JsonRpc2.buildRequest jsonRpc2Call input
let
respLs :: ListenerSet request response
respLs = getLs listeners'
Expand Down
4 changes: 2 additions & 2 deletions src/Internal/QueryM/Dispatcher.purs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ module Ctl.Internal.QueryM.Dispatcher
import Prelude

import Aeson (Aeson, JsonDecodeError, stringifyAeson)
import Ctl.Internal.QueryM.JsonWsp (parseJsonWspResponseId)
import Ctl.Internal.QueryM.JsonRpc2 (parseJsonRpc2ResponseId)
import Ctl.Internal.QueryM.Ogmios (TxHash)
import Ctl.Internal.QueryM.UniqueId (ListenerId)
import Data.Either (Either(Left, Right))
Expand Down Expand Up @@ -64,7 +64,7 @@ newDispatcher = Ref.new Map.empty

mkWebsocketDispatch :: Dispatcher -> WebsocketDispatch
mkWebsocketDispatch dispatcher aeson = do
case parseJsonWspResponseId aeson of
case parseJsonRpc2ResponseId aeson of
Left parseError ->
pure $ Left $ JsonError parseError
Right reflection -> do
Expand Down
124 changes: 124 additions & 0 deletions src/Internal/QueryM/JsonRpc2.purs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
-- | Provides basics types and operations for working with JSON RPC protocol
-- | used by Ogmios
module Ctl.Internal.QueryM.JsonRpc2
( JsonRpc2Request
, JsonRpc2Response
, JsonRpc2Call
, mkCallType
, buildRequest
, parseJsonRpc2Response
, parseJsonRpc2ResponseId
) where

import Prelude

import Aeson
( class DecodeAeson
, class EncodeAeson
, Aeson
, JsonDecodeError(TypeMismatch)
, caseAesonObject
, encodeAeson
, getField
, getFieldOptional
)
import Ctl.Internal.QueryM.UniqueId (ListenerId, uniqueId)
import Data.Either (Either(Left))
import Data.Maybe (Maybe)
import Effect (Effect)
import Foreign.Object (Object)
import Record as Record

-- | Structure of all json rpc2.0 websocket requests
-- described in: https://ogmios.dev/getting-started/basics/
type JsonRpc2Request (a :: Type) =
{ jsonrpc :: String
, method :: String
, params :: a
, id :: ListenerId
}

-- | Convenience helper function for creating `JsonRpc2Request a` objects
mkJsonRpc2Request
:: forall (a :: Type)
. { jsonrpc :: String }
-> { method :: String
, params :: a
}
-> Effect (JsonRpc2Request a)
mkJsonRpc2Request service method = do
id <- uniqueId $ method.method <> "-"
pure
$ Record.merge { id }
$ Record.merge service method

-- | Structure of all json wsp websocket responses
-- described in: https://ogmios.dev/getting-started/basics/
type JsonRpc2Response (a :: Type) =
{ jsonrpc :: String
-- methodname is not always present if `error` is not empty
, method :: Maybe String
, result :: Maybe a
, error :: Maybe Aeson
, id :: ListenerId
}

-- | A wrapper for tying arguments and response types to request building.
newtype JsonRpc2Call :: Type -> Type -> Type
newtype JsonRpc2Call (i :: Type) (o :: Type) = JsonRpc2Call
(i -> Effect { body :: Aeson, id :: String })

-- | Creates a "jsonwsp call" which ties together request input and response output types
-- | along with a way to create a request object.
mkCallType
:: forall (a :: Type) (i :: Type) (o :: Type)
. EncodeAeson (JsonRpc2Request a)
=> { jsonrpc :: String }
-> { method :: String, params :: i -> a }
-> JsonRpc2Call i o
mkCallType service { method, params } = JsonRpc2Call $ \i -> do
req <- mkJsonRpc2Request service { method, params: params i }
pure { body: encodeAeson req, id: req.id }

-- | Create a JsonRpc2 request body and id
buildRequest
:: forall (i :: Type) (o :: Type)
. JsonRpc2Call i o
-> i
-> Effect { body :: Aeson, id :: String }
buildRequest (JsonRpc2Call c) = c

-- | Polymorphic response parser
parseJsonRpc2Response
:: forall (a :: Type)
. DecodeAeson a
=> Aeson
-> Either JsonDecodeError (JsonRpc2Response a)
parseJsonRpc2Response = aesonObject $ \o -> do
jsonrpc <- getField o "jsonrpc"
method <- getFieldOptional o "method"
result <- getFieldOptional o "result"
error <- getFieldOptional o "error"
id <- getField o "id"
pure
{ jsonrpc
, method
, result
, error
, id
}

-- | Parse just ID from the response
parseJsonRpc2ResponseId
:: Aeson
-> Either JsonDecodeError ListenerId
parseJsonRpc2ResponseId =
aesonObject $ flip getField "id"

-- | Helper for assuming we get an object
aesonObject
:: forall (a :: Type)
. (Object Aeson -> Either JsonDecodeError a)
-> Aeson
-> Either JsonDecodeError a
aesonObject = caseAesonObject (Left (TypeMismatch "expected object"))
Loading

0 comments on commit 0fd1270

Please sign in to comment.