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

-- | Types used for interaction with @tezos-client@.

module Morley.Client.TezosClient.Types
  ( CmdArg (..)
  , Alias
  , AliasHint
  , AliasOrAliasHint (..)
  , AddressOrAlias (..)
  , addressResolved
  , CalcOriginationFeeData (..)
  , CalcTransferFeeData (..)
  , TezosClientConfig (..)
  , TezosClientEnv (..)
  , HasTezosClientEnv (..)
  , SecretKeyEncryption (..)

  -- * Unsafe coercions
  , unsafeCoerceAliasHintToAlias
  , unsafeCoerceAliasToAliasHint
  , unsafeGetAliasText
  , unsafeGetAliasHintText
  , mkAlias
  , mkAliasHint

  -- * Lens
  , tceAliasPrefixL
  , tceEndpointUrlL
  , tceTezosClientPathL
  , tceMbTezosClientDataDirL
  ) where

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)

import Lorentz (ToAddress, toAddress)
import Morley.Client.RPC.Types (OperationHash)
import Morley.Client.Util
import Morley.Micheline
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.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
  -- | Render an object as a command-line argument.
  toCmdArg :: a -> String
  default toCmdArg :: Buildable a => a -> String
  toCmdArg = a -> String
forall a b. (Buildable a, FromBuilder b) => a -> b
pretty

instance CmdArg Text where

instance CmdArg LText where

instance CmdArg Word16 where

instance CmdArg SecretKey where
  toCmdArg :: SecretKey -> String
toCmdArg = Text -> String
forall a. CmdArg a => a -> String
toCmdArg (Text -> String) -> (SecretKey -> Text) -> SecretKey -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SecretKey -> Text
formatSecretKey

instance CmdArg Address where

instance CmdArg ByteString where
  toCmdArg :: ByteString -> String
toCmdArg = Text -> String
forall a. CmdArg a => a -> String
toCmdArg (Text -> String) -> (ByteString -> Text) -> ByteString -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text
"0x" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) (Text -> Text) -> (ByteString -> Text) -> ByteString -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
encodeHex

instance CmdArg EpName where
  toCmdArg :: EpName -> String
toCmdArg = Text -> String
forall a. CmdArg a => a -> String
toCmdArg (Text -> String) -> (EpName -> Text) -> EpName -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EpName -> Text
epNameToTezosEp

instance CmdArg Mutez where
  toCmdArg :: Mutez -> String
toCmdArg Mutez
m = Fixed E6 -> String
forall b a. (PrettyShow a, Show a, IsString b) => a -> b
show (Fixed E6 -> String) -> (Integer -> Fixed E6) -> Integer -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Fixed E6
forall k (a :: k). Integer -> Fixed a
MkFixed @_ @E6 (Integer -> String) -> Integer -> String
forall a b. (a -> b) -> a -> b
$ Word63 -> Integer
forall a b. (Integral a, Integral b, CheckIntSubType a b) => a -> b
fromIntegral (Mutez -> Word63
unMutez Mutez
m)

instance T.ProperUntypedValBetterErrors t => CmdArg (Value t) where
  toCmdArg :: Value t -> String
toCmdArg = LText -> String
forall a. CmdArg a => a -> String
toCmdArg (LText -> String) -> (Value t -> LText) -> Value t -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Value t -> LText
forall (t :: T).
ProperUntypedValBetterErrors t =>
Bool -> Value t -> LText
printTypedValue Bool
True

instance CmdArg (Contract cp st) where
  toCmdArg :: Contract cp st -> String
toCmdArg = LText -> String
forall a. ToString a => a -> String
toString (LText -> String)
-> (Contract cp st -> LText) -> Contract cp st -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Contract cp st -> LText
forall (p :: T) (s :: T). Bool -> Contract p s -> LText
printTypedContract Bool
True

instance CmdArg BaseUrl where
  toCmdArg :: BaseUrl -> String
toCmdArg = BaseUrl -> String
showBaseUrl

instance CmdArg OperationHash

