packages feed

morley-client 0.1.2 → 0.2.0

raw patch · 40 files changed

+713/−438 lines, 40 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Morley.Client: AddressAlias :: Alias -> AddressOrAlias
- Morley.Client: AddressResolved :: Address -> AddressOrAlias
- Morley.Client: AnAlias :: Alias -> AliasOrAliasHint
- Morley.Client: AnAliasHint :: AliasHint -> AliasOrAliasHint
- Morley.Client: [mccAliasPrefix] :: MorleyClientConfig -> Maybe Text
- Morley.Client: data AddressOrAlias
- Morley.Client: data Alias
- Morley.Client: data AliasHint
- Morley.Client: data AliasOrAliasHint
- Morley.Client: mkAlias :: Text -> Alias
- Morley.Client: mkAliasHint :: Text -> AliasHint
- Morley.Client.Action.Operation: instance Data.Singletons.Internal.SingI 'Morley.Client.Action.Operation.DryRun
- Morley.Client.Action.Operation: instance Data.Singletons.Internal.SingI 'Morley.Client.Action.Operation.RealRun
- Morley.Client.Init: [mccAliasPrefix] :: MorleyClientConfig -> Maybe Text
- Morley.Client.Init: mccAliasPrefixL :: Lens' MorleyClientConfig (Maybe Text)
- Morley.Client.RPC.Types: OperationInput :: CommonOperationData -> OperationInfo RPCInput -> OperationInput
- Morley.Client.RPC.Types: [oiCommonData] :: OperationInput -> CommonOperationData
- Morley.Client.RPC.Types: [oiCustom] :: OperationInput -> OperationInfo RPCInput
- Morley.Client.RPC.Types: combineResults :: OperationResult -> OperationResult -> OperationResult
- Morley.Client.RPC.Types: data OperationInput
- Morley.Client.RPC.Types: instance Data.Aeson.Types.ToJSON.ToJSON (Morley.Client.Types.OperationInfo Morley.Client.RPC.Types.RPCInput)
- Morley.Client.RPC.Types: instance Data.Aeson.Types.ToJSON.ToJSON Morley.Client.RPC.Types.OperationInput
- Morley.Client.RPC.Types: oiCommonDataL :: Lens' OperationInput CommonOperationData
- Morley.Client.TezosClient.Class: waitForOperation :: HasTezosClient m => OperationHash -> m ()
- Morley.Client.TezosClient.Impl: prefixName :: Maybe Text -> AliasOrAliasHint -> Alias
- Morley.Client.TezosClient.Impl: prefixNameM :: (HasTezosClientEnv env, MonadReader env m) => AliasOrAliasHint -> m Alias
- Morley.Client.TezosClient.Impl: waitForOperationInclusion :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m) => OperationHash -> m ()
- Morley.Client.TezosClient.Types: AddressAlias :: Alias -> AddressOrAlias
- Morley.Client.TezosClient.Types: AddressResolved :: Address -> AddressOrAlias
- Morley.Client.TezosClient.Types: AnAlias :: Alias -> AliasOrAliasHint
- Morley.Client.TezosClient.Types: AnAliasHint :: AliasHint -> AliasOrAliasHint
- Morley.Client.TezosClient.Types: [tceAliasPrefix] :: TezosClientEnv -> Maybe Text
- Morley.Client.TezosClient.Types: data AddressOrAlias
- Morley.Client.TezosClient.Types: data Alias
- Morley.Client.TezosClient.Types: data AliasHint
- Morley.Client.TezosClient.Types: data AliasOrAliasHint
- Morley.Client.TezosClient.Types: instance Data.String.IsString Morley.Client.TezosClient.Types.AliasHint
- Morley.Client.TezosClient.Types: instance Formatting.Buildable.Buildable Morley.Client.TezosClient.Types.AddressOrAlias
- Morley.Client.TezosClient.Types: instance Formatting.Buildable.Buildable Morley.Client.TezosClient.Types.Alias
- Morley.Client.TezosClient.Types: instance Formatting.Buildable.Buildable Morley.Client.TezosClient.Types.AliasHint
- Morley.Client.TezosClient.Types: instance GHC.Base.Monoid Morley.Client.TezosClient.Types.AliasHint
- Morley.Client.TezosClient.Types: instance GHC.Base.Semigroup Morley.Client.TezosClient.Types.AliasHint
- Morley.Client.TezosClient.Types: instance GHC.Classes.Eq Morley.Client.TezosClient.Types.AddressOrAlias
- Morley.Client.TezosClient.Types: instance GHC.Classes.Eq Morley.Client.TezosClient.Types.Alias
- Morley.Client.TezosClient.Types: instance GHC.Classes.Ord Morley.Client.TezosClient.Types.AddressOrAlias
- Morley.Client.TezosClient.Types: instance GHC.Classes.Ord Morley.Client.TezosClient.Types.Alias
- Morley.Client.TezosClient.Types: instance GHC.Show.Show Morley.Client.TezosClient.Types.AddressOrAlias
- Morley.Client.TezosClient.Types: instance GHC.Show.Show Morley.Client.TezosClient.Types.Alias
- Morley.Client.TezosClient.Types: instance GHC.Show.Show Morley.Client.TezosClient.Types.AliasHint
- Morley.Client.TezosClient.Types: instance GHC.Show.Show Morley.Client.TezosClient.Types.AliasOrAliasHint
- Morley.Client.TezosClient.Types: instance Morley.Client.TezosClient.Types.CmdArg Morley.Client.TezosClient.Types.AddressOrAlias
- Morley.Client.TezosClient.Types: instance Morley.Client.TezosClient.Types.CmdArg Morley.Client.TezosClient.Types.Alias
- Morley.Client.TezosClient.Types: instance Morley.Util.CLI.HasCLReader Morley.Client.TezosClient.Types.AddressOrAlias
- Morley.Client.TezosClient.Types: mkAlias :: Text -> Alias
- Morley.Client.TezosClient.Types: mkAliasHint :: Text -> AliasHint
- Morley.Client.TezosClient.Types: tceAliasPrefixL :: Lens' TezosClientEnv (Maybe Text)
- Morley.Client.TezosClient.Types: unsafeCoerceAliasHintToAlias :: AliasHint -> Alias
- Morley.Client.TezosClient.Types: unsafeCoerceAliasToAliasHint :: Alias -> AliasHint
- Morley.Client.TezosClient.Types: unsafeGetAliasHintText :: AliasHint -> Text
- Morley.Client.TezosClient.Types: unsafeGetAliasText :: Alias -> Text
+ Morley.Client: InvalidB58Check :: Text -> RunError
+ Morley.Client: getBlockOperationHashes :: HasTezosRpc m => BlockId -> m [[OperationHash]]
+ Morley.Client: getScriptSizeAtBlock :: HasTezosRpc m => BlockId -> CalcSize -> m ScriptSize
+ Morley.Client: getSecretKey :: HasTezosClient m => AddressOrAlias -> m SecretKey
+ Morley.Client.Action.Common: handleOperationResult :: MonadThrow m => RunOperationResult -> Int -> m (NonEmpty AppliedResult)
+ Morley.Client.Action.Operation: instance Data.Singletons.SingI 'Morley.Client.Action.Operation.DryRun
+ Morley.Client.Action.Operation: instance Data.Singletons.SingI 'Morley.Client.Action.Operation.RealRun
+ Morley.Client.Action.SizeCalculation: computeContractSize :: forall m cp st. (HasTezosRpc m, StorageScope st) => Contract cp st -> Value st -> m Natural
+ Morley.Client.Action.SizeCalculation: computeUntypedContractSize :: HasTezosRpc m => Contract -> Value -> m Natural
+ Morley.Client.App: getBlockOperationHashesImpl :: (RunClient m, MonadUnliftIO m, MonadCatch m) => BlockId -> m [[OperationHash]]
+ Morley.Client.App: getScriptSizeAtBlockImpl :: (RunClient m, MonadUnliftIO m, MonadCatch m) => BlockId -> CalcSize -> m ScriptSize
+ Morley.Client.App: waitForOperationImpl :: forall m. (MonadUnliftIO m, HasTezosRpc m) => m OperationHash -> ClientEnv -> m OperationHash
+ Morley.Client.Parser: GetScriptSize :: GetScriptSizeArgs -> ClientArgsRaw
+ Morley.Client.Parser: GetScriptSizeArgs :: FilePath -> Value -> GetScriptSizeArgs
+ Morley.Client.Parser: [ssScriptFile] :: GetScriptSizeArgs -> FilePath
+ Morley.Client.Parser: [ssStorage] :: GetScriptSizeArgs -> Value
+ Morley.Client.Parser: data GetScriptSizeArgs
+ Morley.Client.RPC.API: [getBlockOperationHashes] :: NodeMethods m -> BlockId -> m [[OperationHash]]
+ Morley.Client.RPC.API: [getScriptSizeAtBlock] :: NodeMethods m -> BlockId -> CalcSize -> m ScriptSize
+ Morley.Client.RPC.API: monitorHeads :: forall m. RunStreamingClient m => m (SourceIO BlockHeader)
+ Morley.Client.RPC.Class: getBlockOperationHashes :: HasTezosRpc m => BlockId -> m [[OperationHash]]
+ Morley.Client.RPC.Class: getScriptSizeAtBlock :: HasTezosRpc m => BlockId -> CalcSize -> m ScriptSize
+ Morley.Client.RPC.Class: waitForOperation :: HasTezosRpc m => m OperationHash -> m OperationHash
+ Morley.Client.RPC.Error: WaitForOperationBlockout :: Word -> WaitForOperationError
+ Morley.Client.RPC.Error: WaitForOperationStreamingError :: Text -> WaitForOperationError
+ Morley.Client.RPC.Error: data WaitForOperationError
+ Morley.Client.RPC.Error: instance Formatting.Buildable.Buildable Morley.Client.RPC.Error.WaitForOperationError
+ Morley.Client.RPC.Error: instance GHC.Exception.Type.Exception Morley.Client.RPC.Error.WaitForOperationError
+ Morley.Client.RPC.Error: instance GHC.Show.Show Morley.Client.RPC.Error.WaitForOperationError
+ Morley.Client.RPC.Getters: getScriptSize :: HasTezosRpc m => CalcSize -> m ScriptSize
+ Morley.Client.RPC.Types: CalcSize :: Expression -> Expression -> TezosInt64 -> Bool -> CalcSize
+ Morley.Client.RPC.Types: InvalidB58Check :: Text -> RunError
+ Morley.Client.RPC.Types: MonitorHeadsContinue :: MonitorHeadsStep a
+ Morley.Client.RPC.Types: MonitorHeadsStop :: a -> MonitorHeadsStep a
+ Morley.Client.RPC.Types: OperationMetadata :: Maybe OperationResult -> OperationMetadata
+ Morley.Client.RPC.Types: OperationRespWithMeta :: OperationResp -> Maybe OperationMetadata -> OperationRespWithMeta
+ Morley.Client.RPC.Types: ScriptSize :: Natural -> ScriptSize
+ Morley.Client.RPC.Types: WithCommonOperationData :: CommonOperationData -> a -> WithCommonOperationData a
+ Morley.Client.RPC.Types: [csGas] :: CalcSize -> TezosInt64
+ Morley.Client.RPC.Types: [csLegacy] :: CalcSize -> Bool
+ Morley.Client.RPC.Types: [csProgram] :: CalcSize -> Expression
+ Morley.Client.RPC.Types: [csStorage] :: CalcSize -> Expression
+ Morley.Client.RPC.Types: [orwmMetadata] :: OperationRespWithMeta -> Maybe OperationMetadata
+ Morley.Client.RPC.Types: [orwmResponse] :: OperationRespWithMeta -> OperationResp
+ Morley.Client.RPC.Types: [rcLevel] :: RunCode -> Maybe TezosNat
+ Morley.Client.RPC.Types: [rcNow] :: RunCode -> Maybe TezosNat
+ Morley.Client.RPC.Types: [ssScriptSize] :: ScriptSize -> Natural
+ Morley.Client.RPC.Types: [unOperationMetadata] :: OperationMetadata -> Maybe OperationResult
+ Morley.Client.RPC.Types: [wcoCommon] :: WithCommonOperationData a -> CommonOperationData
+ Morley.Client.RPC.Types: [wcoCustom] :: WithCommonOperationData a -> a
+ Morley.Client.RPC.Types: data CalcSize
+ Morley.Client.RPC.Types: data MonitorHeadsStep a
+ Morley.Client.RPC.Types: data OperationRespWithMeta
+ Morley.Client.RPC.Types: data WithCommonOperationData a
+ Morley.Client.RPC.Types: instance Data.Aeson.Types.FromJSON.FromJSON Morley.Client.RPC.Types.OperationMetadata
+ Morley.Client.RPC.Types: instance Data.Aeson.Types.FromJSON.FromJSON Morley.Client.RPC.Types.OperationRespWithMeta
+ Morley.Client.RPC.Types: instance Data.Aeson.Types.FromJSON.FromJSON Morley.Client.RPC.Types.ScriptSize
+ Morley.Client.RPC.Types: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Morley.Client.RPC.Types.WithCommonOperationData a)
+ Morley.Client.RPC.Types: instance Data.Aeson.Types.ToJSON.ToJSON Morley.Client.RPC.Types.CalcSize
+ Morley.Client.RPC.Types: instance Formatting.Buildable.Buildable Morley.Client.RPC.Types.BlockHash
+ Morley.Client.RPC.Types: instance GHC.Classes.Eq Morley.Client.RPC.Types.BlockHash
+ Morley.Client.RPC.Types: instance GHC.Classes.Ord Morley.Client.RPC.Types.BlockHash
+ Morley.Client.RPC.Types: instance GHC.Show.Show Morley.Client.RPC.Types.BlockHash
+ Morley.Client.RPC.Types: instance Morley.Client.Types.ToJSONObject Morley.Client.RPC.Types.OriginationOperation
+ Morley.Client.RPC.Types: instance Morley.Client.Types.ToJSONObject Morley.Client.RPC.Types.RevealOperation
+ Morley.Client.RPC.Types: instance Morley.Client.Types.ToJSONObject Morley.Client.RPC.Types.TransactionOperation
+ Morley.Client.RPC.Types: instance Morley.Client.Types.ToJSONObject a => Data.Aeson.Types.ToJSON.ToJSON (Morley.Client.RPC.Types.WithCommonOperationData a)
+ Morley.Client.RPC.Types: instance Web.Internal.HttpApiData.ToHttpApiData Morley.Client.RPC.Types.BlockHash
+ Morley.Client.RPC.Types: newtype OperationMetadata
+ Morley.Client.RPC.Types: newtype ScriptSize
+ Morley.Client.RPC.Types: type OperationInput = WithCommonOperationData (OperationInfo RPCInput)
+ Morley.Client.RPC.Types: wcoCommonDataL :: Lens' (WithCommonOperationData a) CommonOperationData
+ Morley.Client.TezosClient.Class: getSecretKey :: HasTezosClient m => AddressOrAlias -> m SecretKey
+ Morley.Client.TezosClient.Impl: getSecretKey :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m) => AddressOrAlias -> m SecretKey
+ Morley.Client.TezosClient.Types: instance Morley.Client.TezosClient.Types.CmdArg Morley.Tezos.Address.Alias.AddressOrAlias
+ Morley.Client.TezosClient.Types: instance Morley.Client.TezosClient.Types.CmdArg Morley.Tezos.Address.Alias.Alias
+ Morley.Client.Types: class ToJSON a => ToJSONObject a
+ Morley.Client.Types: instance Data.Aeson.Types.ToJSON.ToJSON (Morley.Client.Types.OperationInfo i) => Morley.Client.Types.ToJSONObject (Morley.Client.Types.OperationInfo i)
+ Morley.Client.Types: instance Universum.TypeOps.Each '[Morley.Client.Types.ToJSONObject] '[Morley.Client.Types.TransferInfo i, Morley.Client.Types.OriginationInfo i, Morley.Client.Types.RevealInfo i] => Data.Aeson.Types.ToJSON.ToJSON (Morley.Client.Types.OperationInfo i)
+ Morley.Client.Util: [rcpLevel] :: RunContractParameters cp st -> Maybe Natural
+ Morley.Client.Util: [rcpNow] :: RunContractParameters cp st -> Maybe Timestamp
+ Morley.Client.Util: withLevel :: forall cp_a1um1 st_a1um2. Lens' (RunContractParameters cp_a1um1 st_a1um2) (Maybe Natural)
+ Morley.Client.Util: withNow :: forall cp_a1um1 st_a1um2. Lens' (RunContractParameters cp_a1um1 st_a1um2) (Maybe Timestamp)
- Morley.Client: BlockHashId :: Text -> BlockId
+ Morley.Client: BlockHashId :: BlockHash -> BlockId
- Morley.Client: MorleyClientConfig :: Maybe Text -> Maybe BaseUrl -> FilePath -> Maybe FilePath -> Word -> Maybe SecretKey -> MorleyClientConfig
+ Morley.Client: MorleyClientConfig :: Maybe BaseUrl -> FilePath -> Maybe FilePath -> Word -> Maybe SecretKey -> MorleyClientConfig
- Morley.Client: clientConfigParser :: Parser (Maybe Text) -> Parser MorleyClientConfig
+ Morley.Client: clientConfigParser :: Parser MorleyClientConfig
- Morley.Client: genFreshKey :: HasTezosClient m => AliasOrAliasHint -> m Address
+ Morley.Client: genFreshKey :: HasTezosClient m => Alias -> m Address
- Morley.Client: genKey :: HasTezosClient m => AliasOrAliasHint -> m Address
+ Morley.Client: genKey :: HasTezosClient m => Alias -> m Address
- Morley.Client: getBlockHash :: HasTezosRpc m => BlockId -> m Text
+ Morley.Client: getBlockHash :: HasTezosRpc m => BlockId -> m BlockHash
- Morley.Client: getHeadBlock :: HasTezosRpc m => m Text
+ Morley.Client: getHeadBlock :: HasTezosRpc m => m BlockHash
- Morley.Client: importKey :: HasTezosClient m => Bool -> AliasOrAliasHint -> SecretKey -> m Alias
+ Morley.Client: importKey :: HasTezosClient m => Bool -> Alias -> SecretKey -> m Alias
- Morley.Client: mceClientEnvL :: forall m_a1tcq. Lens' (MorleyClientEnv' m_a1tcq) ClientEnv
+ Morley.Client: mceClientEnvL :: forall m_a1A4i. Lens' (MorleyClientEnv' m_a1A4i) ClientEnv
- Morley.Client: mceLogActionL :: forall m_a1tcq m_a1td7. Lens (MorleyClientEnv' m_a1tcq) (MorleyClientEnv' m_a1td7) (ClientLogAction m_a1tcq) (ClientLogAction m_a1td7)
+ Morley.Client: mceLogActionL :: forall m_a1A4i m_a1A52. Lens (MorleyClientEnv' m_a1A4i) (MorleyClientEnv' m_a1A52) (ClientLogAction m_a1A4i) (ClientLogAction m_a1A52)
- Morley.Client: mceSecretKeyL :: forall m_a1tcq. Lens' (MorleyClientEnv' m_a1tcq) (Maybe SecretKey)
+ Morley.Client: mceSecretKeyL :: forall m_a1A4i. Lens' (MorleyClientEnv' m_a1A4i) (Maybe SecretKey)
- Morley.Client: mceTezosClientL :: forall m_a1tcq. Lens' (MorleyClientEnv' m_a1tcq) TezosClientEnv
+ Morley.Client: mceTezosClientL :: forall m_a1A4i. Lens' (MorleyClientEnv' m_a1A4i) TezosClientEnv
- Morley.Client: registerDelegate :: HasTezosClient m => AliasOrAliasHint -> Maybe ScrubbedBytes -> m ()
+ Morley.Client: registerDelegate :: HasTezosClient m => Alias -> Maybe ScrubbedBytes -> m ()
- Morley.Client: rememberContract :: HasTezosClient m => Bool -> Address -> AliasOrAliasHint -> m ()
+ Morley.Client: rememberContract :: HasTezosClient m => Bool -> Address -> Alias -> m ()
- Morley.Client: waitForOperation :: HasTezosClient m => OperationHash -> m ()
+ Morley.Client: waitForOperation :: HasTezosRpc m => m OperationHash -> m OperationHash
- Morley.Client.Action.Common: OperationConstants :: Text -> BlockConstants -> FeeConstants -> TezosInt64 -> OperationConstants
+ Morley.Client.Action.Common: OperationConstants :: BlockHash -> BlockConstants -> FeeConstants -> TezosInt64 -> OperationConstants
- Morley.Client.Action.Common: OriginationData :: Bool -> AliasHint -> Mutez -> Contract cp st -> Value st -> Maybe Mutez -> OriginationData
+ Morley.Client.Action.Common: OriginationData :: Bool -> Alias -> Mutez -> Contract cp st -> Value st -> Maybe Mutez -> OriginationData
- Morley.Client.Action.Common: [ocLastBlockHash] :: OperationConstants -> Text
+ Morley.Client.Action.Common: [ocLastBlockHash] :: OperationConstants -> BlockHash
- Morley.Client.Action.Common: [odName] :: OriginationData -> AliasHint
+ Morley.Client.Action.Common: [odName] :: OriginationData -> Alias
- Morley.Client.Action.Origination: LOriginationData :: Bool -> AliasHint -> Mutez -> Contract cp st vd -> st -> Maybe Mutez -> LOriginationData
+ Morley.Client.Action.Origination: LOriginationData :: Bool -> Alias -> Mutez -> Contract cp st vd -> st -> Maybe Mutez -> LOriginationData
- Morley.Client.Action.Origination: OriginationData :: Bool -> AliasHint -> Mutez -> Contract cp st -> Value st -> Maybe Mutez -> OriginationData
+ Morley.Client.Action.Origination: OriginationData :: Bool -> Alias -> Mutez -> Contract cp st -> Value st -> Maybe Mutez -> OriginationData
- Morley.Client.Action.Origination: [lodName] :: LOriginationData -> AliasHint
+ Morley.Client.Action.Origination: [lodName] :: LOriginationData -> Alias
- Morley.Client.Action.Origination: [odName] :: OriginationData -> AliasHint
+ Morley.Client.Action.Origination: [odName] :: OriginationData -> Alias
- Morley.Client.Action.Origination: lOriginateContract :: forall m cp st vd env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m, NiceStorage st, NiceParameterFull cp) => Bool -> AliasHint -> AddressOrAlias -> Mutez -> Contract cp st vd -> st -> Maybe Mutez -> m (OperationHash, Address)
+ Morley.Client.Action.Origination: lOriginateContract :: forall m cp st vd env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m, NiceStorage st, NiceParameterFull cp) => Bool -> Alias -> AddressOrAlias -> Mutez -> Contract cp st vd -> st -> Maybe Mutez -> m (OperationHash, Address)
- Morley.Client.Action.Origination: lOriginateLargeContract :: forall m cp st vd env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m, NiceStorage st, NiceParameterFull cp) => Bool -> AliasHint -> AddressOrAlias -> Mutez -> Contract cp st vd -> st -> Maybe Mutez -> m (OperationHash, Address)
+ Morley.Client.Action.Origination: lOriginateLargeContract :: forall m cp st vd env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m, NiceStorage st, NiceParameterFull cp) => Bool -> Alias -> AddressOrAlias -> Mutez -> Contract cp st vd -> st -> Maybe Mutez -> m (OperationHash, Address)
- Morley.Client.Action.Origination: originateContract :: forall m cp st env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m, StorageScope st, ParameterScope cp) => Bool -> AliasHint -> AddressOrAlias -> Mutez -> Contract cp st -> Value st -> Maybe Mutez -> m (OperationHash, Address)
+ Morley.Client.Action.Origination: originateContract :: forall m cp st env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m, StorageScope st, ParameterScope cp) => Bool -> Alias -> AddressOrAlias -> Mutez -> Contract cp st -> Value st -> Maybe Mutez -> m (OperationHash, Address)
- Morley.Client.Action.Origination: originateLargeContract :: forall m cp st env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m, StorageScope st, ParameterScope cp) => Bool -> AliasHint -> AddressOrAlias -> Mutez -> Contract cp st -> Value st -> Maybe Mutez -> m (OperationHash, Address)
+ Morley.Client.Action.Origination: originateLargeContract :: forall m cp st env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m, StorageScope st, ParameterScope cp) => Bool -> Alias -> AddressOrAlias -> Mutez -> Contract cp st -> Value st -> Maybe Mutez -> m (OperationHash, Address)
- Morley.Client.Action.Origination: originateLargeUntypedContract :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => Bool -> AliasHint -> AddressOrAlias -> Mutez -> Contract -> Value -> Maybe Mutez -> m (OperationHash, Address)
+ Morley.Client.Action.Origination: originateLargeUntypedContract :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => Bool -> Alias -> AddressOrAlias -> Mutez -> Contract -> Value -> Maybe Mutez -> m (OperationHash, Address)
- Morley.Client.Action.Origination: originateUntypedContract :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => Bool -> AliasHint -> AddressOrAlias -> Mutez -> Contract -> Value -> Maybe Mutez -> m (OperationHash, Address)
+ Morley.Client.Action.Origination: originateUntypedContract :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => Bool -> Alias -> AddressOrAlias -> Mutez -> Contract -> Value -> Maybe Mutez -> m (OperationHash, Address)
- Morley.Client.App: getBlockHashImpl :: (RunClient m, MonadUnliftIO m, MonadCatch m) => BlockId -> m Text
+ Morley.Client.App: getBlockHashImpl :: (RunClient m, MonadUnliftIO m, MonadCatch m) => BlockId -> m BlockHash
- Morley.Client.Env: mceClientEnvL :: forall m_a1tcq. Lens' (MorleyClientEnv' m_a1tcq) ClientEnv
+ Morley.Client.Env: mceClientEnvL :: forall m_a1A4i. Lens' (MorleyClientEnv' m_a1A4i) ClientEnv
- Morley.Client.Env: mceLogActionL :: forall m_a1tcq m_a1td7. Lens (MorleyClientEnv' m_a1tcq) (MorleyClientEnv' m_a1td7) (ClientLogAction m_a1tcq) (ClientLogAction m_a1td7)
+ Morley.Client.Env: mceLogActionL :: forall m_a1A4i m_a1A52. Lens (MorleyClientEnv' m_a1A4i) (MorleyClientEnv' m_a1A52) (ClientLogAction m_a1A4i) (ClientLogAction m_a1A52)
- Morley.Client.Env: mceSecretKeyL :: forall m_a1tcq. Lens' (MorleyClientEnv' m_a1tcq) (Maybe SecretKey)
+ Morley.Client.Env: mceSecretKeyL :: forall m_a1A4i. Lens' (MorleyClientEnv' m_a1A4i) (Maybe SecretKey)
- Morley.Client.Env: mceTezosClientL :: forall m_a1tcq. Lens' (MorleyClientEnv' m_a1tcq) TezosClientEnv
+ Morley.Client.Env: mceTezosClientL :: forall m_a1A4i. Lens' (MorleyClientEnv' m_a1A4i) TezosClientEnv
- Morley.Client.Init: MorleyClientConfig :: Maybe Text -> Maybe BaseUrl -> FilePath -> Maybe FilePath -> Word -> Maybe SecretKey -> MorleyClientConfig
+ Morley.Client.Init: MorleyClientConfig :: Maybe BaseUrl -> FilePath -> Maybe FilePath -> Word -> Maybe SecretKey -> MorleyClientConfig
- Morley.Client.Logging: logFlush :: MonadIO m => Handle -> LogAction m a
+ Morley.Client.Logging: logFlush :: forall (m :: Type -> Type) a. MonadIO m => Handle -> LogAction m a
- Morley.Client.Parser: ClientArgs :: MorleyClientConfig -> Bool -> ClientArgsRaw -> ClientArgs
+ Morley.Client.Parser: ClientArgs :: MorleyClientConfig -> ClientArgsRaw -> ClientArgs
- Morley.Client.Parser: OriginateArgs :: Maybe FilePath -> AliasHint -> Mutez -> Value -> AddressOrAlias -> Maybe Mutez -> OriginateArgs
+ Morley.Client.Parser: OriginateArgs :: Maybe FilePath -> Alias -> Mutez -> Value -> AddressOrAlias -> Maybe Mutez -> OriginateArgs
- Morley.Client.Parser: [oaContractName] :: OriginateArgs -> AliasHint
+ Morley.Client.Parser: [oaContractName] :: OriginateArgs -> Alias
- Morley.Client.Parser: clientConfigParser :: Parser (Maybe Text) -> Parser MorleyClientConfig
+ Morley.Client.Parser: clientConfigParser :: Parser MorleyClientConfig
- Morley.Client.Parser: contractNameOption :: Parser AliasHint
+ Morley.Client.Parser: contractNameOption :: Parser Alias
- Morley.Client.RPC.API: NodeMethods :: (BlockId -> m Text) -> (BlockId -> Address -> m TezosInt64) -> (BlockId -> Address -> m OriginationScript) -> (BlockId -> Address -> m Expression) -> (BlockId -> m BlockConstants) -> (BlockId -> m BlockHeader) -> (BlockId -> m ProtocolParameters) -> (BlockId -> m [[BlockOperation]]) -> (BlockId -> Address -> GetBigMap -> m GetBigMapResult) -> (BlockId -> Natural -> Text -> m Expression) -> (BlockId -> Natural -> Maybe Natural -> Maybe Natural -> m Expression) -> (BlockId -> Address -> m TezosMutez) -> (BlockId -> Address -> m (Maybe KeyHash)) -> (BlockId -> ForgeOperation -> m HexJSONByteString) -> (BlockId -> RunOperation -> m RunOperationResult) -> (BlockId -> [PreApplyOperation] -> m [RunOperationResult]) -> (BlockId -> RunCode -> m RunCodeResult) -> (BlockId -> Address -> m (Maybe PublicKey)) -> m Text -> (HexJSONByteString -> m OperationHash) -> NodeMethods m
+ Morley.Client.RPC.API: NodeMethods :: (BlockId -> m Text) -> (BlockId -> Address -> m TezosInt64) -> (BlockId -> Address -> m OriginationScript) -> (BlockId -> Address -> m Expression) -> (BlockId -> m BlockConstants) -> (BlockId -> m BlockHeader) -> (BlockId -> m ProtocolParameters) -> (BlockId -> m [[BlockOperation]]) -> (BlockId -> m [[OperationHash]]) -> (BlockId -> Address -> GetBigMap -> m GetBigMapResult) -> (BlockId -> Natural -> Text -> m Expression) -> (BlockId -> Natural -> Maybe Natural -> Maybe Natural -> m Expression) -> (BlockId -> Address -> m TezosMutez) -> (BlockId -> Address -> m (Maybe KeyHash)) -> (BlockId -> CalcSize -> m ScriptSize) -> (BlockId -> ForgeOperation -> m HexJSONByteString) -> (BlockId -> RunOperation -> m RunOperationResult) -> (BlockId -> [PreApplyOperation] -> m [RunOperationResult]) -> (BlockId -> RunCode -> m RunCodeResult) -> (BlockId -> Address -> m (Maybe PublicKey)) -> m Text -> (HexJSONByteString -> m OperationHash) -> NodeMethods m
- Morley.Client.RPC.Class: getBlockHash :: HasTezosRpc m => BlockId -> m Text
+ Morley.Client.RPC.Class: getBlockHash :: HasTezosRpc m => BlockId -> m BlockHash
- Morley.Client.RPC.Getters: getHeadBlock :: HasTezosRpc m => m Text
+ Morley.Client.RPC.Getters: getHeadBlock :: HasTezosRpc m => m BlockHash
- Morley.Client.RPC.Types: BlockHashId :: Text -> BlockId
+ Morley.Client.RPC.Types: BlockHashId :: BlockHash -> BlockId
- Morley.Client.RPC.Types: BlockOperation :: Text -> [OperationResp] -> BlockOperation
+ Morley.Client.RPC.Types: BlockOperation :: Text -> [OperationRespWithMeta] -> BlockOperation
- Morley.Client.RPC.Types: ForgeOperation :: Text -> NonEmpty OperationInput -> ForgeOperation
+ Morley.Client.RPC.Types: ForgeOperation :: BlockHash -> NonEmpty OperationInput -> ForgeOperation
- Morley.Client.RPC.Types: PreApplyOperation :: Text -> Text -> NonEmpty OperationInput -> Signature -> PreApplyOperation
+ Morley.Client.RPC.Types: PreApplyOperation :: Text -> BlockHash -> NonEmpty OperationInput -> Signature -> PreApplyOperation
- Morley.Client.RPC.Types: RunCode :: Expression -> Expression -> Expression -> TezosMutez -> TezosMutez -> Text -> Maybe Address -> Maybe Address -> RunCode
+ Morley.Client.RPC.Types: RunCode :: Expression -> Expression -> Expression -> TezosMutez -> TezosMutez -> Text -> Maybe TezosNat -> Maybe TezosNat -> Maybe Address -> Maybe Address -> RunCode
- Morley.Client.RPC.Types: RunOperationInternal :: Text -> NonEmpty OperationInput -> Signature -> RunOperationInternal
+ Morley.Client.RPC.Types: RunOperationInternal :: BlockHash -> NonEmpty OperationInput -> Signature -> RunOperationInternal
- Morley.Client.RPC.Types: TransactionOpResp :: TransactionOperation -> OperationResp
+ Morley.Client.RPC.Types: TransactionOpResp :: WithCommonOperationData TransactionOperation -> OperationResp
- Morley.Client.RPC.Types: [boContents] :: BlockOperation -> [OperationResp]
+ Morley.Client.RPC.Types: [boContents] :: BlockOperation -> [OperationRespWithMeta]
- Morley.Client.RPC.Types: [foBranch] :: ForgeOperation -> Text
+ Morley.Client.RPC.Types: [foBranch] :: ForgeOperation -> BlockHash
- Morley.Client.RPC.Types: [paoBranch] :: PreApplyOperation -> Text
+ Morley.Client.RPC.Types: [paoBranch] :: PreApplyOperation -> BlockHash
- Morley.Client.RPC.Types: [roiBranch] :: RunOperationInternal -> Text
+ Morley.Client.RPC.Types: [roiBranch] :: RunOperationInternal -> BlockHash
- Morley.Client.TezosClient.Class: genFreshKey :: HasTezosClient m => AliasOrAliasHint -> m Address
+ Morley.Client.TezosClient.Class: genFreshKey :: HasTezosClient m => Alias -> m Address
- Morley.Client.TezosClient.Class: genKey :: HasTezosClient m => AliasOrAliasHint -> m Address
+ Morley.Client.TezosClient.Class: genKey :: HasTezosClient m => Alias -> m Address
- Morley.Client.TezosClient.Class: importKey :: HasTezosClient m => Bool -> AliasOrAliasHint -> SecretKey -> m Alias
+ Morley.Client.TezosClient.Class: importKey :: HasTezosClient m => Bool -> Alias -> SecretKey -> m Alias
- Morley.Client.TezosClient.Class: registerDelegate :: HasTezosClient m => AliasOrAliasHint -> Maybe ScrubbedBytes -> m ()
+ Morley.Client.TezosClient.Class: registerDelegate :: HasTezosClient m => Alias -> Maybe ScrubbedBytes -> m ()
- Morley.Client.TezosClient.Class: rememberContract :: HasTezosClient m => Bool -> Address -> AliasOrAliasHint -> m ()
+ Morley.Client.TezosClient.Class: rememberContract :: HasTezosClient m => Bool -> Address -> Alias -> m ()
- Morley.Client.TezosClient.Impl: genFreshKey :: (MonadThrow m, MonadCatch m, WithClientLog env m, HasTezosClientEnv env, MonadIO m, HasTezosClient m) => AliasOrAliasHint -> m Address
+ Morley.Client.TezosClient.Impl: genFreshKey :: (MonadThrow m, MonadCatch m, WithClientLog env m, HasTezosClientEnv env, MonadIO m, HasTezosClient m) => Alias -> m Address
- Morley.Client.TezosClient.Impl: genKey :: (MonadThrow m, MonadCatch m, WithClientLog env m, HasTezosClientEnv env, MonadIO m, HasTezosClient m) => AliasOrAliasHint -> m Address
+ Morley.Client.TezosClient.Impl: genKey :: (MonadThrow m, MonadCatch m, WithClientLog env m, HasTezosClientEnv env, MonadIO m, HasTezosClient m) => Alias -> m Address
- Morley.Client.TezosClient.Impl: importKey :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m) => Bool -> AliasOrAliasHint -> SecretKey -> m Alias
+ Morley.Client.TezosClient.Impl: importKey :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m) => Bool -> Alias -> SecretKey -> m Alias
- Morley.Client.TezosClient.Impl: registerDelegate :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m) => AliasOrAliasHint -> Maybe ScrubbedBytes -> m ()
+ Morley.Client.TezosClient.Impl: registerDelegate :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m) => Alias -> Maybe ScrubbedBytes -> m ()
- Morley.Client.TezosClient.Impl: rememberContract :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m) => Bool -> Address -> AliasOrAliasHint -> m ()
+ Morley.Client.TezosClient.Impl: rememberContract :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m) => Bool -> Address -> Alias -> m ()
- Morley.Client.TezosClient.Types: TezosClientEnv :: Maybe Text -> BaseUrl -> FilePath -> Maybe FilePath -> TezosClientEnv
+ Morley.Client.TezosClient.Types: TezosClientEnv :: BaseUrl -> FilePath -> Maybe FilePath -> TezosClientEnv
- Morley.Client.Types: _OpOriginate :: forall i_auzE. Prism' (OperationInfo i_auzE) (OriginationInfo i_auzE)
+ Morley.Client.Types: _OpOriginate :: forall i_axBU. Prism' (OperationInfo i_axBU) (OriginationInfo i_axBU)
- Morley.Client.Types: _OpReveal :: forall i_auzE. Prism' (OperationInfo i_auzE) (RevealInfo i_auzE)
+ Morley.Client.Types: _OpReveal :: forall i_axBU. Prism' (OperationInfo i_axBU) (RevealInfo i_axBU)
- Morley.Client.Types: _OpTransfer :: forall i_auzE. Prism' (OperationInfo i_auzE) (TransferInfo i_auzE)
+ Morley.Client.Types: _OpTransfer :: forall i_axBU. Prism' (OperationInfo i_axBU) (TransferInfo i_axBU)
- Morley.Client.Util: RunContractParameters :: Contract cp st -> MaybeRPC (Value cp) -> MaybeRPC (Value st) -> Mutez -> Mutez -> Maybe Address -> Maybe Address -> RunContractParameters cp st
+ Morley.Client.Util: RunContractParameters :: Contract cp st -> MaybeRPC (Value cp) -> MaybeRPC (Value st) -> Mutez -> Maybe Timestamp -> Maybe Natural -> Mutez -> Maybe Address -> Maybe Address -> RunContractParameters cp st
- Morley.Client.Util: withAmount :: forall cp_a1mx2 st_a1mx3. Lens' (RunContractParameters cp_a1mx2 st_a1mx3) Mutez
+ Morley.Client.Util: withAmount :: forall cp_a1um1 st_a1um2. Lens' (RunContractParameters cp_a1um1 st_a1um2) Mutez
- Morley.Client.Util: withBalance :: forall cp_a1mx2 st_a1mx3. Lens' (RunContractParameters cp_a1mx2 st_a1mx3) Mutez
+ Morley.Client.Util: withBalance :: forall cp_a1um1 st_a1um2. Lens' (RunContractParameters cp_a1um1 st_a1um2) Mutez
- Morley.Client.Util: withSender :: forall cp_a1mx2 st_a1mx3. Lens' (RunContractParameters cp_a1mx2 st_a1mx3) (Maybe Address)
+ Morley.Client.Util: withSender :: forall cp_a1um1 st_a1um2. Lens' (RunContractParameters cp_a1um1 st_a1um2) (Maybe Address)
- Morley.Client.Util: withSource :: forall cp_a1mx2 st_a1mx3. Lens' (RunContractParameters cp_a1mx2 st_a1mx3) (Maybe Address)
+ Morley.Client.Util: withSource :: forall cp_a1um1 st_a1um2. Lens' (RunContractParameters cp_a1um1 st_a1um2) (Maybe Address)

