-- SPDX-FileCopyrightText: 2021 Oxhead Alpha
-- SPDX-License-Identifier: LicenseRef-MIT-OA

-- | Implementation of full-featured Morley client.

module Morley.Client.Full
  ( MorleyClientEnv(..)
  , MorleyClientConfig (..)
  , MorleyClientM
  , runMorleyClientM
  , mkMorleyClientEnv
  , mkLogAction
  -- * Lens
  , mceTezosClientL
  , mceLogActionL
  , mceSecretKeyL
  , mceClientEnvL
  , mccEndpointUrlL
  , mccTezosClientPathL
  , mccMbTezosClientDataDirL
  , mccVerbosityL
  , mccSecretKeyL
  ) where

import Colog (HasLog(..), Message)
import Network.HTTP.Types (Status(..))
import Servant.Client (ClientEnv)
import Servant.Client.Core (Request, Response, RunClient(..))
import System.Environment (lookupEnv)
import UnliftIO (MonadUnliftIO)

import Morley.Client.App
import Morley.Client.Init
import Morley.Client.Logging (ClientLogAction)
import Morley.Client.RPC.Class
import Morley.Client.RPC.HttpClient
import Morley.Client.TezosClient.Class
import Morley.Client.TezosClient.Impl (getTezosClientConfig)
import Morley.Client.TezosClient.Impl qualified as TezosClient
import Morley.Client.TezosClient.Types
import Morley.Client.Types
import Morley.Tezos.Crypto (Signature(..))
import Morley.Tezos.Crypto.Ed25519 qualified as Ed25519
import Morley.Util.Lens (makeLensesWith, postfixLFields)


-- | Runtime environment for morley client.
data MorleyClientEnv = MorleyClientEnv
  { MorleyClientEnv -> TezosClientEnv
mceTezosClient :: TezosClientEnv
  -- ^ Environment for @octez-client@.
  , MorleyClientEnv -> ClientLogAction MorleyClientM
mceLogAction :: ClientLogAction MorleyClientM
  -- ^ Action used to log messages.
  , MorleyClientEnv -> Maybe SecretKey
mceSecretKey :: Maybe Ed25519.SecretKey
  -- ^ Pass if you want to sign operations manually or leave it
  -- to @octez-client@.
  , MorleyClientEnv -> ClientEnv
mceClientEnv :: ClientEnv
  -- ^ Environment necessary to make HTTP calls.
  }