-- | @tezos-client@ can associate addresses with textual aliases.
-- This type denotes such an alias.
newtype Alias = Alias
  { Alias -> Text
unsafeGetAliasText :: Text
    -- ^ Unsafely extract 'Text' from 'Alias'. Do NOT use the result with
    -- 'mkAliasHint'.
  }
  deriving stock (Int -> Alias -> ShowS
[Alias] -> ShowS
Alias -> String
(Int -> Alias -> ShowS)
-> (Alias -> String) -> ([Alias] -> ShowS) -> Show Alias
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Alias] -> ShowS
$cshowList :: [Alias] -> ShowS
show :: Alias -> String
$cshow :: Alias -> String
showsPrec :: Int -> Alias -> ShowS
$cshowsPrec :: Int -> Alias -> ShowS
Show, Alias -> Alias -> Bool
(Alias -> Alias -> Bool) -> (Alias -> Alias -> Bool) -> Eq Alias
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Alias -> Alias -> Bool
$c/= :: Alias -> Alias -> Bool
== :: Alias -> Alias -> Bool
$c== :: Alias -> Alias -> Bool
Eq, Eq Alias
Eq Alias
-> (Alias -> Alias -> Ordering)
-> (Alias -> Alias -> Bool)
-> (Alias -> Alias -> Bool)
-> (Alias -> Alias -> Bool)
-> (Alias -> Alias -> Bool)
-> (Alias -> Alias -> Alias)
-> (Alias -> Alias -> Alias)
-> Ord Alias
Alias -> Alias -> Bool
Alias -> Alias -> Ordering
Alias -> Alias -> Alias
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Alias -> Alias -> Alias
$cmin :: Alias -> Alias -> Alias
max :: Alias -> Alias -> Alias
$cmax :: Alias -> Alias -> Alias
>= :: Alias -> Alias -> Bool
$c>= :: Alias -> Alias -> Bool
> :: Alias -> Alias -> Bool
$c> :: Alias -> Alias -> Bool
<= :: Alias -> Alias -> Bool
$c<= :: Alias -> Alias -> Bool
< :: Alias -> Alias -> Bool
$c< :: Alias -> Alias -> Bool
compare :: Alias -> Alias -> Ordering
$ccompare :: Alias -> Alias -> Ordering
$cp1Ord :: Eq Alias
Ord)
  deriving newtype (Alias -> Builder
(Alias -> Builder) -> Buildable Alias
forall p. (p -> Builder) -> Buildable p
build :: Alias -> Builder
$cbuild :: Alias -> Builder
Buildable, Alias -> String
(Alias -> String) -> CmdArg Alias
forall a. (a -> String) -> CmdArg a
toCmdArg :: Alias -> String
$ctoCmdArg :: Alias -> String
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
  { AliasHint -> Text
unsafeGetAliasHintText :: Text
    -- ^ Unsafely extract 'Text' from 'AliasHint'. Do NOT use the result with
    -- 'mkAlias'.
  }
  deriving stock (Int -> AliasHint -> ShowS
[AliasHint] -> ShowS
AliasHint -> String
(Int -> AliasHint -> ShowS)
-> (AliasHint -> String)
-> ([AliasHint] -> ShowS)
-> Show AliasHint
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AliasHint] -> ShowS
$cshowList :: [AliasHint] -> ShowS
show :: AliasHint -> String
$cshow :: AliasHint -> String
showsPrec :: Int -> AliasHint -> ShowS
$cshowsPrec :: Int -> AliasHint -> ShowS
Show)
  deriving newtype (String -> AliasHint
(String -> AliasHint) -> IsString AliasHint
forall a. (String -> a) -> IsString a
fromString :: String -> AliasHint
$cfromString :: String -> AliasHint
IsString, AliasHint -> Builder
(AliasHint -> Builder) -> Buildable AliasHint
forall p. (p -> Builder) -> Buildable p
build :: AliasHint -> Builder
$cbuild :: AliasHint -> Builder
Buildable, b -> AliasHint -> AliasHint
NonEmpty AliasHint -> AliasHint
AliasHint -> AliasHint -> AliasHint
(AliasHint -> AliasHint -> AliasHint)
-> (NonEmpty AliasHint -> AliasHint)
-> (forall b. Integral b => b -> AliasHint -> AliasHint)
-> Semigroup AliasHint
forall b. Integral b => b -> AliasHint -> AliasHint
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
stimes :: b -> AliasHint -> AliasHint
$cstimes :: forall b. Integral b => b -> AliasHint -> AliasHint
sconcat :: NonEmpty AliasHint -> AliasHint
$csconcat :: NonEmpty AliasHint -> AliasHint
<> :: AliasHint -> AliasHint -> AliasHint
$c<> :: AliasHint -> AliasHint -> AliasHint
Semigroup, Semigroup AliasHint
AliasHint
Semigroup AliasHint
-> AliasHint
-> (AliasHint -> AliasHint -> AliasHint)
-> ([AliasHint] -> AliasHint)
-> Monoid AliasHint
[AliasHint] -> AliasHint
AliasHint -> AliasHint -> AliasHint
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
mconcat :: [AliasHint] -> AliasHint
$cmconcat :: [AliasHint] -> AliasHint
mappend :: AliasHint -> AliasHint -> AliasHint
$cmappend :: AliasHint -> AliasHint -> AliasHint
mempty :: AliasHint
$cmempty :: AliasHint
$cp1Monoid :: Semigroup AliasHint
Monoid)