Files

CHANGES.md view
@@ -1,6 +1,35 @@ <!-- Unreleased: append new entries here -->  +0.2.0+=====+* [!1161](https://gitlab.com/morley-framework/morley/-/merge_requests/1161)+  Remove support for `AliasHint`+* [!1164](https://gitlab.com/morley-framework/morley/-/merge_requests/1164)+  Add `now` and `level` params to the `/run_code`+* [!1150](https://gitlab.com/morley-framework/morley/-/merge_requests/1150)+  Implement wait-for-operation via RPC+  + Block injection is now checked for errors and injection is retried.+* [!1159](https://gitlab.com/morley-framework/morley/-/merge_requests/1159)+  Add script size calculation to morley-client+* [!1088](https://gitlab.com/morley-framework/morley/-/merge_requests/1088)+  Move data types related to address aliases to `morley`.+* [!1155](https://gitlab.com/morley-framework/morley/-/merge_requests/1155)+  Update operations limits estimation to match the v13.0 `tezos-client` implementation.+* [!1147](https://gitlab.com/morley-framework/morley/-/merge_requests/1147)+  Fix error handling in morley-client+  + `handleOperationResult` is now exported from `Morley.Client.Action.Common`+* [!1114](https://gitlab.com/morley-framework/morley/-/merge_requests/1114)+  Update to ghc-9.0.2+* [!1108](https://gitlab.com/morley-framework/morley/-/merge_requests/1108)+  Remove support for the deprecated morley extensions+* [!1133](https://gitlab.com/morley-framework/morley/-/merge_requests/1133)+  Add missing fields to `TransactionOpResp` constructor.+* [!1127](https://gitlab.com/morley-framework/morley/-/merge_requests/1127)+  Add method to get secret key from tezos-client+* [!1140](https://gitlab.com/morley-framework/morley/-/merge_requests/1140)+  Derive `newtype` `Eq`, `Ord`, `Show`, `Buildable` instances for `BlockHash`+ 0.1.2 ===== * [!1017](https://gitlab.com/morley-framework/morley/-/merge_requests/1017)@@ -31,7 +60,7 @@   Move `AsRPC` type family to `morley` * [!978](https://gitlab.com/morley-framework/morley/-/merge_requests/978)   Make it difficult to misuse 'Show'-  + Use `Buildable` and `pretty` preferrentially.+  + Use `Buildable` and `pretty` preferentially.   + Add `Buildable` instances to that effect for `FeeParserException`, `SecretKeyEncryptionParserException`.   + Use `displayException` instead of `show` where appropriate. 
app/Main.hs view
@@ -1,9 +1,6 @@ -- SPDX-FileCopyrightText: 2021 Oxhead Alpha -- SPDX-License-Identifier: LicenseRef-MIT-OA --- TODO [#712]: Remove this next major release-{-# OPTIONS_GHC -Wno-deprecations #-}- module Main   ( main   ) where@@ -18,11 +15,12 @@  import Morley.Client import Morley.Client.Parser-import Morley.Client.RPC (BlockOperation(..), OperationResp(..))+import Morley.Client.RPC (BlockOperation(..), OperationResp(..), OperationRespWithMeta(..)) import Morley.Client.RPC.Getters import Morley.Client.Util (extractAddressesFromValue)-import Morley.Michelson.Runtime (prepareContract, prepareContractExt)-import Morley.Michelson.TypeCheck (typeCheckContract, typeCheckingWith, typeVerifyParameter)+import Morley.Michelson.Runtime (prepareContract)+import Morley.Michelson.TypeCheck+  (typeCheckContract, typeCheckContractAndStorage, typeCheckingWith, typeVerifyParameter) import Morley.Michelson.Typed (Contract, Contract'(..), SomeContract(..)) import Morley.Michelson.Typed.Value (Value'(..)) import Morley.Michelson.Untyped qualified as U@@ -31,11 +29,11 @@ import Morley.Util.Exception (throwLeft) import Morley.Util.Main (wrapMain) -mainImpl :: Bool -> ClientArgsRaw -> MorleyClientM ()-mainImpl exts cmd =+mainImpl :: ClientArgsRaw -> MorleyClientM ()+mainImpl cmd =   case cmd of     Originate OriginateArgs{..} -> do-      contract <- liftIO $ (if exts then prepareContractExt else prepareContract) oaMbContractFile+      contract <- liftIO $ prepareContract oaMbContractFile       let originator = oaOriginateFrom       (operationHash, contractAddr) <-         originateUntypedContract True oaContractName originator oaInitialBalance@@ -64,6 +62,7 @@           U.ValueUnit -> transfer sendAddress destAddress taAmount U.DefEpName VUnit Nothing           _ -> throwString ("The transaction parameter must be 'Unit' "             <> "when transferring to an implicit account")+        TransactionRollupAddress _ -> throwString "Only smart contracts can call txr1 addresses"        putTextLn $ "Transaction was successfully sent.\nOperation hash " <> pretty operationHash <> "." @@ -75,13 +74,20 @@       blockHeader <- getBlockHeader blockId       putStrLn $ Aeson.encode blockHeader +    GetScriptSize GetScriptSizeArgs{..} -> do+      contract <- liftIO $ prepareContract (Just ssScriptFile)+      void . throwLeft . pure . typeCheckingWith def $+        typeCheckContractAndStorage contract ssStorage+      size <- computeUntypedContractSize contract ssStorage+      print size+     GetBlockOperations blockId -> do       operationLists <- getBlockOperations blockId       forM_ operationLists $ \operations -> do         forM_ operations $ \BlockOperation {..} -> do           putTextLn $ "Hash: " <> boHash           putTextLn $ "Contents: "-          forM_ boContents $ \case+          forM_ (orwmResponse <$> boContents) \case             TransactionOpResp to -> putStrLn $ Aeson.encode to             OtherOpResp -> putTextLn "Non-transaction operation"           putTextLn ""@@ -97,6 +103,6 @@   setFileSystemEncoding utf8    disableAlphanetWarning-  ClientArgs parsedConfig exts cmd <- Opt.execParser morleyClientInfo+  ClientArgs parsedConfig cmd <- Opt.execParser morleyClientInfo   env <- mkMorleyClientEnv parsedConfig-  runMorleyClientM env (mainImpl exts cmd)+  runMorleyClientM env (mainImpl cmd)
morley-client.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           morley-client-version:        0.1.2+version:        0.2.0 synopsis:       Client to interact with the Tezos blockchain description:    A client to interact with the Tezos blockchain, by use of the tezos-node RPC and/or of the tezos-client binary. category:       Blockchain@@ -35,6 +35,7 @@       Morley.Client.Action.Origination       Morley.Client.Action.Origination.Large       Morley.Client.Action.Reveal+      Morley.Client.Action.SizeCalculation       Morley.Client.Action.Transaction       Morley.Client.App       Morley.Client.Env@@ -235,6 +236,7 @@   other-modules:       Ingredients       Test.BigMapGet+      Test.Errors       Test.Fees       Test.KeyRevealing       Test.Origination
src/Morley/Client.hs view
@@ -68,12 +68,6 @@   , readBigMapValue    -- * @tezos-client@-  , Alias-  , mkAlias-  , AliasHint-  , mkAliasHint-  , AliasOrAliasHint (..)-  , AddressOrAlias (..)   , addressResolved   , HasTezosClient (..)   , resolveAddress
src/Morley/Client/Action.hs view
@@ -8,6 +8,7 @@   ( module Morley.Client.Action.Operation   , module Morley.Client.Action.Origination   , module Morley.Client.Action.Transaction+  , module Morley.Client.Action.SizeCalculation   , ClientInput   , revealKeyUnlessRevealed   ) where@@ -15,4 +16,5 @@ import Morley.Client.Action.Common (ClientInput, revealKeyUnlessRevealed) import Morley.Client.Action.Operation import Morley.Client.Action.Origination+import Morley.Client.Action.SizeCalculation import Morley.Client.Action.Transaction
src/Morley/Client/Action/Batched.hs view
@@ -21,6 +21,7 @@ import Morley.Client.TezosClient import Morley.Client.Types import Morley.Tezos.Address+import Morley.Tezos.Address.Alias (AddressOrAlias) import Morley.Util.Batching  {- | Where the batched operations occur.
src/Morley/Client/Action/Common.hs view
@@ -23,6 +23,7 @@   , toParametersInternals   , mkOriginationScript   , revealKeyUnlessRevealed+  , handleOperationResult   ) where  import Control.Lens (Prism')@@ -40,18 +41,19 @@ import Morley.Client.Types import Morley.Client.Util import Morley.Micheline (TezosInt64, TezosMutez(..), toExpression)-import Morley.Micheline.Expression (Expression(ExpressionString))+import Morley.Micheline.Expression (expressionString) import Morley.Michelson.Typed qualified as T import Morley.Michelson.Typed.Scope import Morley.Michelson.Untyped.Entrypoints import Morley.Tezos.Address+import Morley.Tezos.Address.Alias (AddressOrAlias(..), Alias) import Morley.Tezos.Core import Morley.Tezos.Crypto  -- | Datatype that contains various values required for -- chain operations. data OperationConstants = OperationConstants-  { ocLastBlockHash :: Text+  { ocLastBlockHash :: BlockHash   -- ^ Block in which operations is going to be injected   , ocBlockConstants :: BlockConstants   -- ^ Information about block: chain_id and protocol@@ -92,7 +94,7 @@ data OriginationData =   forall cp st. (ParameterScope cp, StorageScope st) => OriginationData   { odReplaceExisting :: Bool-  , odName :: AliasHint+  , odName :: Alias   , odBalance :: Mutez   , odContract :: T.Contract cp st   , odStorage :: T.Value st@@ -173,20 +175,30 @@         _ -> throwM $ RpcUnexpectedSize 1 (length results)    handleOperationResult runResult expectedContentsSize-  where-    handleOperationResult ::-      MonadThrow m => RunOperationResult -> Int -> m (NonEmpty AppliedResult)-    handleOperationResult RunOperationResult{..} expectedContentsSize = do-      when (length rrOperationContents /= expectedContentsSize) $-        throwM $ RpcUnexpectedSize expectedContentsSize (length rrOperationContents) -      mapM (\(OperationContent (RunMetadata res internalOps)) ->-              let internalResults = map unInternalOperation internalOps in-                case foldr combineResults res internalResults of-                  OperationApplied appliedRes -> pure appliedRes-                  OperationFailed errors -> handleErrors errors-           ) rrOperationContents+-- | Handle a result of an operation: throw errors if there was an error,+-- return a nonempty list of applied results if there weren't.+handleOperationResult ::+  MonadThrow m => RunOperationResult -> Int -> m (NonEmpty AppliedResult)+handleOperationResult RunOperationResult{..} expectedContentsSize = do+  when (length rrOperationContents /= expectedContentsSize) $+    throwM $ RpcUnexpectedSize expectedContentsSize (length rrOperationContents) +  let (appliedResults, runErrors) =+        sconcat $ first pure . collectResults <$> rrOperationContents++  whenJust runErrors handleErrors++  pure appliedResults++  where+    collectResults :: OperationContent -> (AppliedResult, Maybe [RunError])+    collectResults (OperationContent (RunMetadata res internalOps)) =+      res : map unInternalOperation internalOps+      & flip foldr (mempty, Nothing) \case+        OperationApplied result -> first (result <>)+        OperationFailed errors -> second (Just errors <>)+     -- When an error happens, we will get a list of 'RunError' in response.     -- This list often contains more than one item.     -- We tested which errors are returned in certain scenarios and added@@ -207,7 +219,7 @@         = throwM $ BadParameter address expr       | Just address <- findError _BadContractParameter       , Just notation <- findError _InvalidContractNotation-        = throwM $ BadParameter address (ExpressionString notation)+        = throwM $ BadParameter address (expressionString notation)       | Just address <- findError _REEmptyTransaction         = throwM $ EmptyTransaction address       | Just address <- findError _RuntimeError
src/Morley/Client/Action/Operation.hs view
@@ -15,7 +15,7 @@ import Data.List.NonEmpty qualified as NE import Data.Singletons (Sing, SingI, sing) import Data.Text qualified as T-import Fmt (blockListF', listF, pretty, (+|), (|+))+import Fmt (blockListF, blockListF', listF, nameF, pretty, (+|), (|+))  import Morley.Client.Action.Common import Morley.Client.Logging@@ -27,6 +27,8 @@ import Morley.Client.Types import Morley.Micheline (StringEncode(..), TezosInt64, TezosMutez(..)) import Morley.Tezos.Address+import Morley.Tezos.Address.Alias (AddressOrAlias(..))+import Morley.Tezos.Core import Morley.Tezos.Crypto import Morley.Util.ByteString @@ -103,6 +105,10 @@     (opHash, res) <- runOperationsNonEmpty sender $ op :| ops     return $ (Just opHash, toList res) +-- | How many times to retry if an operation fails after injection+injectionRetryCount :: Natural+injectionRetryCount = 2+ -- | Perform non-empty sequence of operations. -- -- Returns operation hash and result of each operation@@ -117,7 +123,7 @@   -> NonEmpty (OperationInfo ClientInput)   -> m (OperationHash, NonEmpty (OperationInfo Result)) runOperationsNonEmpty sender operations =-  runOperationsNonEmptyHelper @'RealRun sender operations+  runOperationsNonEmptyHelper @'RealRun injectionRetryCount sender operations  -- | Flag that is used to determine @runOperationsNonEmptyHelper@ behaviour. data RunMode = DryRun | RealRun@@ -159,7 +165,7 @@   -> NonEmpty (OperationInfo ClientInput)   -> m (NonEmpty (AppliedResult, TezosMutez)) dryRunOperationsNonEmpty sender operations =-  runOperationsNonEmptyHelper @'DryRun sender operations+  runOperationsNonEmptyHelper @'DryRun 0 sender operations  -- | Perform non-empty sequence of operations and either dry-run -- and return estimated limits and fees or perform operation injection.@@ -171,10 +177,11 @@      , WithClientLog env m      , SingI runMode      )-  => AddressOrAlias+  => Natural+  -> AddressOrAlias   -> NonEmpty (OperationInfo ClientInput)   -> m (RunResult runMode)-runOperationsNonEmptyHelper sender operations = do+runOperationsNonEmptyHelper retryCount sender operations = do   logOperations @runMode sender operations   senderAddress <- resolveAddress sender   prohibitContractSender senderAddress $ head operations@@ -185,7 +192,7 @@   pp <- getProtocolParameters   OperationConstants{..} <- preProcessOperation senderAddress -  let convertOps i = OperationInput commonData . \case+  let convertOps i = WithCommonOperationData commonData . \case         OpTransfer (TransactionData TD {..}) ->           OpTransfer TransactionOperation           { toDestination = tdReceiver@@ -238,9 +245,20 @@    -- Fill in fees   let-    updateOp opToRun mbFee ar isFirst = do+    updateOp :: OperationInput -> Maybe Mutez -> AppliedResult -> Bool -> m (OperationInput, Maybe (Signature, ByteString))+    updateOp opToRun@(WithCommonOperationData _ internalOp) mbFee ar isFirst = do+      let gasSafetyGuard = 100+          -- @gasSafetyGuard@ is added to origination operations and transfers to non-implicit+          -- accounts, see https://gitlab.com/tezos/tezos/-/blob/v13.0/src/proto_013_PtJakart/lib_client/injection.ml#L750+          additionalGas = case internalOp of+            OpOriginate _ -> gasSafetyGuard+            OpTransfer (TransactionOperation {..}) -> case toDestination of+              KeyAddress _ -> 0+              ContractAddress _ -> gasSafetyGuard+              TransactionRollupAddress _ -> gasSafetyGuard+            OpReveal _ -> 0       let storageLimit = computeStorageLimit [ar] pp + 20 -- similarly to tezos-client, we add 20 for safety-      let gasLimit = arConsumedGas ar + 100  -- adding extra for safety+      let gasLimit = arConsumedGas ar + additionalGas           updateCommonDataForFee fee =             updateCommonData gasLimit storageLimit (TezosMutez fee) @@ -249,7 +267,7 @@         @(Maybe (Signature, ByteString))  -- ready operation and its signature         (\fee ->           return $ opToRun &~-            oiCommonDataL %= updateCommonDataForFee fee+            wcoCommonDataL %= updateCommonDataForFee fee           )         (\op -> do           forgedOp <- forgeOp $ one op@@ -304,11 +322,10 @@   ars2 <- getAppliedResults (Right preApplyOp)   case sing @runMode of     SDryRun -> do-      let fees = map (codFee . oiCommonData) updOps+      let fees = map (codFee . wcoCommon) updOps       return $ NE.zip ars2 fees     SRealRun -> do-      operationHash <- injectOperation (HexJSONByteString signedOp)-      waitForOperation operationHash+      operationHash <- waitForOperation $ injectOperation (HexJSONByteString signedOp)       let contractAddrs = arOriginatedContracts <$> ars2       opsRes <- forM (NE.zip operations contractAddrs) $ \case         (OpTransfer _, []) ->@@ -322,7 +339,7 @@           throwM RpcOriginatedNoContracts         (OpOriginate OriginationData{..}, [addr]) -> do           logDebug $ "Saving " +| addr |+ " for " +| odName |+ "\n"-          rememberContract odReplaceExisting addr (AnAliasHint odName)+          rememberContract odReplaceExisting addr odName           alias <- getAlias $ AddressResolved addr           logInfo $ "Originated contract: " <> pretty alias           return $ OpOriginate addr@@ -332,6 +349,12 @@           return $ OpReveal ()       forM_ ars2 logStatistics       return (operationHash, opsRes)+      `catch` \case+        (UnexpectedRunErrors errs) | retryCount > 0 -> do+          logError $ pretty $ nameF "When injecting operations, there were unexpected errors" $+            blockListF errs+          runOperationsNonEmptyHelper @runMode (retryCount - 1) sender operations+        e -> throwM e   where     mayNeedSenderRevealing :: [OperationInfo i] -> Bool     mayNeedSenderRevealing = any \case@@ -350,6 +373,7 @@     prohibitContractSender addr op = case (addr, op) of       (KeyAddress _, _) -> pass       (ContractAddress _, op') -> throwM $ ContractSender addr (opName op')+      (TransactionRollupAddress _, op') -> throwM $ ContractSender addr (opName op')      opName = \case       OpTransfer _ -> "transfer"
src/Morley/Client/Action/Origination.hs view
@@ -41,6 +41,7 @@ import Morley.Michelson.Typed.Scope import Morley.Michelson.Untyped qualified as U import Morley.Tezos.Address+import Morley.Tezos.Address.Alias (AddressOrAlias, Alias) import Morley.Tezos.Core import Morley.Util.Exception @@ -74,7 +75,7 @@      , ParameterScope cp      )   => Bool-  -> AliasHint+  -> Alias   -> AddressOrAlias   -> Mutez   -> Contract cp st@@ -93,7 +94,7 @@      , WithClientLog env m      )   => Bool-  -> AliasHint+  -> Alias   -> AddressOrAlias   -> Mutez   -> U.Contract@@ -129,7 +130,7 @@      , NiceParameterFull cp      )   => Bool-  -> AliasHint+  -> Alias   -> AddressOrAlias   -> Mutez   -> L.Contract cp st vd@@ -185,7 +186,7 @@      , ParameterScope cp      )   => Bool-  -> AliasHint+  -> Alias   -> AddressOrAlias   -> Mutez   -> Contract cp st@@ -204,7 +205,7 @@      , WithClientLog env m      )   => Bool-  -> AliasHint+  -> Alias   -> AddressOrAlias   -> Mutez   -> U.Contract@@ -240,7 +241,7 @@      , NiceParameterFull cp      )   => Bool-  -> AliasHint+  -> Alias   -> AddressOrAlias   -> Mutez   -> L.Contract cp st vd@@ -259,7 +260,7 @@ data LOriginationData = forall cp st vd. (NiceParameterFull cp, NiceStorage st)   => LOriginationData   { lodReplaceExisting :: Bool-  , lodName :: AliasHint+  , lodName :: Alias   , lodBalance :: Mutez   , lodContract :: L.Contract cp st vd   , lodStorage :: st
src/Morley/Client/Action/Origination/Large.hs view
@@ -53,6 +53,7 @@ import Morley.Michelson.Typed.Util (PushableStorageSplit(..), splitPushableStorage) import Morley.Michelson.Typed.Value import Morley.Michelson.Untyped.Annotation (annQ, noAnn)+import Morley.Tezos.Address.Alias (Alias(..))  -- | Just a utility type to hold 'SomeLargeContractOriginator' and its large -- contract 'OriginationData'.@@ -135,7 +136,7 @@     cEntriesOrder = def      cViews = def-    cCode =+    cCode = T.mkContractCode $       UNPAIR `Seq`       -- make checks on the storage       DIP@@ -192,7 +193,7 @@   -> T.Contract param store -- ^ large contract   -> Mutez -- ^ balance to tranfer during contract creation   -> Value (ToT (Lambda (Value heavy) (Address, [Operation])))-mkOriginationLambda instr largeContract xtzs = VLam $ RfNormal $+mkOriginationLambda instr largeContract xtzs = mkVLam $ RfNormal $   instr `Seq` PUSH (VMutez xtzs) `Seq` NONE `Seq`   CREATE_CONTRACT largeContract `Seq`   NIL `Seq` SWAP `Seq` CONS `Seq` SWAP `Seq` PAIR@@ -220,7 +221,7 @@ mkLargeOriginatorData sender' LargeOriginationData{..} = case largeOriginator of   SomeLargeContractOriginator heavyVal origContract _origLambda -> OriginationData     { odReplaceExisting = odReplaceExisting $ largeContractData-    , odName = "largeOriginator." <> odName largeContractData+    , odName = Alias $ "largeOriginator." <> unAlias (odName largeContractData)     , odBalance = zeroMutez     -- Note ^ we don't transfer any balance here, we instead do it as part of the     -- last transaction (where it will be transferred to the large contract)@@ -272,6 +273,6 @@   case completedStore of     Right (VPair (_, VOr (Left largeVAddr))) -> do       let largeAddr = fromVal @Address largeVAddr-      rememberContract odReplaceExisting largeAddr (AnAliasHint odName)+      rememberContract odReplaceExisting largeAddr odName       pure largeAddr     _ -> throwM RpcOriginatedNoContracts
src/Morley/Client/Action/Reveal.hs view
@@ -17,9 +17,10 @@ import Morley.Client.RPC.Error import Morley.Client.RPC.Getters import Morley.Client.RPC.Types-import Morley.Client.TezosClient (AddressOrAlias(..), HasTezosClient)+import Morley.Client.TezosClient (HasTezosClient) import Morley.Client.Types import Morley.Tezos.Address+import Morley.Tezos.Address.Alias (AddressOrAlias(..))  -- | Reveal given key. --
+ src/Morley/Client/Action/SizeCalculation.hs view
@@ -0,0 +1,40 @@+-- SPDX-FileCopyrightText: 2022 Oxhead Alpha+-- SPDX-License-Identifier: LicenseRef-MIT-OA++module Morley.Client.Action.SizeCalculation+  ( computeUntypedContractSize+  , computeContractSize+  ) where++import Morley.Client.RPC+import Morley.Micheline.Class (ToExpression(..))+import Morley.Michelson.Typed (Contract, Value)+import Morley.Michelson.Typed.Scope+import Morley.Michelson.Untyped qualified as U++computeUntypedContractSize :: HasTezosRpc m => U.Contract -> U.Value -> m Natural+computeUntypedContractSize ct st = do+  pps <- getProtocolParameters+  let csProgram = toExpression ct+      csStorage = toExpression st+      csGas     = ppHardGasLimitPerOperation pps+      csLegacy  = False+  ScriptSize size <- getScriptSize CalcSize{..}+  return size++computeContractSize+  :: forall m cp st.+     ( HasTezosRpc m+     , StorageScope st+     )+  => Contract cp st+  -> Value st+  -> m Natural+computeContractSize ct st = do+  pps <- getProtocolParameters+  let csProgram = toExpression ct+      csStorage = toExpression st+      csGas     = ppHardGasLimitPerOperation pps+      csLegacy  = False+  ScriptSize size <- getScriptSize CalcSize{..}+  return size
src/Morley/Client/Action/Transaction.hs view
@@ -24,12 +24,12 @@ import Morley.Client.RPC.Error import Morley.Client.RPC.Types import Morley.Client.TezosClient.Class-import Morley.Client.TezosClient.Types import Morley.Client.Types import Morley.Michelson.Typed qualified as T import Morley.Michelson.Typed.Scope import Morley.Michelson.Untyped.Entrypoints import Morley.Tezos.Address+import Morley.Tezos.Address.Alias (AddressOrAlias(..)) import Morley.Tezos.Core (Mutez)  -- | Perform sequence of transactions to the contract, each transactions should be
src/Morley/Client/App.hs view
@@ -14,7 +14,9 @@   , getCounterImpl   , getBlockHeaderImpl   , getBlockConstantsImpl+  , getScriptSizeAtBlockImpl   , getBlockOperationsImpl+  , getBlockOperationHashesImpl   , getProtocolParametersImpl   , runOperationImpl   , preApplyOperationsImpl@@ -30,6 +32,7 @@   , runCodeImpl   , getChainIdImpl   , getDelegateImpl+  , waitForOperationImpl    -- * Timeouts and retries   , retryOnTimeout@@ -51,8 +54,11 @@ import Servant.Client.Core   (ClientError(..), Request, RequestBody(..), RequestF(..), Response, ResponseF(..), RunClient) import Servant.Client.Core.RunClient (runRequest)+import Servant.Client.Streaming (withClientM)+import Servant.Types.SourceT (SourceT(unSourceT), StepT(..)) import System.Random (randomRIO)-import UnliftIO (MonadUnliftIO)+import UnliftIO (MonadUnliftIO, withRunInIO)+import UnliftIO.Async (wait, waitEither, withAsync) import UnliftIO.Timeout (timeout)  import Morley.Client.Logging (WithClientLog, logDebug)@@ -102,8 +108,8 @@ -- HasTezosRpc functions ---------------- -getBlockHashImpl :: (RunClient m, MonadUnliftIO m, MonadCatch m) => BlockId -> m Text-getBlockHashImpl = retryOnceOnTimeout ... API.getBlockHash API.nodeMethods+getBlockHashImpl :: (RunClient m, MonadUnliftIO m, MonadCatch m) => BlockId -> m BlockHash+getBlockHashImpl = retryOnceOnTimeout ... fmap BlockHash . API.getBlockHash API.nodeMethods  getCounterImpl :: (RunClient m, MonadUnliftIO m, MonadCatch m) => BlockId -> Address -> m TezosInt64 getCounterImpl = retryOnceOnTimeout ... API.getCounter API.nodeMethods@@ -119,6 +125,10 @@ getBlockOperationsImpl =   retryOnceOnTimeout ... API.getBlockOperations API.nodeMethods +getBlockOperationHashesImpl :: (RunClient m, MonadUnliftIO m, MonadCatch m) => BlockId -> m [[OperationHash]]+getBlockOperationHashesImpl =+  retryOnceOnTimeout ... API.getBlockOperationHashes API.nodeMethods+ getProtocolParametersImpl ::   (RunClient m, MonadUnliftIO m, MonadCatch m) => BlockId -> m ProtocolParameters getProtocolParametersImpl = retryOnceOnTimeout ... API.getProtocolParameters API.nodeMethods@@ -160,6 +170,10 @@   BlockId -> Address -> GetBigMap -> m GetBigMapResult getContractBigMapImpl = retryOnceOnTimeout ... API.getBigMap API.nodeMethods +getScriptSizeAtBlockImpl ::+  (RunClient m, MonadUnliftIO m, MonadCatch m) => BlockId -> CalcSize -> m ScriptSize+getScriptSizeAtBlockImpl = retryOnceOnTimeout ... API.getScriptSizeAtBlock API.nodeMethods+ getBigMapValueAtBlockImpl ::   (RunClient m, MonadUnliftIO m, MonadCatch m) =>   BlockId -> Natural -> Text -> m Expression@@ -193,6 +207,70 @@  getChainIdImpl :: (RunClient m, MonadCatch m) => m ChainId getChainIdImpl = throwLeft $ parseChainId <$> API.getChainId API.nodeMethods++waitForOperationImpl :: forall m+                      . (MonadUnliftIO m, HasTezosRpc m)+                     => m OperationHash+                     -> ClientEnv+                     -> m OperationHash+waitForOperationImpl opHash env = do+  finalHead <- getBlockHeader FinalHeadId+  hash <- opHash+  let limit = 10 -- blocks to wait for+      blockout = throwM $ WaitForOperationBlockout limit+      handle other = maybe (wait other >>= maybe blockout pure) pure+  -- NB: we can't really use race here because even on failure on one direction+  -- we still want to check the other.+  withAsync (searchForwards limit hash) \fwd ->+    withAsync (searchBackwards hash (bhLevel finalHead) HeadId) \bwd ->+      waitEither fwd bwd >>= \case+        Left res -> handle bwd res+        Right res -> handle fwd res+  where+    monitorHeads :: Word -> (BlockHeader -> m (MonitorHeadsStep OperationHash)) -> m (Maybe OperationHash)+    monitorHeads limit test = withRunInIO $ \runInIO ->+      withClientM (client runInIO) env (either throwM pure)+      where+        client runInIO = do+          src <- API.monitorHeads+          liftIO $ unSourceT src $ go limit runInIO+        go 0 _ = const $ pure Nothing+        go n runInIO = \case+          Stop -> pure Nothing+          Error str -> throwM $ WaitForOperationStreamingError (fromString str)+          Skip next -> go n runInIO next+          Yield a next -> runInIO (test a) >>= \case+            MonitorHeadsContinue -> go (n - 1) runInIO next+            MonitorHeadsStop res -> pure $ Just res+          Effect eff -> eff >>= go n runInIO+    searchBackwards :: OperationHash -> Int64 -> BlockId -> m (Maybe OperationHash)+    searchBackwards hash stopAtLevel blkHead = do+      checkBlock hash blkHead >>= \case+        MonitorHeadsContinue -> do+          header <- getBlockHeader blkHead+          if bhLevel header == stopAtLevel+          then pure Nothing+          else searchBackwards hash stopAtLevel $ BlockHashId $ bhPredecessor header+        MonitorHeadsStop res -> pure $ Just res+    searchForwards :: Word -> OperationHash -> m (Maybe OperationHash)+    searchForwards limit hash = monitorHeads limit (checkBlock hash . BlockHashId . bhHash)+    checkBlock :: OperationHash -> BlockId -> m (MonitorHeadsStep OperationHash)+    checkBlock hash blkId = do+      opHashes <- concat <$> getBlockOperationHashes blkId+      if hash `notElem` opHashes+      then pure MonitorHeadsContinue+      else do+        ops <- concat <$> getBlockOperations blkId+        case find (\op -> boHash op == unOperationHash hash) ops of+          Just op -> do+            for_ (boContents op)+              \(OperationRespWithMeta{..}) -> case unOperationMetadata =<< orwmMetadata of+                Just res -> case res of+                  OperationApplied{} -> pass+                  OperationFailed errs -> throwM $ UnexpectedRunErrors errs+                Nothing -> pass+            pure $ MonitorHeadsStop hash+          Nothing -> error "impossible"  ---------------- -- Logging of requests and responses
src/Morley/Client/Full.hs view
@@ -37,8 +37,7 @@ -- | Run 'MorleyClientM' action within given t'MorleyClientEnv'. Retry action -- in case of invalid counter error. runMorleyClientM :: MorleyClientEnv -> MorleyClientM a -> IO a-runMorleyClientM env client =-  runReaderT (unMorleyClientM client) env+runMorleyClientM env client = runReaderT (unMorleyClientM client) env  instance HasLog MorleyClientEnv Message MorleyClientM where   getLogAction = mceLogAction@@ -50,12 +49,12 @@     case mceSecretKey env of       Just sk -> pure . SignatureEd25519 $ Ed25519.sign sk opHash       Nothing -> TezosClient.signBytes senderAlias mbPassword opHash-  waitForOperation = retryOnceOnTimeout ... TezosClient.waitForOperationInclusion   rememberContract = failOnTimeout ... TezosClient.rememberContract   importKey = failOnTimeout ... TezosClient.importKey   resolveAddressMaybe = retryOnceOnTimeout ... TezosClient.resolveAddressMaybe   getAlias = retryOnceOnTimeout ... TezosClient.getAlias   getPublicKey = retryOnceOnTimeout ... TezosClient.getPublicKey+  getSecretKey = retryOnceOnTimeout ... TezosClient.getSecretKey   -- This function doesn't perform any chain related operations with tezos-client,   -- so @ECONNRESET@ cannot appear here   getTezosClientConfig = do@@ -85,6 +84,8 @@   getBlockHeader = getBlockHeaderImpl   getBlockConstants = getBlockConstantsImpl   getBlockOperations = getBlockOperationsImpl+  getScriptSizeAtBlock = getScriptSizeAtBlockImpl+  getBlockOperationHashes = getBlockOperationHashesImpl   getProtocolParametersAtBlock = getProtocolParametersImpl   runOperationAtBlock = runOperationImpl   preApplyOperationsAtBlock = preApplyOperationsImpl@@ -100,3 +101,4 @@   runCodeAtBlock = runCodeImpl   getChainId = getChainIdImpl   getManagerKeyAtBlock = getManagerKeyImpl+  waitForOperation = (asks mceClientEnv >>=) . waitForOperationImpl
src/Morley/Client/Init.hs view
@@ -8,7 +8,6 @@   , mkLogAction      -- * Lens-  , mccAliasPrefixL   , mccEndpointUrlL   , mccTezosClientPathL   , mccMbTezosClientDataDirL@@ -31,9 +30,7 @@  -- | Data necessary for morley client initialization. data MorleyClientConfig = MorleyClientConfig-  { mccAliasPrefix :: Maybe Text-  -- ^ Optional prefix for aliases that will be passed to @tezos-client@.-  , mccEndpointUrl :: Maybe BaseUrl+  { mccEndpointUrl :: Maybe BaseUrl   -- ^ URL of tezos endpoint on which operations are performed   , mccTezosClientPath :: FilePath   -- ^ Path to @tezos-client@ binary through which operations are@@ -66,8 +63,7 @@   let     endpointUrl = fromMaybe tcEndpointUrl mccEndpointUrl     tezosClientEnv = TezosClientEnv-      { tceAliasPrefix = mccAliasPrefix-      , tceEndpointUrl = endpointUrl+      { tceEndpointUrl = endpointUrl       , tceTezosClientPath = tezosClientPath       , tceMbTezosClientDataDir = mccMbTezosClientDataDir       }
src/Morley/Client/Logging.hs view
@@ -16,13 +16,11 @@   , logWarning   , logError   , logException-   , logFlush   ) where  import Colog-  (LogAction(..), Message, WithLog, logDebug, logError, logException, logInfo, logWarning)-import System.IO (hFlush)+  (LogAction(..), Message, WithLog, logDebug, logError, logException, logFlush, logInfo, logWarning)  -- | 'LogAction' with fixed message parameter. type ClientLogAction m = LogAction m Message@@ -31,12 +29,3 @@ -- If we want to use another message type we can change this constraint -- and exported functions, presumably without breaking other code significantly. type WithClientLog env m = WithLog env Message m---- See <https://github.com/kowainik/co-log/pull/194>, hopefully we won't need it one day.-{- | This action can be used in combination with other actions to flush-   a handle every time you log anything.--}-logFlush :: MonadIO m => Handle -> LogAction m a-logFlush handle = LogAction $ const $ liftIO $ hFlush handle-{-# INLINE logFlush #-}-{-# SPECIALIZE logFlush :: Handle -> LogAction IO () #-}
src/Morley/Client/OnlyRPC.hs view
@@ -27,8 +27,8 @@ import Morley.Client.RPC.Class (HasTezosRpc(..)) import Morley.Client.RPC.HttpClient (newClientEnv) import Morley.Client.TezosClient.Class (HasTezosClient(..))-import Morley.Client.TezosClient.Types (AddressOrAlias(..), mkAlias) import Morley.Tezos.Address (Address, mkKeyAddress)+import Morley.Tezos.Address.Alias (AddressOrAlias(..), Alias(..)) import Morley.Tezos.Crypto (SecretKey, sign, toPublic)  ----------------@@ -77,12 +77,7 @@ -- | Run 'MorleyOnlyRpcM' action within given 'MorleyOnlyRpcEnv'. Retry action -- in case of invalid counter error. runMorleyOnlyRpcM :: MorleyOnlyRpcEnv -> MorleyOnlyRpcM a -> IO a-runMorleyOnlyRpcM env action =-  runReaderT (unMorleyOnlyRpcM (retryInvalidCounter action)) env-  where-    retryInvalidCounter a = a `catch` handleInvalidCounterRpc retryAction-      where-        retryAction = waitBeforeRetry >> retryInvalidCounter action+runMorleyOnlyRpcM env action = runReaderT (unMorleyOnlyRpcM action) env  ---------------- -- Exceptions@@ -125,11 +120,6 @@   -- In RPC-only mode we only use unencrypted in-memory passwords.   getKeyPassword _ = pure Nothing -  -- This method can be implemented if necessary by manually checking whether-  -- the operation is confirmed. For now we simply don't wait for confirmation-  -- in RPC-only mode.-  waitForOperation = \_ -> pass-   -- Stateful actions that simply do nothing because there is no persistent state.   rememberContract = \_ _ _ -> pass @@ -137,7 +127,7 @@   -- places and with an exception here it's not possible to send transactions.   -- So be aware of this and do not rely on this value!   -- TODO [#652]: consider using a `Map` instead-  getAlias _ = pure (mkAlias "MorleyOnlyRpc")+  getAlias _ = pure (Alias "MorleyOnlyRpc")    -- Actions that are not supported and simply throw exceptions.   genKey _ = throwM $ UnsupportedByOnlyRPC "genKey"@@ -146,6 +136,7 @@   revealKey _ _ = throwM $ UnsupportedByOnlyRPC "revealKey"   resolveAddressMaybe _ = throwM $ UnsupportedByOnlyRPC "resolveAddressMaybe"   getPublicKey _ = throwM $ UnsupportedByOnlyRPC "getPublicKey"+  getSecretKey _ = throwM $ UnsupportedByOnlyRPC "getSecretKey"   registerDelegate _ _ = throwM $ UnsupportedByOnlyRPC "registerDelegate"   getTezosClientConfig = throwM $ UnsupportedByOnlyRPC "getTezosClientConfig"   calcTransferFee _ _ _ _ = throwM $ UnsupportedByOnlyRPC "calcTransferFee"@@ -163,10 +154,12 @@   getBlockHeader = getBlockHeaderImpl   getBlockConstants = getBlockConstantsImpl   getBlockOperations = getBlockOperationsImpl+  getBlockOperationHashes = getBlockOperationHashesImpl   getProtocolParametersAtBlock = getProtocolParametersImpl   runOperationAtBlock = runOperationImpl   preApplyOperationsAtBlock = preApplyOperationsImpl   forgeOperationAtBlock = forgeOperationImpl+  getScriptSizeAtBlock = getScriptSizeAtBlockImpl   injectOperation = injectOperationImpl   getContractScriptAtBlock = getContractScriptImpl   getContractStorageAtBlock = getContractStorageAtBlockImpl@@ -178,3 +171,4 @@   runCodeAtBlock = runCodeImpl   getChainId = getChainIdImpl   getManagerKeyAtBlock = getManagerKeyImpl+  waitForOperation = (asks moreClientEnv >>=) . waitForOperationImpl
src/Morley/Client/Parser.hs view
@@ -6,6 +6,7 @@   , ClientArgsRaw (..)   , OriginateArgs (..)   , TransferArgs (..)+  , GetScriptSizeArgs (..)   , addressOrAliasOption   , clientConfigParser   , morleyClientInfo@@ -25,20 +26,21 @@ import Options.Applicative.Help.Pretty (Doc, linebreak) import Servant.Client (BaseUrl(..), parseBaseUrl) -import Morley.CLI+import Morley.CLI (addressOrAliasOption, mutezOption, parserInfo, valueOption) import Morley.Client.Init import Morley.Client.RPC.Types (BlockId(HeadId))-import Morley.Client.TezosClient.Types (AddressOrAlias, AliasHint) import Morley.Michelson.Untyped qualified as U+import Morley.Tezos.Address.Alias (AddressOrAlias, Alias(..)) import Morley.Tezos.Core import Morley.Util.CLI (mkCLOptionParser, mkCommandParser) import Morley.Util.Named  data ClientArgs-  = ClientArgs MorleyClientConfig Bool ClientArgsRaw+  = ClientArgs MorleyClientConfig ClientArgsRaw  data ClientArgsRaw   = Originate OriginateArgs+  | GetScriptSize GetScriptSizeArgs   | Transfer TransferArgs   | GetBalance AddressOrAlias   | GetBlockHeader BlockId@@ -46,13 +48,18 @@  data OriginateArgs = OriginateArgs   { oaMbContractFile :: Maybe FilePath-  , oaContractName   :: AliasHint+  , oaContractName   :: Alias   , oaInitialBalance :: Mutez   , oaInitialStorage :: U.Value   , oaOriginateFrom  :: AddressOrAlias   , oaMbFee :: Maybe Mutez   } +data GetScriptSizeArgs = GetScriptSizeArgs+  { ssScriptFile :: FilePath+  , ssStorage    :: U.Value+  }+ data TransferArgs = TransferArgs   { taSender      :: AddressOrAlias   , taDestination :: AddressOrAlias@@ -71,16 +78,11 @@  -- | Parser for the @morley-client@ executable. clientParser :: Opt.Parser ClientArgs-clientParser = ClientArgs <$> clientConfigParser (pure Nothing) <*> enableExtsOption <*> argsRawParser-  where-    enableExtsOption = Opt.switch $-      long "deprecated-morley-extensions" <>-      help "Enable parsing deprecated Morley extensions"+clientParser = ClientArgs <$> clientConfigParser <*> argsRawParser -clientConfigParser :: Opt.Parser (Maybe Text) -> Opt.Parser MorleyClientConfig-clientConfigParser prefixParser = do+clientConfigParser :: Opt.Parser MorleyClientConfig+clientConfigParser = do   let mccSecretKey = Nothing-  mccAliasPrefix <- prefixParser   mccEndpointUrl <- endpointOption   mccTezosClientPath <- pathOption   mccMbTezosClientDataDir <- dataDirOption@@ -123,14 +125,6 @@                       \By default fee will be computed automatically."             ) --- | Generic parser to read an option of 'AddressOrAlias' type.-addressOrAliasOption-  :: Maybe AddressOrAlias-  -> "name" :! String-  -> "help" :! String-  -> Opt.Parser AddressOrAlias-addressOrAliasOption = mkCLOptionParser- -- | Generic parser to read an option of 'BlockId' type. blockIdOption   :: Maybe BlockId@@ -144,6 +138,7 @@   [ originateCmd   , transferCmd   , getBalanceCmd+  , getScriptSizeCmd   , getBlockHeaderCmd   , getBlockOperationsCmd   ]@@ -180,6 +175,10 @@         (#help :! "Id of the block whose operations will be queried.")       )       "Get operations contained in a block"+    getScriptSizeCmd =+      mkCommandParser "compute-script-size"+      (GetScriptSize <$> getScriptSizeArgsOption)+      "Compute script size"  originateArgsOption :: Opt.Parser OriginateArgs originateArgsOption = do@@ -203,14 +202,25 @@   oaMbFee <- feeOption   pure $ OriginateArgs {..} +getScriptSizeArgsOption :: Opt.Parser GetScriptSizeArgs+getScriptSizeArgsOption = GetScriptSizeArgs <$> scriptFileOption+  <*> valueOption Nothing (#name :! "storage")+                          (#help :! "Contract storage value")+ mbContractFileOption :: Opt.Parser (Maybe FilePath) mbContractFileOption = optional . strOption $ mconcat   [ long "contract", metavar "FILEPATH"   , help "Path to contract file"   ] -contractNameOption :: Opt.Parser AliasHint-contractNameOption = strOption $ mconcat+scriptFileOption :: Opt.Parser FilePath+scriptFileOption = strOption $ mconcat+  [ long "script", metavar "FILEPATH"+  , help "Path to script file"+  ]++contractNameOption :: Opt.Parser Alias+contractNameOption = fmap Alias . strOption $ mconcat   [ long "contract-name"   , value "stdin"   , help "Alias of originated contract"
src/Morley/Client/RPC/API.hs view
@@ -6,12 +6,15 @@ module Morley.Client.RPC.API   ( NodeMethods (..)   , nodeMethods+  , monitorHeads   ) where  import Network.HTTP.Types.Status (Status(..)) import Servant.API-  (Capture, Get, JSON, Post, QueryParam, ReqBody, ToHttpApiData(..), (:<|>)(..), (:>))-import Servant.Client.Core (ResponseF(..), RunClient, clientIn, pattern FailureResponse)+  (Capture, Get, JSON, NewlineFraming, Post, QueryParam, ReqBody, SourceIO, StreamGet,+  ToHttpApiData(..), (:<|>)(..), (:>))+import Servant.Client.Core+  (ResponseF(..), RunClient, RunStreamingClient, clientIn, pattern FailureResponse)  import Morley.Client.RPC.QueryFixedParam import Morley.Client.RPC.Types@@ -44,6 +47,8 @@      Capture "block_id" BlockId :> "operations" :> Get '[JSON] [[BlockOperation]] :<|> +    Capture "block_id" BlockId :> "operation_hashes" :> Get '[JSON] [[OperationHash]] :<|>+     -- Despite this RPC is deprecated, it is said to be implemented quite sanely,     -- and also we were said that it is not going to be removed soon.     -- In babylonnet this entrypoint finds big_map with relevant key type and@@ -76,8 +81,15 @@     Capture "block_id" BlockId :> "context" :> "contracts"       :> Capture "contract" Address' :> "delegate" :> Get '[JSON] KeyHash :<|> +    Capture "block_id" BlockId :> "context" :> "contracts" :> Capture "address" Address' :> "manager_key"+      :> Get '[JSON] (Maybe PublicKey) :<|>+     -- POST +    -- Calculate script size with given storage.+    Capture "block_id" BlockId :> "helpers" :> "scripts" :> "script_size"+        :> ReqBody '[JSON] CalcSize :> Post '[JSON] ScriptSize :<|>+     -- Turn a structured representation of an operation into a     -- bytestring that can be submitted to the blockchain.     Capture "block_id" BlockId :> "helpers" :> "forge" :> "operations"@@ -93,10 +105,7 @@      -- Run contract with given parameter and storage.     Capture "block_id" BlockId :> "helpers" :> "scripts" :> "run_code"-      :> ReqBody '[JSON] RunCode :> Post '[JSON] RunCodeResult :<|>--    Capture "block_id" BlockId :> "context" :> "contracts" :> Capture "address" Address' :> "manager_key"-      :> Get '[JSON] (Maybe PublicKey)+      :> ReqBody '[JSON] RunCode :> Post '[JSON] RunCodeResult      ) :<|> @@ -109,6 +118,10 @@     :> ReqBody '[JSON] HexJSONByteString     :> Post '[JSON] OperationHash +type StreamingAPI =+  "monitor" :> "heads" :> "main"+    :> StreamGet NewlineFraming JSON (SourceIO BlockHeader)+ nodeAPI :: Proxy NodeAPI nodeAPI = Proxy @@ -121,11 +134,13 @@   , getBlockHeader :: BlockId -> m BlockHeader   , getProtocolParameters :: BlockId -> m ProtocolParameters   , getBlockOperations :: BlockId -> m [[BlockOperation]]+  , getBlockOperationHashes :: BlockId -> m [[OperationHash]]   , getBigMap :: BlockId -> Address -> GetBigMap -> m GetBigMapResult   , getBigMapValueAtBlock :: BlockId -> Natural -> Text -> m Expression   , getBigMapValuesAtBlock :: BlockId -> Natural -> Maybe Natural -> Maybe Natural -> m Expression   , getBalance :: BlockId -> Address -> m TezosMutez   , getDelegate :: BlockId -> Address -> m (Maybe KeyHash)+  , getScriptSizeAtBlock :: BlockId -> CalcSize -> m ScriptSize   , forgeOperation :: BlockId -> ForgeOperation -> m HexJSONByteString   , runOperation :: BlockId -> RunOperation -> m RunOperationResult   , preApplyOperations :: BlockId -> [PreApplyOperation] -> m [RunOperationResult]@@ -135,6 +150,10 @@   , injectOperation :: HexJSONByteString -> m OperationHash   } ++monitorHeads :: forall m. (RunStreamingClient m) => m (SourceIO BlockHeader)+monitorHeads = Proxy @StreamingAPI `clientIn` Proxy @m+ nodeMethods :: forall m. (MonadCatch m, RunClient m) => NodeMethods m nodeMethods = NodeMethods   { getCounter        = withAddress' getCounter'@@ -155,12 +174,29 @@   where     withAddress' f blockId = f blockId . Address'     getDelegate' :: BlockId -> Address' -> m KeyHash-    (getBlockHash :<|> getCounter' :<|> getScript' :<|> getStorageAtBlock' :<|> getBlockConstants :<|>-      getBlockHeader :<|> getProtocolParameters :<|> getBlockOperations :<|> getBigMap' :<|>-      getBigMapValueAtBlock :<|> getBigMapValuesAtBlock :<|> getBalance' :<|> getDelegate' :<|>-      forgeOperation :<|> runOperation :<|> preApplyOperations :<|> runCode :<|> getManagerKey') :<|>-      getChainId :<|> injectOperation =-      nodeAPI `clientIn` (Proxy @m)+    (getBlockHash+        :<|> getCounter'+        :<|> getScript'+        :<|> getStorageAtBlock'+        :<|> getBlockConstants+        :<|> getBlockHeader+        :<|> getProtocolParameters+        :<|> getBlockOperations+        :<|> getBlockOperationHashes+        :<|> getBigMap'+        :<|> getBigMapValueAtBlock+        :<|> getBigMapValuesAtBlock+        :<|> getBalance'+        :<|> getDelegate'+        :<|> getManagerKey'+        :<|> getScriptSizeAtBlock+        :<|> forgeOperation+        :<|> runOperation+        :<|> preApplyOperations+        :<|> runCode)+      :<|> getChainId+      :<|> injectOperation+      = nodeAPI `clientIn` (Proxy @m)  ---------------------------------------------------------------------------- -- Instances and helpers
src/Morley/Client/RPC/Class.hs view
@@ -19,7 +19,7 @@  -- | Type class that provides interaction with tezos node via RPC class (Monad m, MonadCatch m) => HasTezosRpc m where-  getBlockHash :: BlockId -> m Text+  getBlockHash :: BlockId -> m BlockHash   -- ^ Get hash of the given 'BlockId', mostly used to get hash of   -- 'HeadId'   getCounterAtBlock :: BlockId -> Address -> m TezosInt64@@ -27,10 +27,14 @@   -- and contract origination.   getBlockHeader :: BlockId -> m BlockHeader   -- ^ Get the whole header of a block.+  getScriptSizeAtBlock :: BlockId -> CalcSize -> m ScriptSize+  -- ^ Get the script size at block.   getBlockConstants :: BlockId -> m BlockConstants   -- ^ Get block constants that are required by other RPC calls.   getBlockOperations :: BlockId -> m [[BlockOperation]]   -- ^ Get all operations from the block with specified ID.+  getBlockOperationHashes :: BlockId -> m [[OperationHash]]+  -- ^ Get all operation hashes from the block with specified ID.   getProtocolParametersAtBlock :: BlockId -> m ProtocolParameters   -- ^ Get protocol parameters that are for limits calculations.   runOperationAtBlock :: BlockId -> RunOperation -> m RunOperationResult@@ -75,3 +79,7 @@   getManagerKeyAtBlock :: BlockId -> Address -> m (Maybe PublicKey)   -- ^ Get manager key for given address.   -- Returns @Nothing@ if this key wasn't revealed.+  waitForOperation :: m OperationHash -> m OperationHash+  -- ^ Blocks until an operation with the given hash is included into the chain.+  -- The first argument is the action that puts the operation on the chain.+  -- Returns the hash of the included operation.
src/Morley/Client/RPC/Error.hs view
@@ -7,6 +7,7 @@   , RunCodeErrors (..)   , UnexpectedErrors (..)   , IncorrectRpcResponse (..)+  , WaitForOperationError (..)   ) where  import Fmt (Buildable(..), blockListF, pretty, (+|), (|+))@@ -136,4 +137,18 @@       "No operations was run"  instance Exception IncorrectRpcResponse where+  displayException = pretty++data WaitForOperationError+  = WaitForOperationBlockout Word+  | WaitForOperationStreamingError Text+  deriving stock Show++instance Buildable WaitForOperationError where+  build = \case+    WaitForOperationBlockout n -> "Operation not included after " +| n |+ " blocks"+    WaitForOperationStreamingError s ->+      "Streaming error received waiting for operation: " +| s |+ ""++instance Exception WaitForOperationError where   displayException = pretty
src/Morley/Client/RPC/Getters.hs view
@@ -16,6 +16,7 @@   , getImplicitContractCounter   , getContractsParameterTypes   , getContractStorage+  , getScriptSize   , getBigMapValue   , getBigMapValues   , getHeadBlock@@ -175,6 +176,7 @@ getImplicitContractCounter addr = case addr of   KeyAddress _      -> getCounter addr   ContractAddress _ -> throwM $ ContractGetCounterAttempt addr+  TransactionRollupAddress _ -> throwM $ ContractGetCounterAttempt addr  handleStatusCode :: MonadCatch m => Int -> m a -> m a -> m a handleStatusCode code onError action = action `catch`@@ -194,6 +196,7 @@       -> m (Maybe (ContractHash, SomeParamType))     extractParameterType addr = case addr of       KeyAddress _ -> return Nothing+      TransactionRollupAddress _ -> return Nothing       ContractAddress ch ->         handleStatusCode 404 (return Nothing) $ do           params <- fmap (U.contractParameter) . throwLeft $@@ -215,7 +218,7 @@  -- | Get hash of the current head block, this head hash is used in other -- RPC calls.-getHeadBlock :: HasTezosRpc m => m Text+getHeadBlock :: HasTezosRpc m => m BlockHash getHeadBlock = getBlockHash HeadId  -- | 'getCounterAtBlock' applied to the head block.@@ -249,6 +252,10 @@ -- | 'getBalanceAtBlock' applied to the head block. getBalance :: HasTezosRpc m => Address -> m Mutez getBalance = getBalanceAtBlock HeadId++-- | 'getScriptSizeAtBlock' applied to the head block.+getScriptSize :: HasTezosRpc m => CalcSize -> m ScriptSize+getScriptSize = getScriptSizeAtBlock HeadId  -- | 'getDelegateAtBlock' applied to the head block. getDelegate :: HasTezosRpc m => Address -> m (Maybe KeyHash)
src/Morley/Client/RPC/QueryFixedParam.hs view
@@ -5,7 +5,9 @@   ( QueryFixedParam   ) where -import Servant.API (ToHttpApiData(toQueryParam), type (:>))+import Data.ByteString.Builder qualified as Builder+import Data.ByteString.Lazy qualified as LBS+import Servant.API (ToHttpApiData(..), type (:>)) import Servant.Client.Core (HasClient(..), appendToQueryString)  import Morley.Util.TypeLits (KnownSymbol, Symbol, symbolValT')@@ -16,11 +18,16 @@  instance (KnownSymbol sym, KnownSymbol val, HasClient m api)       => HasClient m (QueryFixedParam sym val :> api) where+   type Client m (QueryFixedParam sym val :> api) = Client m api+   clientWithRoute pm Proxy req =     clientWithRoute pm (Proxy :: Proxy api)-      $ appendToQueryString pname (Just $ toQueryParam pval) req+      $ appendToQueryString pname (Just $ encodeQueryParamValue pval) req     where       pname = symbolValT' @sym       pval  = symbolValT' @val+      -- Lifted from the unreleased https://github.com/haskell-servant/servant/pull/1549+      encodeQueryParamValue = LBS.toStrict . Builder.toLazyByteString . toEncodedUrlPiece+   hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy api) f cl
src/Morley/Client/RPC/Types.hs view
@@ -25,12 +25,16 @@   , CommonOperationData (..)   , ForgeOperation (..)   , GetBigMap (..)+  , CalcSize(..)+  , ScriptSize(..)   , GetBigMapResult (..)   , InternalOperation (..)   , OperationContent (..)   , OperationHash (..)-  , OperationInput (..)+  , OperationInput   , OperationResp (..)+  , OperationRespWithMeta (..)+  , OperationMetadata (..)   , OperationResult (..)   , OriginationOperation (..)   , OriginationScript (..)@@ -46,7 +50,8 @@   , RunOperationResult (..)   , RPCInput   , TransactionOperation (..)-  , combineResults+  , WithCommonOperationData (..)+  , MonitorHeadsStep(..)   , mkCommonOperationData    -- * Errors@@ -72,13 +77,14 @@   , _GasExhaustedOperation    -- * Lenses-  , oiCommonDataL+  , wcoCommonDataL   ) where -import Control.Lens (makeLensesFor, makePrisms)+import Control.Lens (makePrisms) import Data.Aeson-  (FromJSON(..), Object, ToJSON(..), Value(..), object, omitNothingFields, withObject, (.!=), (.:),-  (.:?), (.=))+  (FromJSON(..), Key, Object, ToJSON(..), Value(..), object, omitNothingFields, withObject, (.!=),+  (.:), (.:?), (.=))+import Data.Aeson.Key qualified as Key (toText) import Data.Aeson.TH (deriveFromJSON, deriveJSON, deriveToJSON) import Data.Default (Default(..)) import Data.Fixed (Milli)@@ -92,8 +98,8 @@ import Morley.Client.RPC.Aeson (morleyClientAesonOptions) import Morley.Client.Types import Morley.Micheline-  (Expression(..), MichelinePrimAp(..), MichelinePrimitive(..), StringEncode(..), TezosInt64,-  TezosMutez(..), TezosNat)+  (Expression, MichelinePrimAp(..), MichelinePrimitive(..), StringEncode(..), TezosInt64,+  TezosMutez(..), TezosNat, expressionPrim) import Morley.Tezos.Address (Address) import Morley.Tezos.Core (Mutez, tz, zeroMutez) import Morley.Tezos.Crypto (PublicKey, Signature, decodeBase58CheckWithPrefix, formatSignature)@@ -113,45 +119,19 @@   type OriginationInfo RPCInput = OriginationOperation   type RevealInfo RPCInput = RevealOperation -instance ToJSON (OperationInfo RPCInput) where-  toJSON = \case-    OpTransfer op -> toJSON op-    OpOriginate op -> toJSON op-    OpReveal op -> toJSON op--data OperationInput = OperationInput-  { oiCommonData :: CommonOperationData-  , oiCustom :: OperationInfo RPCInput-  }--instance ToJSON OperationInput where-  toJSON OperationInput{..} =-    toJSON oiCommonData `mergeObjects` toJSON oiCustom+type OperationInput = WithCommonOperationData (OperationInfo RPCInput)  data ForgeOperation = ForgeOperation-  { foBranch :: Text+  { foBranch :: BlockHash   , foContents :: NonEmpty OperationInput   } -instance ToJSON ForgeOperation where-  toJSON ForgeOperation{..} = object-    [ "branch" .= toString foBranch-    , "contents" .= foContents-    ]- data RunOperationInternal = RunOperationInternal-  { roiBranch :: Text+  { roiBranch :: BlockHash   , roiContents :: NonEmpty OperationInput   , roiSignature :: Signature   } -instance ToJSON RunOperationInternal where-  toJSON RunOperationInternal{..} = object-    [ "branch" .= toString roiBranch-    , "contents" .= roiContents-    , "signature" .= roiSignature-    ]- data RunOperation = RunOperation   { roOperation :: RunOperationInternal   , roChainId :: Text@@ -159,19 +139,11 @@  data PreApplyOperation = PreApplyOperation   { paoProtocol :: Text-  , paoBranch :: Text+  , paoBranch :: BlockHash   , paoContents :: NonEmpty OperationInput   , paoSignature :: Signature   } -instance ToJSON PreApplyOperation where-  toJSON PreApplyOperation{..} = object-    [ "branch" .= toString paoBranch-    , "contents" .= paoContents-    , "protocol" .= toString paoProtocol-    , "signature" .= formatSignature paoSignature-    ]- data RunOperationResult = RunOperationResult   { rrOperationContents :: NonEmpty OperationContent   }@@ -233,7 +205,7 @@   }  newtype BlockHash = BlockHash { unBlockHash :: Text }-  deriving newtype (ToJSON, FromJSON)+  deriving newtype (Eq, Ord, Show, Buildable, ToJSON, FromJSON, ToHttpApiData)  data FeeConstants = FeeConstants   { fcBase :: Mutez@@ -262,7 +234,7 @@   -- ^ Identifier referring to the genesis block.   | LevelId Natural   -- ^ Identifier referring to a block by its level.-  | BlockHashId Text+  | BlockHashId BlockHash   -- ^ Idenfitier referring to a block by its hash in Base58Check notation.   | AtDepthId Natural   -- ^ Identifier of a block at specific depth relative to @head@.@@ -296,7 +268,7 @@   | Right lvl <- readEither t = Just (LevelId lvl)   | Just depthTxt <- "head~" `T.stripPrefix` t   , Right depth <- readEither depthTxt = Just (AtDepthId depth)-  | Right _ <- decodeBase58CheckWithPrefix blockPrefix t = Just (BlockHashId t)+  | Right _ <- decodeBase58CheckWithPrefix blockPrefix t = Just (BlockHashId (BlockHash t))   | otherwise = Nothing  -- A magic prefix used by Tezos for block hashes@@ -363,6 +335,7 @@   | BalanceTooLow ("balance" :! Mutez) ("required" :! Mutez)   | PreviouslyRevealedKey Address   | NonExistingContract Address+  | InvalidB58Check Text   deriving stock Show  instance FromJSON RunError where@@ -417,6 +390,8 @@           PreviouslyRevealedKey <$> o .: "contract"       x | "non_existing_contract" `isSuffixOf` x ->           NonExistingContract <$> o .: "contract"+      x | "invalid_b58check" `isSuffixOf` x ->+          InvalidB58Check <$> o .: "input"       _ -> fail ("unknown id: " <> id')  instance Buildable RunError where@@ -474,6 +449,8 @@       "Key for " +| addr |+ " has already been revealed"     NonExistingContract addr ->       "Contract is not registered: " +| addr |+ ""+    InvalidB58Check input ->+      "Failed to read a valid b58check_encoding data from \"" +| input |+ "\""  -- | Errors that are sent as part of an "Internal Server Error" -- response (HTTP code 500).@@ -518,11 +495,11 @@       "failure" -> Failure <$> o .: "msg"       x -> fail ("unknown id: " <> x)     where-      parseCounter :: Object -> Text -> Parser Word+      parseCounter :: Object -> Key -> Parser Word       parseCounter o fieldName = do         fieldValue <- o .: fieldName         let mCounter = fromIntegralMaybe fieldValue-        maybe (fail $ mkErrorMsg fieldName fieldValue) pure mCounter+        maybe (fail $ mkErrorMsg (Key.toText fieldName) fieldValue) pure mCounter        mkErrorMsg :: Text -> TezosInt64 -> String       mkErrorMsg fieldName fieldValue = toString $ unwords@@ -556,17 +533,6 @@ instance Monoid AppliedResult where   mempty = AppliedResult 0 0 0 [] 0 -combineResults :: OperationResult -> OperationResult -> OperationResult-combineResults-  (OperationApplied res1) (OperationApplied res2) =-  OperationApplied $ res1 <> res2-combineResults (OperationApplied _) (OperationFailed e) =-  OperationFailed e-combineResults (OperationFailed e) (OperationApplied _) =-  OperationFailed e-combineResults (OperationFailed e1) (OperationFailed e2) =-  OperationFailed $ e1 <> e2- instance FromJSON OperationResult where   parseJSON = withObject "operation_costs" $ \o -> do     status <- o .: "status"@@ -598,7 +564,7 @@ defaultParametersInternal :: ParametersInternal defaultParametersInternal = ParametersInternal   { piEntrypoint = "default"-  , piValue = ExpressionPrim MichelinePrimAp+  , piValue = expressionPrim MichelinePrimAp     { mpaPrim = MichelinePrimitive "Unit"     , mpaArgs = []     , mpaAnnots = []@@ -649,6 +615,19 @@     codStorageLimit <- o .: "storage_limit"     pure CommonOperationData {..} +-- | Some operation data accompanied with common data.+data WithCommonOperationData a = WithCommonOperationData+  { wcoCommon :: CommonOperationData+  , wcoCustom :: a+  }++instance ToJSONObject a => ToJSON (WithCommonOperationData a) where+  toJSON (WithCommonOperationData common custom) =+    toJSON common `mergeObjects` toJSON custom++instance FromJSON a => FromJSON (WithCommonOperationData a) where+  parseJSON v = WithCommonOperationData <$> parseJSON v <*> parseJSON v+ -- | All the data needed to perform a transaction through -- Tezos RPC interface. -- For additional information, please refer to RPC documentation@@ -659,21 +638,6 @@   , toParameters :: ParametersInternal   } -instance ToJSON TransactionOperation where-  toJSON TransactionOperation{..} = object $-    [ "kind" .= String "transaction"-    , "amount" .= toAmount-    , "destination" .= toDestination-    , "parameters" .= toParameters-    ]--instance FromJSON TransactionOperation where-  parseJSON = withObject "TransactionOperation" $ \obj -> do-    toAmount <- obj .: "amount"-    toDestination <- obj .: "destination"-    toParameters <- fromMaybe defaultParametersInternal <$> obj .:? "parameters"-    pure TransactionOperation {..}- data OriginationScript = OriginationScript   { osCode :: Expression   , osStorage :: Expression@@ -686,13 +650,6 @@   , ooScript :: OriginationScript   } -instance ToJSON OriginationOperation where-  toJSON OriginationOperation{..} = object $-    [ "kind" .= String "origination"-    , "balance" .= ooBalance-    , "script" .= ooScript-    ]- -- | All the data needed to perform key revealing -- through Tezos RPC interface data RevealOperation = RevealOperation@@ -704,27 +661,32 @@     [ "kind" .= String "reveal"     , "public_key" .= roPublicKey     ]+instance ToJSONObject RevealOperation  -- | @$operation@ in Tezos docs. data BlockOperation = BlockOperation   { boHash :: Text-  , boContents :: [OperationResp]+  , boContents :: [OperationRespWithMeta]   }  -- | Contents of an operation that can appear in RPC responses. data OperationResp-  = TransactionOpResp TransactionOperation+  = TransactionOpResp (WithCommonOperationData TransactionOperation)   -- ^ Operation with kind @transaction@.   | OtherOpResp   -- ^ Operation with kind that we don't support yet (but need to parse to something). -instance FromJSON OperationResp where-  parseJSON = withObject "OperationResp" $ \obj -> do-    kind :: Text <- obj .: "kind"-    case kind of-      "transaction" -> TransactionOpResp <$> parseJSON (Object obj)-      _ -> pure OtherOpResp+data OperationRespWithMeta = OperationRespWithMeta+  { orwmResponse :: OperationResp+  , orwmMetadata :: Maybe OperationMetadata+  } +newtype OperationMetadata = OperationMetadata { unOperationMetadata :: Maybe OperationResult }++instance FromJSON OperationMetadata where+  parseJSON = withObject "operationMetadata" $ \o ->+    OperationMetadata <$> o .:? "operation_result"+ data GetBigMap = GetBigMap   { bmKey :: Expression   , bmType :: Expression@@ -742,6 +704,8 @@   , rcAmount :: TezosMutez   , rcBalance :: TezosMutez   , rcChainId :: Text+  , rcNow :: Maybe TezosNat+  , rcLevel :: Maybe TezosNat   , rcSource :: Maybe Address   , rcPayer :: Maybe Address   }@@ -754,13 +718,84 @@   { rcrStorage :: Expression   } +newtype ScriptSize = ScriptSize { ssScriptSize :: Natural }++data CalcSize = CalcSize+  { csProgram :: Expression+  , csStorage :: Expression+  , csGas     :: TezosInt64+  , csLegacy  :: Bool+  }++data MonitorHeadsStep a = MonitorHeadsStop a | MonitorHeadsContinue+ deriveJSON morleyClientAesonOptions ''ParametersInternal++instance ToJSON TransactionOperation where+  toJSON TransactionOperation{..} = object $+    [ "kind" .= String "transaction"+    , "amount" .= toAmount+    , "destination" .= toDestination+    , "parameters" .= toParameters+    ]+instance ToJSONObject TransactionOperation++instance FromJSON TransactionOperation where+  parseJSON = withObject "TransactionOperation" $ \obj -> do+    toAmount <- obj .: "amount"+    toDestination <- obj .: "destination"+    toParameters <- fromMaybe defaultParametersInternal <$> obj .:? "parameters"+    pure TransactionOperation {..}++instance FromJSON OperationResp where+  parseJSON = withObject "OperationResp" $ \obj -> do+    kind :: Text <- obj .: "kind"+    case kind of+      "transaction" -> TransactionOpResp <$> parseJSON (Object obj)+      _ -> pure OtherOpResp++instance FromJSON OperationRespWithMeta where+  parseJSON = withObject "OperationRespWithMeta" $ \obj -> do+    OperationRespWithMeta <$> parseJSON (Object obj) <*> obj .:? "metadata"+ deriveToJSON morleyClientAesonOptions ''OriginationScript++instance ToJSON OriginationOperation where+  toJSON OriginationOperation{..} = object $+    [ "kind" .= String "origination"+    , "balance" .= ooBalance+    , "script" .= ooScript+    ]+instance ToJSONObject OriginationOperation++instance ToJSON ForgeOperation where+  toJSON ForgeOperation{..} = object+    [ "branch" .= unBlockHash foBranch+    , "contents" .= foContents+    ]++instance ToJSON RunOperationInternal where+  toJSON RunOperationInternal{..} = object+    [ "branch" .= unBlockHash roiBranch+    , "contents" .= roiContents+    , "signature" .= roiSignature+    ]++instance ToJSON PreApplyOperation where+  toJSON PreApplyOperation{..} = object+    [ "branch" .= unBlockHash paoBranch+    , "contents" .= paoContents+    , "protocol" .= paoProtocol+    , "signature" .= formatSignature paoSignature+    ]+ deriveToJSON morleyClientAesonOptions ''RunOperation deriveToJSON morleyClientAesonOptions ''GetBigMap+deriveToJSON morleyClientAesonOptions ''CalcSize deriveToJSON morleyClientAesonOptions{omitNothingFields = True} ''RunCode-deriveFromJSON morleyClientAesonOptions ''BlockConstants deriveFromJSON morleyClientAesonOptions ''BlockHeaderNoHash+deriveFromJSON morleyClientAesonOptions ''ScriptSize+deriveFromJSON morleyClientAesonOptions ''BlockConstants deriveJSON morleyClientAesonOptions ''BlockHeader deriveFromJSON morleyClientAesonOptions ''ProtocolParameters deriveFromJSON morleyClientAesonOptions ''BlockOperation@@ -771,4 +806,7 @@   parseJSON v = maybe GetBigMapNotFound GetBigMapResult <$> parseJSON v  makePrisms ''RunError-makeLensesFor [("oiCommonData", "oiCommonDataL")] ''OperationInput++wcoCommonDataL :: Lens' (WithCommonOperationData a) CommonOperationData+wcoCommonDataL = \f (WithCommonOperationData com cust) ->+  (`WithCommonOperationData` cust) <$> f com
src/Morley/Client/TezosClient/Class.hs view
@@ -10,34 +10,32 @@  import Data.ByteArray (ScrubbedBytes) -import Morley.Client.RPC.Types import Morley.Client.TezosClient.Types import Morley.Micheline import Morley.Michelson.Typed.Scope import Morley.Tezos.Address+import Morley.Tezos.Address.Alias (AddressOrAlias, Alias) import Morley.Tezos.Crypto  -- | Type class that provides interaction with @tezos-client@ binary class (Monad m) => HasTezosClient m where   signBytes :: AddressOrAlias -> Maybe ScrubbedBytes -> ByteString -> m Signature   -- ^ Sign an operation with @tezos-client@.-  genKey :: AliasOrAliasHint -> m Address+  genKey :: Alias -> m Address   -- ^ Generate a secret key and store it with given alias.   -- If a key with this alias already exists, the corresponding address   -- will be returned and no state will be changed.-  genFreshKey :: AliasOrAliasHint -> m Address+  genFreshKey :: Alias -> m Address   -- ^ Generate a secret key and store it with given alias.   -- Unlike 'genKey' this function overwrites   -- the existing key when given alias is already stored.   revealKey :: Alias -> Maybe ScrubbedBytes -> m ()   -- ^ Reveal public key associated with given implicit account.-  waitForOperation :: OperationHash -> m ()-  -- ^ Wait until operation known by some hash is included into the chain.-  rememberContract :: Bool -> Address -> AliasOrAliasHint -> m ()+  rememberContract :: Bool -> Address -> Alias -> m ()   -- ^ Associate the given contract with alias.   -- The 'Bool' variable indicates whether or not we should replace already   -- existing contract alias or not.-  importKey :: Bool -> AliasOrAliasHint -> SecretKey -> m Alias+  importKey :: Bool -> Alias -> SecretKey -> m Alias   -- ^ Saves 'SecretKey' via @tezos-client@ with given alias or hint associated.   -- The 'Bool' variable indicates whether or not we should replace already   -- existing alias key or not.@@ -53,7 +51,9 @@   getPublicKey :: AddressOrAlias -> m PublicKey   -- ^ Get public key for given address. Public keys are often used when interacting   -- with the multising contracts-  registerDelegate :: AliasOrAliasHint -> Maybe ScrubbedBytes -> m ()+  getSecretKey :: AddressOrAlias -> m SecretKey+  -- ^ Get secret key for given address.+  registerDelegate :: Alias -> Maybe ScrubbedBytes -> m ()   -- ^ Register a given address as delegate   getTezosClientConfig :: m TezosClientConfig   -- ^ Retrieve the current @tezos-client@ config.
src/Morley/Client/TezosClient/Impl.hs view
@@ -8,7 +8,6 @@    -- * @tezos-client@ api   , signBytes-  , waitForOperationInclusion   , rememberContract   , importKey   , genKey@@ -18,6 +17,7 @@   , resolveAddress   , getAlias   , getPublicKey+  , getSecretKey   , getTezosClientConfig   , calcTransferFee   , calcOriginationFee@@ -28,8 +28,6 @@   -- * Internals   , callTezosClient   , callTezosClientStrict-  , prefixName-  , prefixNameM   ) where  import Unsafe qualified ((!!))@@ -56,6 +54,7 @@ import Morley.Micheline import Morley.Michelson.Typed.Scope import Morley.Tezos.Address+import Morley.Tezos.Address.Alias (AddressOrAlias(..), Alias(..)) import Morley.Tezos.Crypto import Morley.Util.Peano import Morley.Util.SizedList.Types@@ -212,10 +211,9 @@ genKey   :: ( MonadThrow m, MonadCatch m, WithClientLog env m, HasTezosClientEnv env, MonadIO m      , Class.HasTezosClient m)-  => AliasOrAliasHint+  => Alias   -> m Address-genKey originatorAlias = do-  name <- prefixNameM originatorAlias+genKey name = do   let     isAlreadyExistsError :: Text -> Bool     -- We can do a bit better here using more complex parsing if necessary.@@ -234,10 +232,9 @@ genFreshKey   :: ( MonadThrow m, MonadCatch m, WithClientLog env m, HasTezosClientEnv env, MonadIO m      , Class.HasTezosClient m)-  => AliasOrAliasHint+  => Alias   -> m Address-genFreshKey originatorAlias = do-  name <- prefixNameM originatorAlias+genFreshKey name = do   let     isNoAliasError :: Text -> Bool     -- We can do a bit better here using more complex parsing if necessary.@@ -279,11 +276,10 @@ -- | Register alias as delegate registerDelegate   :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m)-  => AliasOrAliasHint+  => Alias   -> Maybe ScrubbedBytes   -> m ()-registerDelegate addressOrAliasHint mbPassword = do-  alias <- prefixNameM addressOrAliasHint+registerDelegate alias mbPassword = do   logDebug $ "Registering " +| alias |+ " as delegate"   let     emptyImplicitContract = T.isInfixOf "Empty implicit contract"@@ -308,7 +304,7 @@   AddressAlias originatorName -> do     logDebug $ "Resolving " +| originatorName |+ ""     output <- callTezosClientStrict ["list", "known", "contracts"] MockupMode Nothing-    let parse = T.stripPrefix (unsafeGetAliasText originatorName <> ": ")+    let parse = T.stripPrefix (unAlias originatorName <> ": ")     liftIO case safeHead . mapMaybe parse . lines $ output of       Nothing -> pure Nothing       Just addrText ->@@ -328,7 +324,7 @@     let parse = T.stripSuffix (": " <> pretty senderAddress)     liftIO case safeHead . mapMaybe parse . lines $ output of       Nothing -> throwM $ UnknownAddress senderAddress-      Just alias -> pure (mkAlias alias)+      Just alias -> pure (Alias alias)  -- | Return 'PublicKey' corresponding to given 'AddressOrAlias'. getPublicKey@@ -348,19 +344,23 @@         parsePublicKey pkText     _ -> throwM $ TezosClientUnexpectedOutputFormat output --- | This function blocks until operation with given hash is included into blockchain.-waitForOperationInclusion+-- | Return 'SecretKey' corresponding to given 'AddressOrAlias'.+getSecretKey   :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m)-  => OperationHash-  -> m ()-waitForOperationInclusion op = void do-  logDebug $ "Waiting for operation " +| op |+ " to be included..."-  callTezosClient errHandler-    ["wait", "for", toCmdArg op, "to", "be", "included"] ClientMode Nothing-  where-    errHandler _ errOutput =-      False <$ when ("Invalid operation hash:" `T.isInfixOf` errOutput)-      (throwM $ InvalidOperationHash op)+  => AddressOrAlias+  -> m SecretKey+getSecretKey addrOrAlias = do+  alias <- getAlias addrOrAlias+  logDebug $ "Getting " +| alias |+ " secret key"+  output <- callTezosClientStrict ["show", "address", toCmdArg alias, "--show-secret"] MockupMode Nothing+  liftIO case lines output of+    _ : _ : [rawSK] -> do+      skText <- maybe+        (throwM $ TezosClientUnexpectedOutputFormat rawSK) pure+        (T.stripPrefix "Secret Key: " rawSK)+      either (throwM . TezosClientCryptoParseError skText) pure $+        parseSecretKey skText+    _ -> throwM $ TezosClientUnexpectedOutputFormat output  -- | Save a contract with given address and alias. -- If @replaceExisting@ is @False@ and a contract with given alias@@ -369,10 +369,9 @@   :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m)   => Bool   -> Address-  -> AliasOrAliasHint+  -> Alias   -> m ()-rememberContract replaceExisting contractAddress newAlias = do-  name <- prefixNameM newAlias+rememberContract replaceExisting contractAddress name = do   let     isAlreadyExistsError = T.isInfixOf "already exists"     errHandler _ errOut = pure (isAlreadyExistsError errOut)@@ -386,11 +385,10 @@ importKey   :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m)   => Bool-  -> AliasOrAliasHint+  -> Alias   -> SecretKey   -> m Alias-importKey replaceExisting alias key = do-  name <- prefixNameM alias+importKey replaceExisting name key = do   let     isAlreadyExistsError = T.isInfixOf "already exists"     errHandler _ errOut = pure (isAlreadyExistsError errOut)@@ -630,22 +628,6 @@     errorMsg =       "ERROR!! There was an error in executing `" <> toText fp <> "` program. Is the \       \ executable available in PATH ?"--prefixName :: Maybe Text -> AliasOrAliasHint -> Alias-prefixName _ (AnAlias x) = x-prefixName mPrefix (AnAliasHint (unsafeGetAliasHintText -> hint)) =-  mkAlias $ case mPrefix of-    Just prefix -> prefix <> "." <> hint-    Nothing -> hint---- | Prefix an alias with the value available in any 'HasTezosClientEnv'.-prefixNameM-  :: (HasTezosClientEnv env, MonadReader env m)-  => AliasOrAliasHint-  -> m Alias-prefixNameM alias = do-  prefix <- tceAliasPrefix <$> view tezosClientEnvL-  pure $ prefixName prefix alias  -- | Return 'Address' corresponding to given 'AddressOrAlias'. resolveAddress
src/Morley/Client/TezosClient/Types.hs view
@@ -5,10 +5,6 @@  module Morley.Client.TezosClient.Types   ( CmdArg (..)-  , Alias-  , AliasHint-  , AliasOrAliasHint (..)-  , AddressOrAlias (..)   , addressResolved   , CalcOriginationFeeData (..)   , CalcTransferFeeData (..)@@ -17,16 +13,7 @@   , HasTezosClientEnv (..)   , SecretKeyEncryption (..) -  -- * Unsafe coercions-  , unsafeCoerceAliasHintToAlias-  , unsafeCoerceAliasToAliasHint-  , unsafeGetAliasText-  , unsafeGetAliasHintText-  , mkAlias-  , mkAliasHint-   -- * Lens-  , tceAliasPrefixL   , tceEndpointUrlL   , tceTezosClientPathL   , tceMbTezosClientDataDirL@@ -34,11 +21,9 @@  import Data.Aeson (FromJSON(..), KeyValue(..), ToJSON(..), object, withObject, (.:)) import Data.ByteArray (ScrubbedBytes)-import Data.Coerce (coerce) import Data.Fixed (E6, Fixed(..)) import Fmt (Buildable(..), pretty) import Morley.Util.Lens (makeLensesWith, postfixLFields)-import Options.Applicative qualified as Opt import Servant.Client (BaseUrl(..), showBaseUrl) import Text.Hex (encodeHex) @@ -49,10 +34,10 @@ import Morley.Michelson.Printer import Morley.Michelson.Typed (Contract, EpName, Value) import Morley.Michelson.Typed qualified as T-import Morley.Tezos.Address (Address, parseAddress)+import Morley.Tezos.Address (Address)+import Morley.Tezos.Address.Alias (AddressOrAlias(..), Alias) import Morley.Tezos.Core import Morley.Tezos.Crypto-import Morley.Util.CLI (HasCLReader(..))  -- | An object that can be put as argument to a tezos-client command-line call. class CmdArg a where@@ -92,84 +77,14 @@  instance CmdArg OperationHash --- | @tezos-client@ can associate addresses with textual aliases.--- This type denotes such an alias.-newtype Alias = Alias-  { unsafeGetAliasText :: Text-    -- ^ Unsafely extract 'Text' from 'Alias'. Do NOT use the result with-    -- 'mkAliasHint'.-  }-  deriving stock (Show, Eq, Ord)-  deriving newtype (Buildable, CmdArg)---- | A hint for constructing an alias when generating an address or--- remembering a contract.------ Resulting 'Alias' most likely will differ from this as we tend to prefix--- aliases, but a user should be able to recognize your alias visually.--- For instance, passing @"alice"@ as a hint may result into @"myTest.alice"@--- alias being created.-newtype AliasHint = AliasHint-  { unsafeGetAliasHintText :: Text-    -- ^ Unsafely extract 'Text' from 'AliasHint'. Do NOT use the result with-    -- 'mkAlias'.-  }-  deriving stock (Show)-  deriving newtype (IsString, Buildable, Semigroup, Monoid)---- | Coerce 'Alias' to 'AliasHint'. Unless you know for a fact that prefix is empty,--- this is unsafe.-unsafeCoerceAliasToAliasHint :: Alias -> AliasHint-unsafeCoerceAliasToAliasHint = coerce---- | Coerce 'AliasHint' to 'Alias'. Unless you know for a fact that prefix is empty,--- this is unsafe.-unsafeCoerceAliasHintToAlias :: AliasHint -> Alias-unsafeCoerceAliasHintToAlias = coerce---- | Make 'Alias' from 'Text'-mkAlias :: Text -> Alias-mkAlias = Alias---- | Make 'AliasHint' from 'Text'-mkAliasHint :: Text -> AliasHint-mkAliasHint = AliasHint---- | Either an 'Alias', or an 'AliasHint'. The difference is that 'AliasHint' needs to be--- prefixed (if alias prefix is non-empty), while 'Alias' doesn't.-data AliasOrAliasHint-  = AnAlias Alias-  | AnAliasHint AliasHint-  deriving stock (Show)---- | Representation of an address that @tezos-client@ uses. It can be--- an address itself or a textual alias.-data AddressOrAlias-  = AddressResolved Address-  -- ^ Address itself, can be used as is.-  | AddressAlias Alias-  -- ^ Address alias, should be resolved by @tezos-client@.-  deriving stock (Show, Eq, Ord)+instance CmdArg Alias where  instance CmdArg AddressOrAlias where -instance HasCLReader AddressOrAlias where-  getReader =-    Opt.str <&> \addrOrAlias ->-      case parseAddress addrOrAlias of-        Right addr -> AddressResolved addr-        Left _ -> AddressAlias (Alias addrOrAlias)-  getMetavar = "ADDRESS OR ALIAS"- -- | Creates an 'AddressOrAlias' with the given address. addressResolved :: ToAddress addr => addr -> AddressOrAlias addressResolved = AddressResolved . toAddress -instance Buildable AddressOrAlias where-  build = \case-    AddressResolved addr -> build addr-    AddressAlias alias -> build alias- -- | Representation of address secret key encryption type data SecretKeyEncryption   = UnencryptedKey@@ -189,15 +104,7 @@  -- | Runtime environment for @tezos-client@ bindings. data TezosClientEnv = TezosClientEnv-  { tceAliasPrefix :: Maybe Text-  -- ^ Optional prefix for aliases that will be passed to @tezos-client@.-  -- If you call some function and pass @foo@ 'Alias' to it when the prefix-  -- is provided, it will be prepened to @foo@. So @prefix.foo@ will be passed-  -- to @tezos-client@. Note that the prefix will be only applied in functions-  -- such as 'Morley.Client.TezosClient.Class.genKey' and-  -- 'Morley.Client.TezosClient.Class.rememberContract' that work directly-  -- with @tezos-client@ contract cache and add addresses to it.-  , tceEndpointUrl :: BaseUrl+  { tceEndpointUrl :: BaseUrl   -- ^ URL of tezos node on which operations are performed.   , tceTezosClientPath :: FilePath   -- ^ Path to tezos client binary through which operations are
src/Morley/Client/Types.hs view
@@ -2,7 +2,8 @@ -- SPDX-License-Identifier: LicenseRef-MIT-OA  module Morley.Client.Types-  ( OperationInfoDescriptor (..)+  ( ToJSONObject+  , OperationInfoDescriptor (..)   , OperationInfo (..)   , _OpTransfer   , _OpOriginate@@ -10,7 +11,11 @@   ) where  import Control.Lens (makePrisms)+import Data.Aeson (ToJSON(..)) +-- | Designates types whose 'ToJSON' instance produces only 'Data.Aeson.Object's.+class ToJSON a => ToJSONObject a+ class OperationInfoDescriptor (i :: Type) where   type family TransferInfo i :: Type   type family OriginationInfo i :: Type@@ -20,5 +25,16 @@   = OpTransfer (TransferInfo i)   | OpOriginate (OriginationInfo i)   | OpReveal (RevealInfo i)++-- Requiring 'ToJSONObject' in superclass as those different types of operation+-- must be distinguishable and that is usually done by a special field+instance+  Each '[ToJSONObject] [TransferInfo i, OriginationInfo i, RevealInfo i] =>+  ToJSON (OperationInfo i) where+  toJSON = \case+    OpTransfer op -> toJSON op+    OpOriginate op -> toJSON op+    OpReveal op -> toJSON op+instance ToJSON (OperationInfo i) => ToJSONObject (OperationInfo i)  makePrisms ''OperationInfo
src/Morley/Client/Util.hs view
@@ -13,6 +13,8 @@   , withAmount   , withSender   , withSource+  , withLevel+  , withNow    -- * @tezos-client@ password-related helpers   , scrubbedBytesToString@@ -37,7 +39,7 @@ import Morley.Michelson.Untyped (InternalByteString(..), Value, Value'(..)) import Morley.Michelson.Untyped.Entrypoints (EpName(..), pattern DefEpName) import Morley.Tezos.Address-import Morley.Tezos.Core (Mutez, zeroMutez)+import Morley.Tezos.Core (Mutez, Timestamp(..), zeroMutez) import Morley.Util.Exception as E (throwLeft)  -- | Sets the environment variable for disabling tezos-client@@ -75,6 +77,8 @@   , rcpParameter :: MaybeRPC (T.Value cp)   , rcpStorage :: MaybeRPC (T.Value st)   , rcpBalance :: Mutez+  , rcpNow :: Maybe Timestamp+  , rcpLevel :: Maybe Natural   , rcpAmount :: Mutez   , rcpSender :: Maybe Address   , rcpSource :: Maybe Address@@ -93,6 +97,8 @@     , rcpStorage = st     , rcpBalance = zeroMutez     , rcpAmount = zeroMutez+    , rcpNow = Nothing+    , rcpLevel = Nothing     , rcpSender = Nothing     , rcpSource = Nothing     }@@ -102,6 +108,8 @@   , ("rcpAmount", "withAmount")   , ("rcpSender", "withSender")   , ("rcpSource", "withSource")+  , ("rcpLevel", "withLevel")+  , ("rcpNow", "withNow")   ]   ''RunContractParameters @@ -119,6 +127,8 @@         , rcAmount = TezosMutez rcpAmount         , rcBalance = TezosMutez rcpBalance         , rcChainId = bcChainId headConstants+        , rcNow = rcpNow <&> StringEncode . round . unTimestamp+        , rcLevel = StringEncode <$> rcpLevel         -- Note: assigning source=sender and payer=source may seem like a bug, but it's not.         -- For some reason, the /run_code uses a different naming scheme.         -- What this endpoint calls 'source' is actually the address that will be returned by the `SENDER` instruction.
test/Test/BigMapGet.hs view
@@ -5,7 +5,7 @@   ( test_BigMapGetUnit   ) where -import Data.Map (fromList, lookup)+import Data.Map (lookup) import Test.HUnit (Assertion, assertFailure) import Test.Hspec.Expectations (shouldThrow) import Test.Tasty (TestTree, testGroup)@@ -18,9 +18,9 @@  import Morley.Client.RPC.Getters import Morley.Client.RPC.Types-import Morley.Client.TezosClient.Types (AddressOrAlias(..)) import Morley.Michelson.Runtime.GState (genesisAddress1, genesisAddress2, genesisAddress3) import Morley.Michelson.Typed+import Morley.Tezos.Address.Alias (AddressOrAlias(..)) import Test.Util import TestM 
+ test/Test/Errors.hs view
@@ -0,0 +1,59 @@+-- SPDX-FileCopyrightText: 2022 Oxhead Alpha+-- SPDX-License-Identifier: LicenseRef-MIT-OA++{-# OPTIONS_GHC -Wno-orphans #-}++module Test.Errors+  ( test_handleOperationResult+  ) where++import Debug qualified++import Test.Tasty (TestTree)+import Test.Tasty.HUnit (assertFailure, testCase, (@?=))++import Morley.Client.Action.Common+import Morley.Client.RPC.Error+import Morley.Client.RPC.Types+import Morley.Tezos.Core+import Morley.Util.Named++deriving stock instance Eq RunError++test_handleOperationResult :: TestTree+test_handleOperationResult = testCase "getAppliedResults #709 regression test" do+  let res = RunOperationResult+        { rrOperationContents =+            OperationContent+              (RunMetadata+                { rmOperationResult = OperationFailed []+                , rmInternalOperationResults =+                    [ InternalOperation {unInternalOperation = OperationFailed []}+                    , InternalOperation {unInternalOperation = OperationFailed []}+                    ]+                })+              :|+              [ OperationContent+                (RunMetadata+                  { rmOperationResult = OperationFailed+                      [ CantPayStorageFee+                      , BalanceTooLow (#balance :! [tz|149.38m|]) (#required :! [tz|355m|])+                      ]+                  , rmInternalOperationResults =+                      [ InternalOperation {unInternalOperation = OperationFailed []}+                      , InternalOperation {unInternalOperation = OperationFailed []}+                      ]+                  })+              , OperationContent (RunMetadata { rmOperationResult = OperationFailed []+                                              , rmInternalOperationResults = []})+              ]+        }+  handleOperationResult @(Either SomeException) res 3 & \case+    Right _ -> assertFailure "Expected result to fail, but it succeeded."+    Left err -> case fromException err of+      Just (UnexpectedRunErrors e) ->+        e @?=+          [ CantPayStorageFee+          , BalanceTooLow (#balance :! [tz|149.38m|]) (#required :! [tz|355m|])+          ]+      _ -> assertFailure $ "Expected failure to be UnexpectedRunErrors, but it was " <> Debug.show err
test/Test/Fees.hs view
@@ -5,7 +5,6 @@   ( test_Fees_comp_iterations   ) where -import Data.Map (fromList) import Test.HUnit ((@?=)) import Test.Tasty (TestTree) import Test.Tasty.HUnit (testCase)@@ -14,9 +13,9 @@ import Morley.Client.Action.Origination import Morley.Client.Action.Transaction import Morley.Client.RPC.Types-import Morley.Client.TezosClient import Morley.Michelson.Runtime.GState (genesisAddress1, genesisAddress2) import Morley.Michelson.Untyped.Entrypoints+import Morley.Tezos.Address.Alias (AddressOrAlias(..)) import Morley.Tezos.Core (tz) import Test.Util import TestM@@ -66,7 +65,7 @@     Right _ -> count  averageContract :: L.Contract () () ()-averageContract = L.mkContractWith L.intactCompilationOptions $+averageContract = L.mkContractWith L.intactCompilationOptions $ L.mkContractCode $   L.unpair L.# L.drop L.#   foldl' (L.#) L.nop (replicate 100 (L.push () L.# L.drop)) L.#   L.nil L.# L.pair
test/Test/KeyRevealing.hs view
@@ -13,6 +13,7 @@ import Morley.Client import Morley.Michelson.Runtime.GState (genesisAddress1) import Morley.Michelson.Typed+import Morley.Tezos.Address.Alias (AddressOrAlias(..)) import Morley.Tezos.Core (tz) import Test.Util import TestM@@ -29,7 +30,7 @@ test_keyRevealing = testGroup "Fake test key revealing"   [ testCase "Manager key for new address is revealed only once for transfer" $ handleSuccess $     runFakeTest chainOperationHandlers fakeState $ do-      senderAddress <- genKey $ AnAlias "sender"+      senderAddress <- genKey "sender"       dummyTransfer genesisAddress1 senderAddress       mbManagerKey <- getManagerKey senderAddress @@ -48,7 +49,7 @@    , testCase "Manager key for new address is revealed only once for origination" $ handleSuccess $     runFakeTest chainOperationHandlers fakeState $ do-      originatorAddress <- genKey $ AnAlias "originator"+      originatorAddress <- genKey "originator"       dummyTransfer genesisAddress1 originatorAddress        mbManagerKey <- getManagerKey originatorAddress
test/Test/Origination.hs view
@@ -5,7 +5,6 @@   ( test_lRunTransactionsUnit   ) where -import Data.Map (fromList) import Test.HUnit (Assertion, assertFailure) import Test.Hspec.Expectations (shouldThrow) import Test.Tasty (TestTree, testGroup)@@ -14,6 +13,7 @@ import Lorentz qualified as L import Morley.Client import Morley.Michelson.Runtime.GState (genesisAddress1, genesisAddress2, genesisAddress3)+import Morley.Tezos.Address.Alias (AddressOrAlias(..)) import Morley.Tezos.Core import Test.Util import TestM
test/Test/ParameterTypeGet.hs view
@@ -5,14 +5,13 @@   ( test_parameterTypeGetUnit   ) where -import Data.Map as Map (empty, fromList)+import Data.Map as Map (empty) import Test.HUnit (Assertion, assertEqual, assertFailure) import Test.Tasty (TestTree, testGroup) import Test.Tasty.HUnit (testCase)  import Lorentz qualified as L -import Morley.Client import Morley.Client.RPC.Getters import Morley.Client.RPC.Types import Morley.Micheline@@ -21,6 +20,8 @@ import Morley.Michelson.Typed import Morley.Michelson.Untyped qualified as U import Morley.Tezos.Address+import Morley.Tezos.Address.Alias (Alias)+import Morley.Tezos.Crypto import Test.Util import TestM @@ -39,9 +40,9 @@   }  contractHash1, contractHash2, contractHash3 :: ContractHash-contractHash1 = ContractHash "lol"-contractHash2 = ContractHash "kek"-contractHash3 = ContractHash "mda"+contractHash1 = Hash HashContract "lol"+contractHash2 = Hash HashContract "kek"+contractHash3 = Hash HashContract "mda"  smartContractAddr1, smartContractAddr2, smartContractAddr3 :: Address smartContractAddr1 = ContractAddress contractHash1
test/Test/ReadBigMapValue.hs view
@@ -6,7 +6,6 @@   , test_ReadBigMapValueMaybeUnit   ) where -import Data.Map (fromList) import Test.HUnit (Assertion, assertFailure) import Test.Tasty (TestTree, testGroup) import Test.Tasty.HUnit (testCase, (@?=))
test/Test/Transaction.hs view
@@ -5,7 +5,6 @@   ( test_lRunTransactionsUnit   ) where -import Data.Map (fromList) import Test.HUnit (Assertion, assertFailure) import Test.Hspec.Expectations (shouldThrow) import Test.Tasty (TestTree, testGroup)
test/Test/Util.hs view
@@ -20,7 +20,7 @@ import Data.Aeson (encode) import Data.ByteArray (ScrubbedBytes) import Data.ByteString.Lazy qualified as LBS (toStrict)-import Data.Map as Map (elems, fromList, insert, lookup, toList)+import Data.Map as Map (elems, insert, lookup, toList) import Data.Singletons (demote) import Fmt ((+|), (|+)) import Network.HTTP.Types.Status (status404)@@ -33,11 +33,11 @@ import Lorentz.Constraints import Lorentz.Pack import Morley.Client.RPC.Types-import Morley.Client.TezosClient.Types import Morley.Client.Types import Morley.Micheline import Morley.Michelson.Typed import Morley.Tezos.Address+import Morley.Tezos.Address.Alias (AddressOrAlias(..), Alias(..)) import Morley.Tezos.Core import Morley.Tezos.Crypto import Morley.Tezos.Crypto.Ed25519 qualified as Ed25519@@ -92,7 +92,7 @@   , hGetContractScript = handleGetContractScript   , hSignBytes =     \_ _ -> pure . SignatureEd25519 . Ed25519.sign testSecretKey-  , hWaitForOperation = const pass+  , hWaitForOperation = id   , hGetAlias = handleGetAlias   , hResolveAddressMaybe = handleResolveAddressMaybe   , hRememberContract = handleRememberContract@@ -117,7 +117,7 @@       }   } -handleGetBlockHash :: Monad m => BlockId -> TestT m Text+handleGetBlockHash :: Monad m => BlockId -> TestT m BlockHash handleGetBlockHash blkId = do   unless (blkId == FinalHeadId) do     throwString "Expected `getBlockHash` to be called with `head~2`."@@ -197,7 +197,7 @@   :: Monad m => OperationInput -> TestT m [Address] handleTransactionOrOrigination op = do   FakeState{..} <- get-  case oiCustom op of+  case wcoCustom op of     -- Ensure that transaction sender exists     OpTransfer TransactionOperation{..} -> case lookup codSource fsContracts of       Nothing -> throwM $ UnknownContract $ AddressResolved codSource@@ -220,7 +220,7 @@       -- We do not care about reveals at the moment       return []   where-    CommonOperationData{..} = oiCommonData op+    CommonOperationData{..} = wcoCommon op  -- | In most places, @morley-client@ executes operations against the @head@ block. assertHeadBlockId :: (HasCallStack, MonadThrow m) => BlockId -> m ()@@ -267,15 +267,8 @@   where     path = "/chains/main/blocks/head/context/big_maps/" <> show bigMapId <> "/" <> scriptExpr --- Here we have an alias with the prefix already added,--- so we can use 'Alias' instead 'AliasHint'.-getAlias :: AliasOrAliasHint -> Alias-getAlias = \case-  AnAlias x -> x-  AnAliasHint hint -> unsafeCoerceAliasHintToAlias hint--handleRememberContract :: Monad m => Bool -> Address -> AliasOrAliasHint -> TestT m ()-handleRememberContract replaceExisting addr (getAlias -> alias) = do+handleRememberContract :: Monad m => Bool -> Address -> Alias -> TestT m ()+handleRememberContract replaceExisting addr alias = do   let     cs = dumbContractState { csAlias = alias }     remember addr' cs' FakeState{..} =@@ -286,10 +279,10 @@     Nothing -> remember addr cs st     _       -> bool pass (remember addr cs st) replaceExisting -handleGenKey :: Monad m => AliasOrAliasHint -> TestT m Address-handleGenKey (getAlias -> alias) = do+handleGenKey :: Monad m => Alias -> TestT m Address+handleGenKey alias = do   let-    addr = detGenKeyAddress (encodeUtf8 $ unsafeGetAliasText alias)+    addr = detGenKeyAddress (encodeUtf8 $ unAlias alias)     newContractState = dumbImplicitContractState { csAlias =  alias }   modify $ \s ->     s & fsContractsL . at addr ?~ newContractState
test/TestM.hs view
@@ -31,8 +31,8 @@ import Control.Monad.Catch.Pure (CatchT(..)) import Data.ByteArray (ScrubbedBytes) import Data.Time.Clock.POSIX (posixSecondsToUTCTime)+import Fmt (pretty) -import Fmt import Morley.Client import Morley.Client.Logging (ClientLogAction) import Morley.Client.RPC@@ -40,22 +40,25 @@ import Morley.Micheline import Morley.Michelson.Typed.Scope (UntypedValScope) import Morley.Tezos.Address+import Morley.Tezos.Address.Alias (AddressOrAlias, Alias(..)) import Morley.Tezos.Core import Morley.Tezos.Crypto (KeyHash, PublicKey, SecretKey, Signature) import Morley.Util.ByteString  -- | A test-specific orphan. instance IsString Alias where-  fromString = mkAlias . fromString+  fromString = Alias . fromString  -- | Reader environment to interact with the fake state. data Handlers m = Handlers   { -- HasTezosRpc-    hGetBlockHash :: BlockId -> m Text+    hGetBlockHash :: BlockId -> m BlockHash   , hGetCounter :: BlockId -> Address -> m TezosInt64   , hGetBlockHeader :: BlockId -> m BlockHeader   , hGetBlockConstants :: BlockId -> m BlockConstants   , hGetBlockOperations :: BlockId -> m [[BlockOperation]]+  , hGetScriptSizeAtBlock :: BlockId -> CalcSize -> m ScriptSize+  , hGetBlockOperationHashes :: BlockId -> m [[OperationHash]]   , hGetProtocolParameters :: BlockId -> m ProtocolParameters   , hRunOperation :: BlockId -> RunOperation -> m RunOperationResult   , hPreApplyOperations :: BlockId -> [PreApplyOperation] -> m [RunOperationResult]@@ -73,22 +76,23 @@    -- HasTezosClient   , hSignBytes :: AddressOrAlias -> Maybe ScrubbedBytes -> ByteString -> m Signature-  , hGenKey :: AliasOrAliasHint -> m Address-  , hGenFreshKey :: AliasOrAliasHint -> m Address+  , hGenKey :: Alias -> m Address+  , hGenFreshKey :: Alias -> m Address   , hRevealKey :: Alias -> Maybe ScrubbedBytes -> m ()-  , hWaitForOperation :: OperationHash -> m ()-  , hRememberContract :: Bool -> Address -> AliasOrAliasHint -> m ()-  , hImportKey :: Bool -> AliasOrAliasHint -> SecretKey -> m Alias+  , hWaitForOperation :: m OperationHash -> m OperationHash+  , hRememberContract :: Bool -> Address -> Alias -> m ()+  , hImportKey :: Bool -> Alias -> SecretKey -> m Alias   , hResolveAddressMaybe :: AddressOrAlias -> m (Maybe Address)   , hGetAlias :: AddressOrAlias -> m Alias   , hGetPublicKey :: AddressOrAlias -> m PublicKey+  , hGetSecretKey :: AddressOrAlias -> m SecretKey   , hGetTezosClientConfig :: m TezosClientConfig   , hCalcTransferFee     :: AddressOrAlias -> Maybe ScrubbedBytes -> TezosInt64 -> [CalcTransferFeeData] -> m [TezosMutez]   , hCalcOriginationFee     :: forall cp st. UntypedValScope st => CalcOriginationFeeData cp st -> m TezosMutez   , hGetKeyPassword :: Address -> m (Maybe ScrubbedBytes)-  , hRegisterDelegate :: AliasOrAliasHint -> Maybe ScrubbedBytes -> m ()+  , hRegisterDelegate :: Alias -> Maybe ScrubbedBytes -> m ()    -- HasLog   , hLogAction :: ClientLogAction m@@ -100,7 +104,9 @@   , hGetCounter = \_ _ -> throwM $ UnexpectedRpcCall "getCounter"   , hGetBlockHeader = \_ -> throwM $ UnexpectedRpcCall "getBlockHeader"   , hGetBlockConstants = \_ -> throwM $ UnexpectedRpcCall "getBlockConstants"+  , hGetScriptSizeAtBlock = \_ _ -> throwM $ UnexpectedRpcCall "getScriptSizeAtBlock"   , hGetBlockOperations = \_ -> throwM $ UnexpectedRpcCall "getBlockOperations"+  , hGetBlockOperationHashes = \_ -> throwM $ UnexpectedRpcCall "hGetBlockOperationHashes"   , hGetProtocolParameters = \_ -> throwM $ UnexpectedRpcCall "getProtocolParameters"   , hRunOperation = \_ _ -> throwM $ UnexpectedRpcCall "runOperation"   , hPreApplyOperations = \_ _ -> throwM $ UnexpectedRpcCall "preApplyOperations"@@ -126,6 +132,7 @@   , hResolveAddressMaybe = \_ -> throwM $ UnexpectedRpcCall "resolveAddressMaybe"   , hGetAlias = \_ -> throwM $ UnexpectedRpcCall "getAlias"   , hGetPublicKey = \_ -> throwM $ UnexpectedRpcCall "getPublicKey"+  , hGetSecretKey = \_ -> throwM $ UnexpectedRpcCall "getSecretKey"   , hGetTezosClientConfig = throwM $ UnexpectedClientCall "getTezosClientConfig"   , hCalcTransferFee = \_ _ _ _ -> throwM $ UnexpectedClientCall "calcTransferFee"   , hCalcOriginationFee = \_ -> throwM $ UnexpectedClientCall "calcOriginationFee"@@ -162,9 +169,9 @@ -- | Type to represent chain state in mock tests. data FakeState = FakeState   { fsContracts :: Map Address ContractState-  , fsHeadBlock :: Text+  , fsHeadBlock :: BlockHash   -- ^ Hash of the `head` block-  , fsFinalHeadBlock :: Text+  , fsFinalHeadBlock :: BlockHash   -- ^ Hash of the `head~2` block   , fsBlockConstants :: BlockId -> BlockConstants   , fsProtocolParameters :: ProtocolParameters@@ -173,8 +180,8 @@ defaultFakeState :: FakeState defaultFakeState = FakeState   { fsContracts = mempty-  , fsHeadBlock = "HEAD"-  , fsFinalHeadBlock = "HEAD~2"+  , fsHeadBlock = BlockHash "HEAD"+  , fsFinalHeadBlock = BlockHash "HEAD~2"   , fsBlockConstants = \blkId -> BlockConstants     { bcProtocol = "PROTOCOL"     , bcChainId = "CHAIN_ID"@@ -221,7 +228,7 @@   | CantRevealContract Address   | InvalidChainId   | InvalidProtocol-  | InvalidBranch Text+  | InvalidBranch BlockHash   | CounterMismatch   deriving stock Show @@ -245,9 +252,6 @@   revealKey alias mbPassword = do     h <- getHandler hRevealKey     h alias mbPassword-  waitForOperation op = do-    h <- getHandler hWaitForOperation-    h op   rememberContract replaceExisting addr alias = do     h <- getHandler hRememberContract     h replaceExisting addr alias@@ -263,13 +267,16 @@   getPublicKey alias = do     h <- getHandler hGetPublicKey     h alias+  getSecretKey alias = do+    h <- getHandler hGetSecretKey+    h alias   getTezosClientConfig =     join $ getHandler hGetTezosClientConfig   calcTransferFee from mbPassword burnCap transferDatas = do     h <- getHandler hCalcTransferFee     h from mbPassword burnCap transferDatas   calcOriginationFee origData = do-    h <- getHandler hCalcOriginationFee+    h <- getHandler (\hs -> hCalcOriginationFee hs)     h origData   getKeyPassword addr = do     h <- getHandler hGetKeyPassword@@ -303,6 +310,9 @@   preApplyOperationsAtBlock block ops = do     h <- getHandler hPreApplyOperations     h block ops+  getScriptSizeAtBlock block script = do+    h <- getHandler hGetScriptSizeAtBlock+    h block script   forgeOperationAtBlock block op = do     h <- getHandler hForgeOperation     h block op@@ -337,5 +347,11 @@   getDelegateAtBlock block addr = do     h <- getHandler hGetDelegateAtBlock     h block addr+  getBlockOperationHashes block = do+    h <- getHandler hGetBlockOperationHashes+    h block+  waitForOperation opHash = do+    h <- getHandler hWaitForOperation+    h opHash  makeLensesFor [("fsContracts", "fsContractsL")] ''FakeState