newtype MorleyClientM a = MorleyClientM
  { forall a. MorleyClientM a -> ReaderT MorleyClientEnv IO a
unMorleyClientM :: ReaderT MorleyClientEnv IO a }
  deriving newtype
    ( (forall a b. (a -> b) -> MorleyClientM a -> MorleyClientM b)
-> (forall a b. a -> MorleyClientM b -> MorleyClientM a)
-> Functor MorleyClientM
forall a b. a -> MorleyClientM b -> MorleyClientM a
forall a b. (a -> b) -> MorleyClientM a -> MorleyClientM b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> MorleyClientM b -> MorleyClientM a
$c<$ :: forall a b. a -> MorleyClientM b -> MorleyClientM a
fmap :: forall a b. (a -> b) -> MorleyClientM a -> MorleyClientM b
$cfmap :: forall a b. (a -> b) -> MorleyClientM a -> MorleyClientM b
Functor, Functor MorleyClientM
Functor MorleyClientM
-> (forall a. a -> MorleyClientM a)
-> (forall a b.
    MorleyClientM (a -> b) -> MorleyClientM a -> MorleyClientM b)
-> (forall a b c.
    (a -> b -> c)
    -> MorleyClientM a -> MorleyClientM b -> MorleyClientM c)
-> (forall a b.
    MorleyClientM a -> MorleyClientM b -> MorleyClientM b)
-> (forall a b.
    MorleyClientM a -> MorleyClientM b -> MorleyClientM a)
-> Applicative MorleyClientM
forall a. a -> MorleyClientM a
forall a b. MorleyClientM a -> MorleyClientM b -> MorleyClientM a
forall a b. MorleyClientM a -> MorleyClientM b -> MorleyClientM b
forall a b.
MorleyClientM (a -> b) -> MorleyClientM a -> MorleyClientM b
forall a b c.
(a -> b -> c)
-> MorleyClientM a -> MorleyClientM b -> MorleyClientM c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: forall a b. MorleyClientM a -> MorleyClientM b -> MorleyClientM a
$c<* :: forall a b. MorleyClientM a -> MorleyClientM b -> MorleyClientM a
*> :: forall a b. MorleyClientM a -> MorleyClientM b -> MorleyClientM b
$c*> :: forall a b. MorleyClientM a -> MorleyClientM b -> MorleyClientM b
liftA2 :: forall a b c.
(a -> b -> c)
-> MorleyClientM a -> MorleyClientM b -> MorleyClientM c
$cliftA2 :: forall a b c.
(a -> b -> c)
-> MorleyClientM a -> MorleyClientM b -> MorleyClientM c
<*> :: forall a b.
MorleyClientM (a -> b) -> MorleyClientM a -> MorleyClientM b
$c<*> :: forall a b.
MorleyClientM (a -> b) -> MorleyClientM a -> MorleyClientM b
pure :: forall a. a -> MorleyClientM a
$cpure :: forall a. a -> MorleyClientM a
Applicative, Applicative MorleyClientM
Applicative MorleyClientM
-> (forall a b.
    MorleyClientM a -> (a -> MorleyClientM b) -> MorleyClientM b)
-> (forall a b.
    MorleyClientM a -> MorleyClientM b -> MorleyClientM b)
-> (forall a. a -> MorleyClientM a)
-> Monad MorleyClientM
forall a. a -> MorleyClientM a
forall a b. MorleyClientM a -> MorleyClientM b -> MorleyClientM b
forall a b.
MorleyClientM a -> (a -> MorleyClientM b) -> MorleyClientM b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: forall a. a -> MorleyClientM a
$creturn :: forall a. a -> MorleyClientM a
>> :: forall a b. MorleyClientM a -> MorleyClientM b -> MorleyClientM b
$c>> :: forall a b. MorleyClientM a -> MorleyClientM b -> MorleyClientM b
>>= :: forall a b.
MorleyClientM a -> (a -> MorleyClientM b) -> MorleyClientM b
$c>>= :: forall a b.
MorleyClientM a -> (a -> MorleyClientM b) -> MorleyClientM b
Monad, MonadReader MorleyClientEnv
    , Monad MorleyClientM
Monad MorleyClientM
-> (forall a. IO a -> MorleyClientM a) -> MonadIO MorleyClientM
forall a. IO a -> MorleyClientM a
forall (m :: * -> *).
Monad m -> (forall a. IO a -> m a) -> MonadIO m
liftIO :: forall a. IO a -> MorleyClientM a
$cliftIO :: forall a. IO a -> MorleyClientM a
MonadIO, Monad MorleyClientM
Monad MorleyClientM
-> (forall e a. Exception e => e -> MorleyClientM a)
-> MonadThrow MorleyClientM
forall e a. Exception e => e -> MorleyClientM a
forall (m :: * -> *).
Monad m -> (forall e a. Exception e => e -> m a) -> MonadThrow m
throwM :: forall e a. Exception e => e -> MorleyClientM a
$cthrowM :: forall e a. Exception e => e -> MorleyClientM a
MonadThrow, MonadThrow MorleyClientM
MonadThrow MorleyClientM
-> (forall e a.
    Exception e =>
    MorleyClientM a -> (e -> MorleyClientM a) -> MorleyClientM a)
-> MonadCatch MorleyClientM
forall e a.
Exception e =>
MorleyClientM a -> (e -> MorleyClientM a) -> MorleyClientM a
forall (m :: * -> *).
MonadThrow m
-> (forall e a. Exception e => m a -> (e -> m a) -> m a)
-> MonadCatch m
catch :: forall e a.
Exception e =>
MorleyClientM a -> (e -> MorleyClientM a) -> MorleyClientM a
$ccatch :: forall e a.
Exception e =>
MorleyClientM a -> (e -> MorleyClientM a) -> MorleyClientM a
MonadCatch, MonadCatch MorleyClientM
MonadCatch MorleyClientM
-> (forall b.
    ((forall a. MorleyClientM a -> MorleyClientM a) -> MorleyClientM b)
    -> MorleyClientM b)
-> (forall b.
    ((forall a. MorleyClientM a -> MorleyClientM a) -> MorleyClientM b)
    -> MorleyClientM b)
-> (forall a b c.
    MorleyClientM a
    -> (a -> ExitCase b -> MorleyClientM c)
    -> (a -> MorleyClientM b)
    -> MorleyClientM (b, c))
-> MonadMask MorleyClientM
forall b.
((forall a. MorleyClientM a -> MorleyClientM a) -> MorleyClientM b)
-> MorleyClientM b
forall a b c.
MorleyClientM a
-> (a -> ExitCase b -> MorleyClientM c)
-> (a -> MorleyClientM b)
-> MorleyClientM (b, c)
forall (m :: * -> *).
MonadCatch m
-> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
-> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
-> (forall a b c.
    m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c))