-- | Coerce 'Alias' to 'AliasHint'. Unless you know for a fact that prefix is empty,
-- this is unsafe.
unsafeCoerceAliasToAliasHint :: Alias -> AliasHint
unsafeCoerceAliasToAliasHint :: Alias -> AliasHint
unsafeCoerceAliasToAliasHint = Alias -> AliasHint
coerce

-- | Coerce 'AliasHint' to 'Alias'. Unless you know for a fact that prefix is empty,
-- this is unsafe.
unsafeCoerceAliasHintToAlias :: AliasHint -> Alias
unsafeCoerceAliasHintToAlias :: AliasHint -> Alias
unsafeCoerceAliasHintToAlias = AliasHint -> Alias
coerce

-- | Make 'Alias' from 'Text'
mkAlias :: Text -> Alias
mkAlias :: Text -> Alias
mkAlias = Text -> Alias
Alias

-- | Make 'AliasHint' from 'Text'
mkAliasHint :: Text -> AliasHint
mkAliasHint :: Text -> AliasHint
mkAliasHint = Text -> AliasHint
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 (Int -> AliasOrAliasHint -> ShowS
[AliasOrAliasHint] -> ShowS
AliasOrAliasHint -> String
(Int -> AliasOrAliasHint -> ShowS)
-> (AliasOrAliasHint -> String)
-> ([AliasOrAliasHint] -> ShowS)
-> Show AliasOrAliasHint
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AliasOrAliasHint] -> ShowS
$cshowList :: [AliasOrAliasHint] -> ShowS
show :: AliasOrAliasHint -> String
$cshow :: AliasOrAliasHint -> String
showsPrec :: Int -> AliasOrAliasHint -> ShowS
$cshowsPrec :: Int -> AliasOrAliasHint -> ShowS
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 (Int -> AddressOrAlias -> ShowS
[AddressOrAlias] -> ShowS
AddressOrAlias -> String
(Int -> AddressOrAlias -> ShowS)
-> (AddressOrAlias -> String)
-> ([AddressOrAlias] -> ShowS)
-> Show AddressOrAlias
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AddressOrAlias] -> ShowS
$cshowList :: [AddressOrAlias] -> ShowS
show :: AddressOrAlias -> String
$cshow :: AddressOrAlias -> String
showsPrec :: Int -> AddressOrAlias -> ShowS
$cshowsPrec :: Int -> AddressOrAlias -> ShowS
Show, AddressOrAlias -> AddressOrAlias -> Bool
(AddressOrAlias -> AddressOrAlias -> Bool)
-> (AddressOrAlias -> AddressOrAlias -> Bool) -> Eq AddressOrAlias
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AddressOrAlias -> AddressOrAlias -> Bool
$c/= :: AddressOrAlias -> AddressOrAlias -> Bool
== :: AddressOrAlias -> AddressOrAlias -> Bool
$c== :: AddressOrAlias -> AddressOrAlias -> Bool
Eq, Eq AddressOrAlias
Eq AddressOrAlias
-> (AddressOrAlias -> AddressOrAlias -> Ordering)
-> (AddressOrAlias -> AddressOrAlias -> Bool)
-> (AddressOrAlias -> AddressOrAlias -> Bool)
-> (AddressOrAlias -> AddressOrAlias -> Bool)
-> (AddressOrAlias -> AddressOrAlias -> Bool)
-> (AddressOrAlias -> AddressOrAlias -> AddressOrAlias)
-> (AddressOrAlias -> AddressOrAlias -> AddressOrAlias)
-> Ord AddressOrAlias
AddressOrAlias -> AddressOrAlias -> Bool
AddressOrAlias -> AddressOrAlias -> Ordering
AddressOrAlias -> AddressOrAlias -> AddressOrAlias
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: AddressOrAlias -> AddressOrAlias -> AddressOrAlias
$cmin :: AddressOrAlias -> AddressOrAlias -> AddressOrAlias
max :: AddressOrAlias -> AddressOrAlias -> AddressOrAlias
$cmax :: AddressOrAlias -> AddressOrAlias -> AddressOrAlias
>= :: AddressOrAlias -> AddressOrAlias -> Bool
$c>= :: AddressOrAlias -> AddressOrAlias -> Bool
> :: AddressOrAlias -> AddressOrAlias -> Bool
$c> :: AddressOrAlias -> AddressOrAlias -> Bool
<= :: AddressOrAlias -> AddressOrAlias -> Bool
$c<= :: AddressOrAlias -> AddressOrAlias -> Bool
< :: AddressOrAlias -> AddressOrAlias -> Bool
$c< :: AddressOrAlias -> AddressOrAlias -> Bool
compare :: AddressOrAlias -> AddressOrAlias -> Ordering
$ccompare :: AddressOrAlias -> AddressOrAlias -> Ordering
$cp1Ord :: Eq AddressOrAlias
Ord)

