As it currently stands, we have MonadBlockchain defined as:
class (Monad m) => MonadBlockchain era m | m -> era where
sendTx
utxoByTxIn
queryProtocolParameters :: m (C.LedgerProtocolParameters era)
queryStakeAddresses
queryStakePools :: m (Set C.PoolId)
querySystemStart :: m SystemStart
queryEraHistory :: m C.EraHistory
querySlotNo :: m (C.SlotNo, SlotLength, UTCTime)
queryNetworkId :: m C.NetworkId
My proposal is to split each of those functions into multiple typeclasses.
First off, we have 2 types of functions: control functions, and query functions. Control functions typically alter the state of the node (such as sendTx). Then, query functions, like the name suggests, query data from some source. That source could be the local node, or Blockfrost, CardanoDbSync, or any other chain-indexer.
So the next question is: why should be split each query function into it's separate typeclass? The reason is because not all data sources can resolve each of those queries. The local node can resolve each of those queries through the mini-protocols, but so can CardanoDbSync. Then, there are some other datasources (like Kupo) which can resolve a subset of those queries. And as user, I don't necessarily need all those queries. Having the ability to decide which datasource should resolve each of those queries is a plus.
So, my proposal is to define the following typeclasses:
class MonadSubmitTx era m | m -> era where
sendTx :: C.Tx era -> m ()
class MonadQueryUtxoByTxIn era m | m -> era where
utxoByTxIn :: Set C.TxIn -> C.UTxO
class MonadQueryProtocolParameters era m | m -> era were
queryProtocolParameters :: m (C.LedgerProtocolParameters)
etc.
Of course, if we can try to group query functions which should always be queryable by some datasource. (such as config related queries like networkId, systemStart, etc.)
As it currently stands, we have
MonadBlockchaindefined as:My proposal is to split each of those functions into multiple typeclasses.
First off, we have 2 types of functions: control functions, and query functions. Control functions typically alter the state of the node (such as
sendTx). Then, query functions, like the name suggests, query data from some source. That source could be the local node, or Blockfrost, CardanoDbSync, or any other chain-indexer.So the next question is: why should be split each query function into it's separate typeclass? The reason is because not all data sources can resolve each of those queries. The local node can resolve each of those queries through the mini-protocols, but so can CardanoDbSync. Then, there are some other datasources (like Kupo) which can resolve a subset of those queries. And as user, I don't necessarily need all those queries. Having the ability to decide which datasource should resolve each of those queries is a plus.
So, my proposal is to define the following typeclasses:
Of course, if we can try to group query functions which should always be queryable by some datasource. (such as config related queries like
networkId,systemStart, etc.)