-> MonadMask m
generalBracket :: forall a b c.
MorleyClientM a
-> (a -> ExitCase b -> MorleyClientM c)
-> (a -> MorleyClientM b)
-> MorleyClientM (b, c)
$cgeneralBracket :: forall a b c.
MorleyClientM a
-> (a -> ExitCase b -> MorleyClientM c)
-> (a -> MorleyClientM b)
-> MorleyClientM (b, c)
uninterruptibleMask :: forall b.
((forall a. MorleyClientM a -> MorleyClientM a) -> MorleyClientM b)
-> MorleyClientM b
$cuninterruptibleMask :: forall b.
((forall a. MorleyClientM a -> MorleyClientM a) -> MorleyClientM b)
-> MorleyClientM b
mask :: forall b.
((forall a. MorleyClientM a -> MorleyClientM a) -> MorleyClientM b)
-> MorleyClientM b
$cmask :: forall b.
((forall a. MorleyClientM a -> MorleyClientM a) -> MorleyClientM b)
-> MorleyClientM b
MonadMask, MonadIO MorleyClientM
MonadIO MorleyClientM
-> (forall b.
    ((forall a. MorleyClientM a -> IO a) -> IO b) -> MorleyClientM b)
-> MonadUnliftIO MorleyClientM
forall b.
((forall a. MorleyClientM a -> IO a) -> IO b) -> MorleyClientM b
forall (m :: * -> *).
MonadIO m
-> (forall b. ((forall a. m a -> IO a) -> IO b) -> m b)
-> MonadUnliftIO m
withRunInIO :: forall b.
((forall a. MorleyClientM a -> IO a) -> IO b) -> MorleyClientM b
$cwithRunInIO :: forall b.
((forall a. MorleyClientM a -> IO a) -> IO b) -> MorleyClientM b
MonadUnliftIO
    )

-- | Run 'MorleyClientM' action within given t'MorleyClientEnv'. Retry action
-- in case of invalid counter error.
runMorleyClientM :: MorleyClientEnv -> MorleyClientM a -> IO a
runMorleyClientM :: forall a. MorleyClientEnv -> MorleyClientM a -> IO a
runMorleyClientM MorleyClientEnv
env MorleyClientM a
client = ReaderT MorleyClientEnv IO a -> MorleyClientEnv -> IO a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (MorleyClientM a -> ReaderT MorleyClientEnv IO a
forall a. MorleyClientM a -> ReaderT MorleyClientEnv IO a
unMorleyClientM MorleyClientM a
client) MorleyClientEnv
env

makeLensesWith postfixLFields ''MorleyClientEnv

instance HasTezosClientEnv MorleyClientEnv where
  tezosClientEnvL :: Lens' MorleyClientEnv TezosClientEnv
tezosClientEnvL = (TezosClientEnv -> f TezosClientEnv)
-> MorleyClientEnv -> f MorleyClientEnv
Lens' MorleyClientEnv TezosClientEnv
mceTezosClientL

instance HasLog MorleyClientEnv Message MorleyClientM where
  getLogAction :: MorleyClientEnv -> ClientLogAction MorleyClientM
getLogAction = MorleyClientEnv -> ClientLogAction MorleyClientM
mceLogAction
  setLogAction :: ClientLogAction MorleyClientM -> MorleyClientEnv -> MorleyClientEnv
setLogAction ClientLogAction MorleyClientM
action MorleyClientEnv
mce = MorleyClientEnv
mce { mceLogAction :: ClientLogAction MorleyClientM
mceLogAction = ClientLogAction MorleyClientM
action }

instance HasTezosClient MorleyClientM where
  signBytes :: ImplicitAddressWithAlias
-> Maybe ScrubbedBytes -> ByteString -> MorleyClientM Signature
signBytes (AddressWithAlias KindedAddress 'AddressKindImplicit
_ ImplicitAlias
senderAlias) Maybe ScrubbedBytes
mbPassword ByteString
opHash = MorleyClientM Signature -> MorleyClientM Signature
forall (m :: * -> *) a.
(MonadUnliftIO m, MonadThrow m) =>
m a -> m a
retryOnceOnTimeout (MorleyClientM Signature -> MorleyClientM Signature)
-> MorleyClientM Signature -> MorleyClientM Signature
forall a b. (a -> b) -> a -> b
$ do
    MorleyClientEnv