instance CmdArg AddressOrAlias where

instance HasCLReader AddressOrAlias where
  getReader :: ReadM AddressOrAlias
getReader =
    ReadM Text
forall s. IsString s => ReadM s
Opt.str ReadM Text -> (Text -> AddressOrAlias) -> ReadM AddressOrAlias
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \Text
addrOrAlias ->
      case Text -> Either ParseAddressError Address
parseAddress Text
addrOrAlias of
        Right Address
addr -> Address -> AddressOrAlias
AddressResolved Address
addr
        Left ParseAddressError
_ -> Alias -> AddressOrAlias
AddressAlias (Text -> Alias
Alias Text
addrOrAlias)
  getMetavar :: String
getMetavar = String
"ADDRESS OR ALIAS"

-- | Creates an 'AddressOrAlias' with the given address.
addressResolved :: ToAddress addr => addr -> AddressOrAlias
addressResolved :: addr -> AddressOrAlias
addressResolved = Address -> AddressOrAlias
AddressResolved (Address -> AddressOrAlias)
-> (addr -> Address) -> addr -> AddressOrAlias
forall b c a. (b -> c) -> (a -> b) -> a -> c
. addr -> Address
forall a. ToAddress a => a -> Address
toAddress

instance Buildable AddressOrAlias where
  build :: AddressOrAlias -> Builder
build = \case
    AddressResolved Address
addr -> Address -> Builder
forall p. Buildable p => p -> Builder
build Address
addr
    AddressAlias Alias
alias -> Alias -> Builder
forall p. Buildable p => p -> Builder
build Alias
alias

-- | Representation of address secret key encryption type
data SecretKeyEncryption
  = UnencryptedKey
  | EncryptedKey
  | LedgerKey
  deriving stock (SecretKeyEncryption -> SecretKeyEncryption -> Bool
(SecretKeyEncryption -> SecretKeyEncryption -> Bool)
-> (SecretKeyEncryption -> SecretKeyEncryption -> Bool)
-> Eq SecretKeyEncryption
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SecretKeyEncryption -> SecretKeyEncryption -> Bool
$c/= :: SecretKeyEncryption -> SecretKeyEncryption -> Bool
== :: SecretKeyEncryption -> SecretKeyEncryption -> Bool
$c== :: SecretKeyEncryption -> SecretKeyEncryption -> Bool
Eq, Int -> SecretKeyEncryption -> ShowS
[SecretKeyEncryption] -> ShowS
SecretKeyEncryption -> String
(Int -> SecretKeyEncryption -> ShowS)
-> (SecretKeyEncryption -> String)
-> ([SecretKeyEncryption] -> ShowS)
-> Show SecretKeyEncryption
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SecretKeyEncryption] -> ShowS
$cshowList :: [SecretKeyEncryption] -> ShowS
show :: SecretKeyEncryption -> String
$cshow :: SecretKeyEncryption -> String
showsPrec :: Int -> SecretKeyEncryption -> ShowS
$cshowsPrec :: Int -> SecretKeyEncryption -> ShowS
Show)

-- | Configuration maintained by @tezos-client@, see its @config@ subcommands
-- (e. g. @tezos-client config show@).
-- Only the field we are interested in is present here.
newtype TezosClientConfig = TezosClientConfig { TezosClientConfig -> BaseUrl
tcEndpointUrl :: BaseUrl }
  deriving stock Int -> TezosClientConfig -> ShowS
[TezosClientConfig] -> ShowS
TezosClientConfig -> String
(Int -> TezosClientConfig -> ShowS)
-> (TezosClientConfig -> String)
-> ([TezosClientConfig] -> ShowS)
-> Show TezosClientConfig
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TezosClientConfig] -> ShowS
$cshowList :: [TezosClientConfig] -> ShowS
show :: TezosClientConfig -> String
$cshow :: TezosClientConfig -> String
showsPrec :: Int -> TezosClientConfig -> ShowS
$cshowsPrec :: Int -> TezosClientConfig -> ShowS
Show