env <- MorleyClientM MorleyClientEnv
forall r (m :: * -> *). MonadReader r m => m r
ask
    case MorleyClientEnv -> Maybe SecretKey
mceSecretKey MorleyClientEnv
env of
      Just SecretKey
sk -> Signature -> MorleyClientM Signature
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Signature -> MorleyClientM Signature)
-> (Signature -> Signature) -> Signature -> MorleyClientM Signature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Signature -> Signature
SignatureEd25519 (Signature -> MorleyClientM Signature)
-> Signature -> MorleyClientM Signature
forall a b. (a -> b) -> a -> b
$ SecretKey -> ByteString -> Signature
Ed25519.sign SecretKey
sk ByteString
opHash
      Maybe SecretKey
Nothing -> ImplicitAlias
-> Maybe ScrubbedBytes -> ByteString -> MorleyClientM Signature
forall env (m :: * -> *).
(WithClientLog env m, HasTezosClientEnv env, MonadIO m,
 MonadCatch m) =>
ImplicitAlias -> Maybe ScrubbedBytes -> ByteString -> m Signature
TezosClient.signBytes ImplicitAlias
senderAlias Maybe ScrubbedBytes
mbPassword ByteString
opHash
  rememberContract :: AliasBehavior
-> ContractAddress -> ContractAlias -> MorleyClientM ()
rememberContract = MorleyClientM () -> MorleyClientM ()
forall (m :: * -> *) a.
(MonadUnliftIO m, MonadThrow m) =>
m a -> m a
failOnTimeout (MorleyClientM () -> MorleyClientM ())
-> (AliasBehavior
    -> ContractAddress -> ContractAlias -> MorleyClientM ())
-> AliasBehavior
-> ContractAddress
-> ContractAlias
-> MorleyClientM ()
forall a b c. SuperComposition a b c => a -> b -> c
... AliasBehavior
-> ContractAddress -> ContractAlias -> MorleyClientM ()
forall env (m :: * -> *).
(WithClientLog env m, HasTezosClientEnv env, MonadIO m,
 MonadCatch m) =>
AliasBehavior -> ContractAddress -> ContractAlias -> m ()
TezosClient.rememberContract
  getAliasesAndAddresses :: MorleyClientM [(Text, Text)]
getAliasesAndAddresses = MorleyClientM [(Text, Text)] -> MorleyClientM [(Text, Text)]
forall (m :: * -> *) a.
(MonadUnliftIO m, MonadThrow m) =>
m a -> m a
retryOnceOnTimeout (MorleyClientM [(Text, Text)] -> MorleyClientM [(Text, Text)])
-> MorleyClientM [(Text, Text)] -> MorleyClientM [(Text, Text)]
forall a b c. SuperComposition a b c => a -> b -> c
... MorleyClientM [(Text, Text)]
forall (m :: * -> *) env.
(WithClientLog env m, HasTezosClientEnv env, MonadIO m,
 MonadCatch m) =>
m [(Text, Text)]
TezosClient.getAliasesAndAddresses
  genKey :: ImplicitAlias -> MorleyClientM ImplicitAddressWithAlias
genKey ImplicitAlias
alias = (KindedAddress 'AddressKindImplicit
 -> ImplicitAlias -> ImplicitAddressWithAlias)
-> ImplicitAlias
-> KindedAddress 'AddressKindImplicit
-> ImplicitAddressWithAlias
forall a b c. (a -> b -> c) -> b -> a -> c
flip KindedAddress 'AddressKindImplicit
-> ImplicitAlias -> ImplicitAddressWithAlias
forall (kind :: AddressKind).
KindedAddress kind -> Alias kind -> AddressWithAlias kind
AddressWithAlias ImplicitAlias
alias (KindedAddress 'AddressKindImplicit -> ImplicitAddressWithAlias)
-> MorleyClientM (KindedAddress 'AddressKindImplicit)
-> MorleyClientM ImplicitAddressWithAlias
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ImplicitAlias -> MorleyClientM (KindedAddress 'AddressKindImplicit)
forall (m :: * -> *) env.
(MonadThrow m, MonadCatch m, WithClientLog env m,
 HasTezosClientEnv env, MonadIO m, HasTezosClient m) =>
ImplicitAlias -> m (KindedAddress 'AddressKindImplicit)
TezosClient.genKey ImplicitAlias
alias
  genFreshKey :: ImplicitAlias -> MorleyClientM ImplicitAddressWithAlias
genFreshKey ImplicitAlias
alias = (KindedAddress 'AddressKindImplicit
 -> ImplicitAlias -> ImplicitAddressWithAlias)
-> ImplicitAlias
-> KindedAddress 'AddressKindImplicit
-> ImplicitAddressWithAlias
forall a b c. (a -> b -> c) -> b -> a -> c
flip KindedAddress 'AddressKindImplicit
-> ImplicitAlias -> ImplicitAddressWithAlias
forall (kind :: AddressKind).
KindedAddress kind -> Alias kind -> AddressWithAlias kind
AddressWithAlias ImplicitAlias
alias (KindedAddress 'AddressKindImplicit -> ImplicitAddressWithAlias)
-> MorleyClientM (KindedAddress 'AddressKindImplicit)
-> MorleyClientM ImplicitAddressWithAlias
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ImplicitAlias -> MorleyClientM (KindedAddress 'AddressKindImplicit)
forall (m :: * -> *) env.
(MonadThrow m, MonadCatch m, WithClientLog env m,
 HasTezosClientEnv env, MonadIO m, HasTezosClient m) =>
ImplicitAlias -> m (KindedAddress 'AddressKindImplicit)
TezosClient.genFreshKey ImplicitAlias
alias
  getKeyPassword :: ImplicitAddressWithAlias -> MorleyClientM (Maybe ScrubbedBytes)
getKeyPassword (AddressWithAlias KindedAddress 'AddressKindImplicit
_ ImplicitAlias
alias) = MorleyClientM (Maybe ScrubbedBytes)
-> MorleyClientM (Maybe ScrubbedBytes)
forall (m :: * -> *) a.
(MonadUnliftIO m, MonadThrow m) =>
m a -> m a
retryOnceOnTimeout (MorleyClientM (Maybe ScrubbedBytes)
 -> MorleyClientM (Maybe ScrubbedBytes))
-> MorleyClientM (Maybe ScrubbedBytes)
-> MorleyClientM (Maybe ScrubbedBytes)
forall a b. (a -> b) -> a -> b
$ ImplicitAlias -> MorleyClientM (Maybe ScrubbedBytes)
forall env (m :: * -> *).
(WithClientLog env m, HasTezosClientEnv env, MonadIO m,
 MonadMask m) =>
ImplicitAlias -> m (Maybe ScrubbedBytes)
TezosClient.getKeyPassword ImplicitAlias
alias
  getPublicKey :: ImplicitAddressWithAlias -> MorleyClientM PublicKey
getPublicKey (AddressWithAlias KindedAddress 'AddressKindImplicit
_ ImplicitAlias
alias) = ImplicitAlias -> MorleyClientM PublicKey
forall env (m :: * -> *).
(WithClientLog env m, HasTezosClientEnv env, MonadIO m,
 MonadCatch m) =>
ImplicitAlias -> m PublicKey
TezosClient.getPublicKey ImplicitAlias
alias

instance RunClient MorleyClientM where
  runRequestAcceptStatus :: Maybe [Status] -> Request -> MorleyClientM Response
  runRequestAcceptStatus :: Maybe [Status] -> Request -> MorleyClientM Response
runRequestAcceptStatus Maybe [Status]
statuses Request
req = do
    ClientEnv
env <- MorleyClientEnv -> ClientEnv
mceClientEnv (MorleyClientEnv -> ClientEnv)
-> MorleyClientM MorleyClientEnv -> MorleyClientM ClientEnv
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MorleyClientM MorleyClientEnv
forall r (m :: * -> *). MonadReader r m => m r
ask
    ClientEnv -> Maybe [Status] -> Request -> MorleyClientM Response
forall env (m :: * -> *).
(WithClientLog env m, MonadIO m, MonadThrow m) =>
ClientEnv -> Maybe [Status] -> Request -> m Response
runRequestAcceptStatusImpl ClientEnv
env Maybe [Status]
statuses Request
req
  throwClientError :: forall a. ClientError -> MorleyClientM a
throwClientError = ClientError -> MorleyClientM a
forall (m :: * -> *) a. MonadThrow m => ClientError -> m a
throwClientErrorImpl

instance HasTezosRpc MorleyClientM where
  getBlockHash :: BlockId -> MorleyClientM BlockHash
getBlockHash = BlockId -> MorleyClientM BlockHash
forall (m :: * -> *).
(RunClient m, MonadUnliftIO m, MonadCatch m) =>
BlockId -> m BlockHash
getBlockHashImpl
  getCounterAtBlock :: BlockId
-> KindedAddress 'AddressKindImplicit -> MorleyClientM TezosInt64
getCounterAtBlock = BlockId
-> KindedAddress 'AddressKindImplicit -> MorleyClientM TezosInt64
forall (m :: * -> *).
(RunClient m, MonadUnliftIO m, MonadCatch m) =>
BlockId -> KindedAddress 'AddressKindImplicit -> m TezosInt64
getCounterImpl
  getBlockHeader :: BlockId -> MorleyClientM BlockHeader
getBlockHeader = BlockId -> MorleyClientM BlockHeader
forall (m :: * -> *).
(RunClient m, MonadUnliftIO m, MonadCatch m) =>
BlockId -> m BlockHeader
getBlockHeaderImpl
  getBlockConstants :: BlockId -> MorleyClientM BlockConstants
getBlockConstants = BlockId -> MorleyClientM BlockConstants
forall (m :: * -> *).
(RunClient m, MonadUnliftIO m, MonadCatch m) =>
BlockId -> m BlockConstants
getBlockConstantsImpl
  getBlockOperations :: BlockId -> MorleyClientM [[BlockOperation]]
getBlockOperations = BlockId -> MorleyClientM [[BlockOperation]]
forall (m :: * -> *).
(RunClient m, MonadUnliftIO m, MonadCatch m) =>
BlockId -> m [[BlockOperation]]
getBlockOperationsImpl
  getScriptSizeAtBlock :: BlockId -> CalcSize -> MorleyClientM ScriptSize
getScriptSizeAtBlock = BlockId -> CalcSize -> MorleyClientM ScriptSize
forall (m :: * -> *).
(RunClient m, MonadUnliftIO m, MonadCatch m) =>
BlockId -> CalcSize -> m ScriptSize
getScriptSizeAtBlockImpl
  getBlockOperationHashes :: BlockId -> MorleyClientM [[OperationHash]]
getBlockOperationHashes = BlockId -> MorleyClientM [[OperationHash]]
forall (m :: * -> *).
(RunClient m, MonadUnliftIO m, MonadCatch m) =>
BlockId -> m [[OperationHash]]
getBlockOperationHashesImpl
  getProtocolParametersAtBlock :: BlockId -> MorleyClientM ProtocolParameters
getProtocolParametersAtBlock = BlockId -> MorleyClientM ProtocolParameters
forall (m :: * -> *).
(RunClient m, MonadUnliftIO m, MonadCatch m) =>
BlockId -> m ProtocolParameters
getProtocolParametersImpl
  runOperationAtBlock :: BlockId -> RunOperation -> MorleyClientM RunOperationResult
runOperationAtBlock = BlockId -> RunOperation -> MorleyClientM RunOperationResult
forall (m :: * -> *).
(RunClient m, MonadUnliftIO m, MonadCatch m) =>
BlockId -> RunOperation -> m RunOperationResult
runOperationImpl
  preApplyOperationsAtBlock :: BlockId
-> [PreApplyOperation] -> MorleyClientM [RunOperationResult]
preApplyOperationsAtBlock = BlockId
-> [PreApplyOperation] -> MorleyClientM [RunOperationResult]
forall (m :: * -> *).
(RunClient m, MonadUnliftIO m, MonadCatch m) =>
BlockId -> [PreApplyOperation] -> m [RunOperationResult]
preApplyOperationsImpl
  forgeOperationAtBlock :: BlockId -> ForgeOperation -> MorleyClientM HexJSONByteString
forgeOperationAtBlock = BlockId -> ForgeOperation -> MorleyClientM HexJSONByteString
forall (m :: * -> *).
(RunClient m, MonadUnliftIO m, MonadCatch m) =>
BlockId -> ForgeOperation -> m HexJSONByteString
forgeOperationImpl
  injectOperation :: HexJSONByteString -> MorleyClientM OperationHash
injectOperation = HexJSONByteString -> MorleyClientM OperationHash
forall (m :: * -> *).
(RunClient m, MonadUnliftIO m, MonadCatch m) =>
HexJSONByteString -> m OperationHash
injectOperationImpl
  getContractScriptAtBlock :: BlockId -> ContractAddress -> MorleyClientM OriginationScript
getContractScriptAtBlock = BlockId -> ContractAddress -> MorleyClientM OriginationScript
forall (m :: * -> *).
(RunClient m, MonadUnliftIO m, MonadCatch m) =>
BlockId -> ContractAddress -> m OriginationScript
getContractScriptImpl
  getContractStorageAtBlock :: BlockId -> ContractAddress -> MorleyClientM Expression
getContractStorageAtBlock = BlockId -> ContractAddress -> MorleyClientM Expression
forall (m :: * -> *).
(RunClient m, MonadUnliftIO m, MonadCatch m) =>
BlockId -> ContractAddress -> m Expression
getContractStorageAtBlockImpl
  getContractBigMapAtBlock :: BlockId
-> ContractAddress -> GetBigMap -> MorleyClientM GetBigMapResult
getContractBigMapAtBlock = BlockId
-> ContractAddress -> GetBigMap -> MorleyClientM GetBigMapResult
forall (m :: * -> *).
(RunClient m, MonadUnliftIO m, MonadCatch m) =>
BlockId -> ContractAddress -> GetBigMap -> m GetBigMapResult
getContractBigMapImpl
  getBigMapValueAtBlock :: BlockId -> Natural -> Text -> MorleyClientM Expression
getBigMapValueAtBlock = BlockId -> Natural -> Text -> MorleyClientM Expression
forall (m :: * -> *).
(RunClient m, MonadUnliftIO m, MonadCatch m) =>
BlockId -> Natural -> Text -> m Expression
getBigMapValueAtBlockImpl
  getBigMapValuesAtBlock :: BlockId
-> Natural
-> Maybe Natural
-> Maybe Natural
-> MorleyClientM Expression
getBigMapValuesAtBlock = BlockId
-> Natural
-> Maybe Natural
-> Maybe Natural
-> MorleyClientM Expression
forall (m :: * -> *).
(RunClient m, MonadUnliftIO m, MonadCatch m) =>
BlockId
-> Natural -> Maybe Natural -> Maybe Natural -> m Expression
getBigMapValuesAtBlockImpl
  getBalanceAtBlock :: BlockId -> Address -> MorleyClientM Mutez
getBalanceAtBlock = BlockId -> Address -> MorleyClientM Mutez
forall (m :: * -> *).
(RunClient m, MonadUnliftIO m, MonadCatch m) =>
BlockId -> Address -> m Mutez
getBalanceImpl
  getDelegateAtBlock :: BlockId -> L1Address -> MorleyClientM (Maybe KeyHash)
getDelegateAtBlock = BlockId -> L1Address -> MorleyClientM (Maybe KeyHash)
forall (m :: * -> *).
(RunClient m, MonadUnliftIO m, MonadCatch m) =>
BlockId -> L1Address -> m (Maybe KeyHash)
getDelegateImpl
  runCodeAtBlock :: BlockId -> RunCode -> MorleyClientM RunCodeResult
runCodeAtBlock = BlockId -> RunCode -> MorleyClientM RunCodeResult
forall (m :: * -> *).
(RunClient m, MonadCatch m) =>
BlockId -> RunCode -> m RunCodeResult
runCodeImpl
  getChainId :: MorleyClientM ChainId
getChainId = MorleyClientM ChainId
forall (m :: * -> *). (RunClient m, MonadCatch m) => m ChainId
getChainIdImpl
  getManagerKeyAtBlock :: BlockId
-> KindedAddress 'AddressKindImplicit
-> MorleyClientM (Maybe PublicKey)
getManagerKeyAtBlock = BlockId
-> KindedAddress 'AddressKindImplicit
-> MorleyClientM (Maybe PublicKey)
forall (m :: * -> *).
(RunClient m, MonadUnliftIO m, MonadCatch m) =>
BlockId
-> KindedAddress 'AddressKindImplicit -> m (Maybe PublicKey)
getManagerKeyImpl
  waitForOperation :: MorleyClientM OperationHash -> MorleyClientM OperationHash
waitForOperation = ((MorleyClientEnv -> ClientEnv) -> MorleyClientM ClientEnv
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks MorleyClientEnv -> ClientEnv
mceClientEnv MorleyClientM ClientEnv
-> (ClientEnv -> MorleyClientM OperationHash)
-> MorleyClientM OperationHash
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=) ((ClientEnv -> MorleyClientM OperationHash)
 -> MorleyClientM OperationHash)
-> (MorleyClientM OperationHash
    -> ClientEnv -> MorleyClientM OperationHash)
-> MorleyClientM OperationHash
-> MorleyClientM OperationHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MorleyClientM OperationHash
-> ClientEnv -> MorleyClientM OperationHash
forall (m :: * -> *).
(MonadUnliftIO m, HasTezosRpc m) =>
m OperationHash -> ClientEnv -> m OperationHash
waitForOperationImpl
  getTicketBalanceAtBlock :: BlockId -> Address -> GetTicketBalance -> MorleyClientM Natural
getTicketBalanceAtBlock = BlockId -> Address -> GetTicketBalance -> MorleyClientM Natural
forall (m :: * -> *).
(RunClient m, MonadUnliftIO m, MonadCatch m) =>
BlockId -> Address -> GetTicketBalance -> m Natural
getTicketBalanceAtBlockImpl
  getAllTicketBalancesAtBlock :: BlockId
-> ContractAddress -> MorleyClientM [GetAllTicketBalancesResponse]
getAllTicketBalancesAtBlock = BlockId
-> ContractAddress -> MorleyClientM [GetAllTicketBalancesResponse]
forall (m :: * -> *).
(RunClient m, MonadUnliftIO m, MonadCatch m) =>
BlockId -> ContractAddress -> m [GetAllTicketBalancesResponse]
getAllTicketBalancesAtBlockImpl


-- | Construct 'MorleyClientEnv'.
--
-- * @octez-client@ path is taken from 'MorleyClientConfig', but can be
-- overridden using @MORLEY_TEZOS_CLIENT@ environment variable.
-- * Node data is taken from @octez-client@ config and can be overridden
-- by 'MorleyClientConfig'.
-- * The rest is taken from 'MorleyClientConfig' as is.
mkMorleyClientEnv :: MorleyClientConfig -> IO MorleyClientEnv
mkMorleyClientEnv :: MorleyClientConfig -> IO MorleyClientEnv
mkMorleyClientEnv MorleyClientConfig{FilePath
Maybe FilePath
Maybe BaseUrl
Maybe SecretKey
Word
mccSecretKey :: MorleyClientConfig -> Maybe SecretKey
mccVerbosity :: MorleyClientConfig -> Word
mccMbTezosClientDataDir :: MorleyClientConfig -> Maybe FilePath
mccTezosClientPath :: MorleyClientConfig -> FilePath
mccEndpointUrl :: MorleyClientConfig -> Maybe BaseUrl
mccSecretKey :: Maybe SecretKey
mccVerbosity :: Word
mccMbTezosClientDataDir :: Maybe FilePath
mccTezosClientPath :: FilePath
mccEndpointUrl :: Maybe BaseUrl
..} = do
  Maybe FilePath
envTezosClientPath <- FilePath -> IO (Maybe FilePath)
lookupEnv FilePath
"MORLEY_TEZOS_CLIENT"
  let tezosClientPath :: FilePath
tezosClientPath = FilePath -> Maybe FilePath -> FilePath
forall a. a -> Maybe a -> a
fromMaybe FilePath
mccTezosClientPath Maybe FilePath
envTezosClientPath
  TezosClientConfig {BaseUrl
tcEndpointUrl :: TezosClientConfig -> BaseUrl
tcEndpointUrl :: BaseUrl
..} <- FilePath -> Maybe FilePath -> IO TezosClientConfig
getTezosClientConfig FilePath
tezosClientPath Maybe FilePath
mccMbTezosClientDataDir
  let
    endpointUrl :: BaseUrl
endpointUrl = BaseUrl -> Maybe BaseUrl -> BaseUrl
forall a. a -> Maybe a -> a
fromMaybe BaseUrl
tcEndpointUrl Maybe BaseUrl
mccEndpointUrl
    tezosClientEnv :: TezosClientEnv
tezosClientEnv = TezosClientEnv :: BaseUrl -> FilePath -> Maybe FilePath -> TezosClientEnv
TezosClientEnv
      { tceEndpointUrl :: BaseUrl
tceEndpointUrl = BaseUrl
endpointUrl
      , tceTezosClientPath :: FilePath
tceTezosClientPath = FilePath
tezosClientPath
      , tceMbTezosClientDataDir :: Maybe FilePath
tceMbTezosClientDataDir = Maybe FilePath
mccMbTezosClientDataDir
      }

  ClientEnv
clientEnv <- BaseUrl -> IO ClientEnv
newClientEnv BaseUrl
endpointUrl
  pure MorleyClientEnv :: TezosClientEnv
-> ClientLogAction MorleyClientM
-> Maybe SecretKey
-> ClientEnv
-> MorleyClientEnv
MorleyClientEnv
    { mceTezosClient :: TezosClientEnv
mceTezosClient = TezosClientEnv
tezosClientEnv
    , mceLogAction :: ClientLogAction MorleyClientM
mceLogAction = Word -> ClientLogAction MorleyClientM
forall (m :: * -> *). MonadIO m => Word -> ClientLogAction m
mkLogAction Word
mccVerbosity
    , mceSecretKey :: Maybe SecretKey
mceSecretKey = Maybe SecretKey
mccSecretKey
    , mceClientEnv :: ClientEnv
mceClientEnv = ClientEnv
clientEnv
    }