-- | For reading tezos-client config.
instance FromJSON TezosClientConfig where
  parseJSON :: Value -> Parser TezosClientConfig
parseJSON = String
-> (Object -> Parser TezosClientConfig)
-> Value
-> Parser TezosClientConfig
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"node info" ((Object -> Parser TezosClientConfig)
 -> Value -> Parser TezosClientConfig)
-> (Object -> Parser TezosClientConfig)
-> Value
-> Parser TezosClientConfig
forall a b. (a -> b) -> a -> b
$ \Object
o -> BaseUrl -> TezosClientConfig
TezosClientConfig (BaseUrl -> TezosClientConfig)
-> Parser BaseUrl -> Parser TezosClientConfig
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser BaseUrl
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"endpoint"

-- | Runtime environment for @tezos-client@ bindings.
data TezosClientEnv = TezosClientEnv
  { TezosClientEnv -> Maybe Text
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.
  , TezosClientEnv -> BaseUrl
tceEndpointUrl :: BaseUrl
  -- ^ URL of tezos node on which operations are performed.
  , TezosClientEnv -> String
tceTezosClientPath :: FilePath
  -- ^ Path to tezos client binary through which operations are
  -- performed.
  , TezosClientEnv -> Maybe String
tceMbTezosClientDataDir :: Maybe FilePath
  -- ^ Path to tezos client data directory.
  }

makeLensesWith postfixLFields ''TezosClientEnv

-- | Using this type class one can require 'MonadReader' constraint
-- that holds any type with 'TezosClientEnv' inside.
class HasTezosClientEnv env where
  tezosClientEnvL :: Lens' env TezosClientEnv

-- | Data required for calculating fee for transfer operation.
data CalcTransferFeeData = forall t. T.UntypedValScope t => CalcTransferFeeData
  { CalcTransferFeeData -> AddressOrAlias
ctfdTo :: AddressOrAlias
  , ()
ctfdParam :: Value t
  , CalcTransferFeeData -> EpName
ctfdEp :: EpName
  , CalcTransferFeeData -> TezosMutez
ctfdAmount :: TezosMutez
  }

instance ToJSON CalcTransferFeeData where
  toJSON :: CalcTransferFeeData -> Value
toJSON CalcTransferFeeData{TezosMutez
Value t
EpName
AddressOrAlias
ctfdAmount :: TezosMutez
ctfdEp :: EpName
ctfdParam :: Value t
ctfdTo :: AddressOrAlias
ctfdAmount :: CalcTransferFeeData -> TezosMutez
ctfdEp :: CalcTransferFeeData -> EpName
ctfdParam :: ()
ctfdTo :: CalcTransferFeeData -> AddressOrAlias
..} = [Pair] -> Value
object
    [ Text
"destination" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= AddressOrAlias -> Text
forall a b. (Buildable a, FromBuilder b) => a -> b
pretty @_ @Text AddressOrAlias
ctfdTo
    , Text
"amount" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (IsString Text => String -> Text
forall a. IsString a => String -> a
fromString @Text (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ Mutez -> String
forall a. CmdArg a => a -> String
toCmdArg (Mutez -> String) -> Mutez -> String
forall a b. (a -> b) -> a -> b
$ TezosMutez -> Mutez
unTezosMutez TezosMutez
ctfdAmount)
    , Text
"arg" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (IsString Text => String -> Text
forall a. IsString a => String -> a
fromString @Text (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ Value t -> String
forall a. CmdArg a => a -> String
toCmdArg Value t
ctfdParam)
    , Text
"entrypoint" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (IsString Text => String -> Text
forall a. IsString a => String -> a
fromString @Text (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ EpName -> String
forall a. CmdArg a => a -> String
toCmdArg EpName
ctfdEp)
    ]

-- | Data required for calculating fee for origination operation.
data CalcOriginationFeeData cp st = CalcOriginationFeeData
  { CalcOriginationFeeData cp st -> AddressOrAlias
cofdFrom :: AddressOrAlias
  , CalcOriginationFeeData cp st -> TezosMutez
cofdBalance :: TezosMutez
  , CalcOriginationFeeData cp st -> Maybe ScrubbedBytes
cofdMbFromPassword :: Maybe ScrubbedBytes
  , CalcOriginationFeeData cp st -> Contract cp st
cofdContract :: Contract cp st
  , CalcOriginationFeeData cp st -> Value st
cofdStorage :: Value st
  , CalcOriginationFeeData cp st -> TezosInt64
cofdBurnCap :: TezosInt64
  }