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

module Morley.Client.Parser
  ( ClientArgs (..)
  , ClientArgsRaw (..)
  , OriginateArgs (..)
  , TransferArgs (..)
  , GetScriptSizeArgs (..)
  , addressOrAliasOption
  , clientConfigParser
  , morleyClientInfo
  , parserInfo

  , originateArgsOption
  , mbContractFileOption
  , contractNameOption

    -- * Parser utilities
  , baseUrlReader
  ) where

import Options.Applicative
  (ReadM, eitherReader, help, long, metavar, option, short, strOption, subparser, value)
import Options.Applicative qualified as Opt
import Options.Applicative.Help.Pretty (Doc, linebreak)
import Servant.Client (BaseUrl(..), parseBaseUrl)

import Morley.CLI
  (addressOrAliasOption, keyHashOption, mutezOption, parserInfo, someAddressOrAliasOption,
  valueOption)
import Morley.Client.Init
import Morley.Client.RPC.Types (BlockId(HeadId))
import Morley.Michelson.Untyped qualified as U
import Morley.Tezos.Address
import Morley.Tezos.Address.Alias
import Morley.Tezos.Address.Kinds
import Morley.Tezos.Core
import Morley.Tezos.Crypto
import Morley.Util.CLI (mkCLOptionParser, mkCommandParser)
import Morley.Util.Named

data ClientArgs
  = ClientArgs MorleyClientConfig ClientArgsRaw

data ClientArgsRaw where
  Originate :: OriginateArgs -> ClientArgsRaw
  GetScriptSize :: GetScriptSizeArgs -> ClientArgsRaw
  Transfer :: TransferArgs -> ClientArgsRaw
  GetBalance :: L1AddressKind kind => AddressOrAlias kind -> ClientArgsRaw
  GetBlockHeader :: BlockId -> ClientArgsRaw
  GetBlockOperations :: BlockId -> ClientArgsRaw

data OriginateArgs = OriginateArgs
  { OriginateArgs -> Maybe FilePath
oaMbContractFile :: Maybe FilePath
  , OriginateArgs -> ContractAlias
oaContractName   :: ContractAlias
  , OriginateArgs -> Mutez
oaInitialBalance :: Mutez
  , OriginateArgs -> Value
oaInitialStorage :: U.Value
  , OriginateArgs -> ImplicitAddressOrAlias
oaOriginateFrom  :: ImplicitAddressOrAlias
  , OriginateArgs -> Maybe Mutez
oaMbFee :: Maybe Mutez
  , OriginateArgs -> Maybe KeyHash
oaDelegate :: Maybe KeyHash
  }

data GetScriptSizeArgs = GetScriptSizeArgs
  { GetScriptSizeArgs -> FilePath
ssScriptFile :: FilePath
  , GetScriptSizeArgs -> Value
ssStorage    :: U.Value
  }

data TransferArgs = TransferArgs
  { TransferArgs -> ImplicitAddressOrAlias
taSender      :: ImplicitAddressOrAlias
  , TransferArgs -> SomeAddressOrAlias
taDestination :: SomeAddressOrAlias
  , TransferArgs -> Mutez
taAmount      :: Mutez
  , TransferArgs -> Value
taParameter   :: U.Value
  , TransferArgs -> Maybe Mutez
taMbFee :: Maybe Mutez
  }

morleyClientInfo :: Opt.ParserInfo ClientArgs
morleyClientInfo :: ParserInfo ClientArgs
morleyClientInfo =
  ("usage" :! Doc)
-> ("description" :! FilePath)
-> ("header" :! FilePath)
-> ("parser" :! Parser ClientArgs)
-> ParserInfo ClientArgs
forall s.
("usage" :! Doc)
-> ("description" :! FilePath)
-> ("header" :! FilePath)
-> ("parser" :! Parser s)
-> ParserInfo s
parserInfo
    (IsLabel "usage" (Name "usage")
Name "usage"
#usage Name "usage" -> Doc -> "usage" :! Doc
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! Doc
usageDoc)
    (IsLabel "description" (Name "description")
Name "description"
#description Name "description" -> FilePath -> "description" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"Morley Client: RPC client for interaction with tezos node")
    (IsLabel "header" (Name "header")
Name "header"
#header Name "header" -> FilePath -> "header" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"Morley Client")
    (IsLabel "parser" (Name "parser")
Name "parser"
#parser Name "parser" -> Parser ClientArgs -> "parser" :! Parser ClientArgs
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! Parser ClientArgs
clientParser)

-- | Parser for the @morley-client@ executable.
clientParser :: Opt.Parser ClientArgs
clientParser :: Parser ClientArgs
clientParser = MorleyClientConfig -> ClientArgsRaw -> ClientArgs
ClientArgs (MorleyClientConfig -> ClientArgsRaw -> ClientArgs)
-> Parser MorleyClientConfig
-> Parser (ClientArgsRaw -> ClientArgs)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser MorleyClientConfig
clientConfigParser Parser (ClientArgsRaw -> ClientArgs)
-> Parser ClientArgsRaw -> Parser ClientArgs
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ClientArgsRaw
argsRawParser

clientConfigParser :: Opt.Parser MorleyClientConfig
clientConfigParser :: Parser MorleyClientConfig
clientConfigParser = do
  let mccSecretKey :: Maybe a
mccSecretKey = Maybe a
forall a. Maybe a
Nothing
  Maybe BaseUrl
mccEndpointUrl <- Parser (Maybe BaseUrl)
endpointOption
  FilePath
mccTezosClientPath <- Parser FilePath
pathOption
  Maybe FilePath
mccMbTezosClientDataDir <- Parser (Maybe FilePath)
dataDirOption
  Word
mccVerbosity <- [()] -> Word
forall i a. Num i => [a] -> i
genericLength ([()] -> Word) -> Parser [()] -> Parser Word
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser () -> Parser [()]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many Parser ()
verboseSwitch
  pure MorleyClientConfig :: Maybe BaseUrl
-> FilePath
-> Maybe FilePath
-> Word
-> Maybe SecretKey
-> MorleyClientConfig
MorleyClientConfig{FilePath
Maybe FilePath
Maybe BaseUrl
Maybe SecretKey
Word
mccSecretKey :: Maybe SecretKey
mccVerbosity :: Word
mccMbTezosClientDataDir :: Maybe FilePath
mccTezosClientPath :: FilePath
mccEndpointUrl :: Maybe BaseUrl
mccVerbosity :: Word
mccMbTezosClientDataDir :: Maybe FilePath
mccTezosClientPath :: FilePath
mccEndpointUrl :: Maybe BaseUrl
mccSecretKey :: Maybe SecretKey
..}
  where
    verboseSwitch :: Opt.Parser ()
    verboseSwitch :: Parser ()
verboseSwitch = () -> Mod FlagFields () -> Parser ()
forall a. a -> Mod FlagFields a -> Parser a
Opt.flag' () (Mod FlagFields () -> Parser ())
-> ([Mod FlagFields ()] -> Mod FlagFields ())
-> [Mod FlagFields ()]
-> Parser ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Mod FlagFields ()] -> Mod FlagFields ()
forall a. Monoid a => [a] -> a
mconcat ([Mod FlagFields ()] -> Parser ())
-> [Mod FlagFields ()] -> Parser ()
forall a b. (a -> b) -> a -> b
$
      [ Char -> Mod FlagFields ()
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'V'
      , FilePath -> Mod FlagFields ()
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Increase verbosity (pass several times to increase further)."
      ]

-- | Parses URL of the Tezos node.
endpointOption :: Opt.Parser (Maybe BaseUrl)
endpointOption :: Parser (Maybe BaseUrl)
endpointOption = Parser BaseUrl -> Parser (Maybe BaseUrl)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser BaseUrl -> Parser (Maybe BaseUrl))
-> (Mod OptionFields BaseUrl -> Parser BaseUrl)
-> Mod OptionFields BaseUrl
-> Parser (Maybe BaseUrl)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReadM BaseUrl -> Mod OptionFields BaseUrl -> Parser BaseUrl
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM BaseUrl
baseUrlReader (Mod OptionFields BaseUrl -> Parser (Maybe BaseUrl))
-> Mod OptionFields BaseUrl -> Parser (Maybe BaseUrl)
forall a b. (a -> b) -> a -> b
$
  FilePath -> Mod OptionFields BaseUrl
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"endpoint"
  Mod OptionFields BaseUrl
-> Mod OptionFields BaseUrl -> Mod OptionFields BaseUrl
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields BaseUrl
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'E'
  Mod OptionFields BaseUrl
-> Mod OptionFields BaseUrl -> Mod OptionFields BaseUrl
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields BaseUrl
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"URL of the remote Tezos node."
  Mod OptionFields BaseUrl
-> Mod OptionFields BaseUrl -> Mod OptionFields BaseUrl
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields BaseUrl
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"URL"

pathOption :: Opt.Parser FilePath
pathOption :: Parser FilePath
pathOption = Mod OptionFields FilePath -> Parser FilePath
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields FilePath -> Parser FilePath)
-> Mod OptionFields FilePath -> Parser FilePath
forall a b. (a -> b) -> a -> b
$
  [Mod OptionFields FilePath] -> Mod OptionFields FilePath
forall a. Monoid a => [a] -> a
mconcat [ Char -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'I', FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"client-path", FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"PATH"
          , FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Path to `octez-client` binary."
          , FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value FilePath
"octez-client"
          , Mod OptionFields FilePath
forall a (f :: * -> *). Show a => Mod f a
Opt.showDefault
          ]

dataDirOption :: Opt.Parser (Maybe FilePath)
dataDirOption :: Parser (Maybe FilePath)
dataDirOption = Parser FilePath -> Parser (Maybe FilePath)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser FilePath -> Parser (Maybe FilePath))
-> Parser FilePath -> Parser (Maybe FilePath)
forall a b. (a -> b) -> a -> b
$ Mod OptionFields FilePath -> Parser FilePath
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields FilePath -> Parser FilePath)
-> Mod OptionFields FilePath -> Parser FilePath
forall a b. (a -> b) -> a -> b
$
  [Mod OptionFields FilePath] -> Mod OptionFields FilePath
forall a. Monoid a => [a] -> a
mconcat [ Char -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'd', FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"data-dir", FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"PATH"
          , FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Path to `octez-client` data directory."
          ]

feeOption :: Opt.Parser (Maybe Mutez)
feeOption :: Parser (Maybe Mutez)
feeOption = Parser Mutez -> Parser (Maybe Mutez)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser Mutez -> Parser (Maybe Mutez))
-> Parser Mutez -> Parser (Maybe Mutez)
forall a b. (a -> b) -> a -> b
$ Maybe Mutez
-> ("name" :! FilePath) -> ("help" :! FilePath) -> Parser Mutez
mutezOption
            Maybe Mutez
forall a. Maybe a
Nothing
            (IsLabel "name" (Name "name")
Name "name"
#name Name "name" -> FilePath -> "name" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"fee")
            (IsLabel "help" (Name "help")
Name "help"
#help Name "help" -> FilePath -> "help" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"Fee that is going to be used for the transaction. \
                      \By default fee will be computed automatically."
            )

-- | Generic parser to read an option of 'BlockId' type.
blockIdOption
  :: Maybe BlockId
  -> "name" :! String
  -> "help" :! String
  -> Opt.Parser BlockId
blockIdOption :: Maybe BlockId
-> ("name" :! FilePath) -> ("help" :! FilePath) -> Parser BlockId
blockIdOption = Maybe BlockId
-> ("name" :! FilePath) -> ("help" :! FilePath) -> Parser BlockId
forall a.
(Buildable a, HasCLReader a) =>
Maybe a -> ("name" :! FilePath) -> ("help" :! FilePath) -> Parser a
mkCLOptionParser

argsRawParser :: Opt.Parser ClientArgsRaw
argsRawParser :: Parser ClientArgsRaw
argsRawParser = Mod CommandFields ClientArgsRaw -> Parser ClientArgsRaw
forall a. Mod CommandFields a -> Parser a
subparser (Mod CommandFields ClientArgsRaw -> Parser ClientArgsRaw)
-> Mod CommandFields ClientArgsRaw -> Parser ClientArgsRaw
forall a b. (a -> b) -> a -> b
$ [Mod CommandFields ClientArgsRaw]
-> Mod CommandFields ClientArgsRaw
forall a. Monoid a => [a] -> a
mconcat
  [ Mod CommandFields ClientArgsRaw
originateCmd
  , Mod CommandFields ClientArgsRaw
transferCmd
  , Mod CommandFields ClientArgsRaw
getBalanceCmd
  , Mod CommandFields ClientArgsRaw
getScriptSizeCmd
  , Mod CommandFields ClientArgsRaw
getBlockHeaderCmd
  , Mod CommandFields ClientArgsRaw
getBlockOperationsCmd
  ]
  where
    originateCmd :: Mod CommandFields ClientArgsRaw
originateCmd =
      FilePath
-> Parser ClientArgsRaw
-> FilePath
-> Mod CommandFields ClientArgsRaw
forall a. FilePath -> Parser a -> FilePath -> Mod CommandFields a
mkCommandParser FilePath
"originate"
      (OriginateArgs -> ClientArgsRaw
Originate (OriginateArgs -> ClientArgsRaw)
-> Parser OriginateArgs -> Parser ClientArgsRaw
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser OriginateArgs
originateArgsOption)
      FilePath
"Originate passed contract on real network."
    transferCmd :: Mod CommandFields ClientArgsRaw
transferCmd =
      FilePath
-> Parser ClientArgsRaw
-> FilePath
-> Mod CommandFields ClientArgsRaw
forall a. FilePath -> Parser a -> FilePath -> Mod CommandFields a
mkCommandParser FilePath
"transfer"
      (TransferArgs -> ClientArgsRaw
Transfer (TransferArgs -> ClientArgsRaw)
-> Parser TransferArgs -> Parser ClientArgsRaw
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser TransferArgs
transferArgsOption)
      FilePath
"Perform a transfer to the given contract with given amount and parameter."
    getBalanceCmd :: Mod CommandFields ClientArgsRaw
getBalanceCmd =
      FilePath
-> Parser ClientArgsRaw
-> FilePath
-> Mod CommandFields ClientArgsRaw
forall a. FilePath -> Parser a -> FilePath -> Mod CommandFields a
mkCommandParser FilePath
"get-balance"
      ((AddressOrAlias 'AddressKindContract -> ClientArgsRaw
forall (kind :: AddressKind).
L1AddressKind kind =>
AddressOrAlias kind -> ClientArgsRaw
GetBalance (AddressOrAlias 'AddressKindContract -> ClientArgsRaw)
-> Parser (AddressOrAlias 'AddressKindContract)
-> Parser ClientArgsRaw
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
        forall (kind :: AddressKind).
(SingI kind, L1AddressKind kind) =>
Maybe (AddressOrAlias kind)
-> ("name" :! FilePath)
-> ("help" :! FilePath)
-> Parser (AddressOrAlias kind)
addressOrAliasOption @'AddressKindContract
          Maybe (AddressOrAlias 'AddressKindContract)
forall a. Maybe a
Nothing
          (IsLabel "name" (Name "name")
Name "name"
#name Name "name" -> FilePath -> "name" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"contract-addr")
          (IsLabel "help" (Name "help")
Name "help"
#help Name "help" -> FilePath -> "help" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"Contract address or alias to get balance for."))
      Parser ClientArgsRaw
-> Parser ClientArgsRaw -> Parser ClientArgsRaw
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (ImplicitAddressOrAlias -> ClientArgsRaw
forall (kind :: AddressKind).
L1AddressKind kind =>
AddressOrAlias kind -> ClientArgsRaw
GetBalance (ImplicitAddressOrAlias -> ClientArgsRaw)
-> Parser ImplicitAddressOrAlias -> Parser ClientArgsRaw
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (kind :: AddressKind).
(SingI kind, L1AddressKind kind) =>
Maybe (AddressOrAlias kind)
-> ("name" :! FilePath)
-> ("help" :! FilePath)
-> Parser (AddressOrAlias kind)
addressOrAliasOption @'AddressKindImplicit
          Maybe ImplicitAddressOrAlias
forall a. Maybe a
Nothing
          (IsLabel "name" (Name "name")
Name "name"
#name Name "name" -> FilePath -> "name" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"implicit-addr")
          (IsLabel "help" (Name "help")
Name "help"
#help Name "help" -> FilePath -> "help" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"Implicit address or alias to get balance for."))
      )
      FilePath
"Get balance for given address"
    getBlockHeaderCmd :: Mod CommandFields ClientArgsRaw
getBlockHeaderCmd =
      FilePath
-> Parser ClientArgsRaw
-> FilePath
-> Mod CommandFields ClientArgsRaw
forall a. FilePath -> Parser a -> FilePath -> Mod CommandFields a
mkCommandParser FilePath
"get-block-header"
      (BlockId -> ClientArgsRaw
GetBlockHeader (BlockId -> ClientArgsRaw)
-> Parser BlockId -> Parser ClientArgsRaw
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe BlockId
-> ("name" :! FilePath) -> ("help" :! FilePath) -> Parser BlockId
blockIdOption
        (BlockId -> Maybe BlockId
forall a. a -> Maybe a
Just BlockId
HeadId)
        (IsLabel "name" (Name "name")
Name "name"
#name Name "name" -> FilePath -> "name" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"block-id")
        (IsLabel "help" (Name "help")
Name "help"
#help Name "help" -> FilePath -> "help" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"Id of the block whose header will be queried.")
      )
      FilePath
"Get header of a block"
    getBlockOperationsCmd :: Mod CommandFields ClientArgsRaw
getBlockOperationsCmd =
      FilePath
-> Parser ClientArgsRaw
-> FilePath
-> Mod CommandFields ClientArgsRaw
forall a. FilePath -> Parser a -> FilePath -> Mod CommandFields a
mkCommandParser FilePath
"get-block-operations"
      (BlockId -> ClientArgsRaw
GetBlockOperations (BlockId -> ClientArgsRaw)
-> Parser BlockId -> Parser ClientArgsRaw
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe BlockId
-> ("name" :! FilePath) -> ("help" :! FilePath) -> Parser BlockId
blockIdOption
        (BlockId -> Maybe BlockId
forall a. a -> Maybe a
Just BlockId
HeadId)
        (IsLabel "name" (Name "name")
Name "name"
#name Name "name" -> FilePath -> "name" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"block-id")
        (IsLabel "help" (Name "help")
Name "help"
#help Name "help" -> FilePath -> "help" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"Id of the block whose operations will be queried.")
      )
      FilePath
"Get operations contained in a block"
    getScriptSizeCmd :: Mod CommandFields ClientArgsRaw
getScriptSizeCmd =
      FilePath
-> Parser ClientArgsRaw
-> FilePath
-> Mod CommandFields ClientArgsRaw
forall a. FilePath -> Parser a -> FilePath -> Mod CommandFields a
mkCommandParser FilePath
"compute-script-size"
      (GetScriptSizeArgs -> ClientArgsRaw
GetScriptSize (GetScriptSizeArgs -> ClientArgsRaw)
-> Parser GetScriptSizeArgs -> Parser ClientArgsRaw
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser GetScriptSizeArgs
getScriptSizeArgsOption)
      FilePath
"Compute script size"

originateArgsOption :: Opt.Parser OriginateArgs
originateArgsOption :: Parser OriginateArgs
originateArgsOption = do
  Maybe FilePath
oaMbContractFile <- Parser (Maybe FilePath)
mbContractFileOption
  ContractAlias
oaContractName <- Parser ContractAlias
contractNameOption
  Mutez
oaInitialBalance <-
    Maybe Mutez
-> ("name" :! FilePath) -> ("help" :! FilePath) -> Parser Mutez
mutezOption
      (Mutez -> Maybe Mutez
forall a. a -> Maybe a
Just Mutez
zeroMutez)
      (IsLabel "name" (Name "name")
Name "name"
#name Name "name" -> FilePath -> "name" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"initial-balance")
      (IsLabel "help" (Name "help")
Name "help"
#help Name "help" -> FilePath -> "help" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"Inital balance of the contract.")
  Value
oaInitialStorage <-
    Maybe Value
-> ("name" :! FilePath) -> ("help" :! FilePath) -> Parser Value
valueOption
      Maybe Value
forall a. Maybe a
Nothing
      (IsLabel "name" (Name "name")
Name "name"
#name Name "name" -> FilePath -> "name" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"initial-storage")
      (IsLabel "help" (Name "help")
Name "help"
#help Name "help" -> FilePath -> "help" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"Initial contract storage value.")
  ImplicitAddressOrAlias
oaOriginateFrom <-
    Maybe ImplicitAddressOrAlias
-> ("name" :! FilePath)
-> ("help" :! FilePath)
-> Parser ImplicitAddressOrAlias
forall (kind :: AddressKind).
(SingI kind, L1AddressKind kind) =>
Maybe (AddressOrAlias kind)
-> ("name" :! FilePath)
-> ("help" :! FilePath)
-> Parser (AddressOrAlias kind)
addressOrAliasOption
      Maybe ImplicitAddressOrAlias
forall a. Maybe a
Nothing
      (IsLabel "name" (Name "name")
Name "name"
#name Name "name" -> FilePath -> "name" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"from")
      (IsLabel "help" (Name "help")
Name "help"
#help Name "help" -> FilePath -> "help" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"Address or alias of address from which origination is performed.")
  Maybe Mutez
oaMbFee <- Parser (Maybe Mutez)
feeOption
  Maybe KeyHash
oaDelegate <- Parser KeyHash -> Parser (Maybe KeyHash)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser KeyHash -> Parser (Maybe KeyHash))
-> Parser KeyHash -> Parser (Maybe KeyHash)
forall a b. (a -> b) -> a -> b
$
    Maybe KeyHash
-> ("name" :! FilePath) -> ("help" :! FilePath) -> Parser KeyHash
keyHashOption
      Maybe KeyHash
forall a. Maybe a
Nothing
      (IsLabel "name" (Name "name")
Name "name"
#name Name "name" -> FilePath -> "name" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"delegate")
      (IsLabel "help" (Name "help")
Name "help"
#help Name "help" -> FilePath -> "help" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"Key hash of the contract's delegate")
  pure $ OriginateArgs :: Maybe FilePath
-> ContractAlias
-> Mutez
-> Value
-> ImplicitAddressOrAlias
-> Maybe Mutez
-> Maybe KeyHash
-> OriginateArgs
OriginateArgs {Maybe FilePath
Maybe KeyHash
Maybe Mutez
ImplicitAddressOrAlias
ContractAlias
Mutez
Value
oaDelegate :: Maybe KeyHash
oaMbFee :: Maybe Mutez
oaOriginateFrom :: ImplicitAddressOrAlias
oaInitialStorage :: Value
oaInitialBalance :: Mutez
oaContractName :: ContractAlias
oaMbContractFile :: Maybe FilePath
oaDelegate :: Maybe KeyHash
oaMbFee :: Maybe Mutez
oaOriginateFrom :: ImplicitAddressOrAlias
oaInitialStorage :: Value
oaInitialBalance :: Mutez
oaContractName :: ContractAlias
oaMbContractFile :: Maybe FilePath
..}

getScriptSizeArgsOption :: Opt.Parser GetScriptSizeArgs
getScriptSizeArgsOption :: Parser GetScriptSizeArgs
getScriptSizeArgsOption = FilePath -> Value -> GetScriptSizeArgs
GetScriptSizeArgs (FilePath -> Value -> GetScriptSizeArgs)
-> Parser FilePath -> Parser (Value -> GetScriptSizeArgs)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser FilePath
scriptFileOption
  Parser (Value -> GetScriptSizeArgs)
-> Parser Value -> Parser GetScriptSizeArgs
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe Value
-> ("name" :! FilePath) -> ("help" :! FilePath) -> Parser Value
valueOption Maybe Value
forall a. Maybe a
Nothing (IsLabel "name" (Name "name")
Name "name"
#name Name "name" -> FilePath -> "name" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"storage")
                          (IsLabel "help" (Name "help")
Name "help"
#help Name "help" -> FilePath -> "help" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"Contract storage value.")

mbContractFileOption :: Opt.Parser (Maybe FilePath)
mbContractFileOption :: Parser (Maybe FilePath)
mbContractFileOption = Parser FilePath -> Parser (Maybe FilePath)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser FilePath -> Parser (Maybe FilePath))
-> (Mod OptionFields FilePath -> Parser FilePath)
-> Mod OptionFields FilePath
-> Parser (Maybe FilePath)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mod OptionFields FilePath -> Parser FilePath
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields FilePath -> Parser (Maybe FilePath))
-> Mod OptionFields FilePath -> Parser (Maybe FilePath)
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields FilePath] -> Mod OptionFields FilePath
forall a. Monoid a => [a] -> a
mconcat
  [ FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"contract", FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"FILEPATH"
  , FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Path to contract file."
  ]

scriptFileOption :: Opt.Parser FilePath
scriptFileOption :: Parser FilePath
scriptFileOption = Mod OptionFields FilePath -> Parser FilePath
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields FilePath -> Parser FilePath)
-> Mod OptionFields FilePath -> Parser FilePath
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields FilePath] -> Mod OptionFields FilePath
forall a. Monoid a => [a] -> a
mconcat
  [ FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"script", FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"FILEPATH"
  , FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Path to script file."
  ]

contractNameOption :: Opt.Parser ContractAlias
contractNameOption :: Parser ContractAlias
contractNameOption = (Text -> ContractAlias) -> Parser Text -> Parser ContractAlias
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> ContractAlias
ContractAlias (Parser Text -> Parser ContractAlias)
-> (Mod OptionFields Text -> Parser Text)
-> Mod OptionFields Text
-> Parser ContractAlias
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mod OptionFields Text -> Parser Text
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields Text -> Parser ContractAlias)
-> Mod OptionFields Text -> Parser ContractAlias
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields Text] -> Mod OptionFields Text
forall a. Monoid a => [a] -> a
mconcat
  [ FilePath -> Mod OptionFields Text
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"contract-name"
  , Text -> Mod OptionFields Text
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value Text
"stdin"
  , FilePath -> Mod OptionFields Text
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Alias of originated contract."
  ]

transferArgsOption :: Opt.Parser TransferArgs
transferArgsOption :: Parser TransferArgs
transferArgsOption = do
  ImplicitAddressOrAlias
taSender <-
    Maybe ImplicitAddressOrAlias
-> ("name" :! FilePath)
-> ("help" :! FilePath)
-> Parser ImplicitAddressOrAlias
forall (kind :: AddressKind).
(SingI kind, L1AddressKind kind) =>
Maybe (AddressOrAlias kind)
-> ("name" :! FilePath)
-> ("help" :! FilePath)
-> Parser (AddressOrAlias kind)
addressOrAliasOption
      Maybe ImplicitAddressOrAlias
forall a. Maybe a
Nothing
      (IsLabel "name" (Name "name")
Name "name"
#name Name "name" -> FilePath -> "name" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"from")
      (IsLabel "help" (Name "help")
Name "help"
#help Name "help" -> FilePath -> "help" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"Address or alias from which transfer is performed.")
  SomeAddressOrAlias
taDestination <-
    Maybe SomeAddressOrAlias
-> ("name" :! FilePath)
-> ("help" :! FilePath)
-> Parser SomeAddressOrAlias
someAddressOrAliasOption
      Maybe SomeAddressOrAlias
forall a. Maybe a
Nothing
      (IsLabel "name" (Name "name")
Name "name"
#name Name "name" -> FilePath -> "name" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"to")
      (IsLabel "help" (Name "help")
Name "help"
#help Name "help" -> FilePath -> "help" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"Address or alias of the transfer's destination.")
  Mutez
taAmount <-
    Maybe Mutez
-> ("name" :! FilePath) -> ("help" :! FilePath) -> Parser Mutez
mutezOption
      (Mutez -> Maybe Mutez
forall a. a -> Maybe a
Just Mutez
zeroMutez)
      (IsLabel "name" (Name "name")
Name "name"
#name Name "name" -> FilePath -> "name" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"amount")
      (IsLabel "help" (Name "help")
Name "help"
#help Name "help" -> FilePath -> "help" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"Transfer amount.")
  Value
taParameter <-
    Maybe Value
-> ("name" :! FilePath) -> ("help" :! FilePath) -> Parser Value
valueOption
      Maybe Value
forall a. Maybe a
Nothing
      (IsLabel "name" (Name "name")
Name "name"
#name Name "name" -> FilePath -> "name" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"parameter")
      (IsLabel "help" (Name "help")
Name "help"
#help Name "help" -> FilePath -> "help" :! FilePath
forall (name :: Symbol) a. Name name -> a -> NamedF Identity a name
:! FilePath
"Transfer parameter.")
  Maybe Mutez
taMbFee <- Parser (Maybe Mutez)
feeOption
  pure $ TransferArgs :: ImplicitAddressOrAlias
-> SomeAddressOrAlias
-> Mutez
-> Value
-> Maybe Mutez
-> TransferArgs
TransferArgs {Maybe Mutez
ImplicitAddressOrAlias
SomeAddressOrAlias
Mutez
Value
taMbFee :: Maybe Mutez
taParameter :: Value
taAmount :: Mutez
taDestination :: SomeAddressOrAlias
taSender :: ImplicitAddressOrAlias
taMbFee :: Maybe Mutez
taParameter :: Value
taAmount :: Mutez
taDestination :: SomeAddressOrAlias
taSender :: ImplicitAddressOrAlias
..}

usageDoc :: Doc
usageDoc :: Doc
usageDoc = [Doc] -> Doc
forall a. Monoid a => [a] -> a
mconcat
  [ Doc
"You can use help for specific COMMAND", Doc
linebreak
  , Doc
"EXAMPLE:", Doc
linebreak
  , Doc
"morley-client originate --help"
  , Doc
"USAGE EXAMPLE:", Doc
linebreak
  , Doc
"morley-client -E florence.testnet.tezos.serokell.team:8732 originate \\", Doc
linebreak
  , Doc
"  --from tz1akcPmG1Kyz2jXpS4RvVJ8uWr7tsiT9i6A \\", Doc
linebreak
  , Doc
"  --contract ../contracts/tezos_examples/attic/add1.tz --initial-balance 1 --initial-storage 0", Doc
linebreak
  , Doc
linebreak
  , Doc
"  This command will originate contract with code stored in add1.tz", Doc
linebreak
  , Doc
"  on real network with initial balance 1 and initial storage set to 0", Doc
linebreak
  , Doc
"  and return info about operation: operation hash and originated contract address", Doc
linebreak
  , Doc
linebreak
  , Doc
"morley-client -E florence.testnet.tezos.serokell.team:8732 transfer \\", Doc
linebreak
  , Doc
"  --from tz1akcPmG1Kyz2jXpS4RvVJ8uWr7tsiT9i6A \\", Doc
linebreak
  , Doc
"  --to KT1USbmjj6P2oJ54UM6HxBZgpoPtdiRSVABW --amount 1 --parameter 0", Doc
linebreak
  , Doc
linebreak
  , Doc
"  This command will perform tranfer to contract with address on real network", Doc
linebreak
  , Doc
"  KT1USbmjj6P2oJ54UM6HxBZgpoPtdiRSVABW with amount 1 and parameter 0", Doc
linebreak
  , Doc
"  as a result it will return operation hash"
  ]

--------------------------------------------------------------------------------
-- Parser utilities
--------------------------------------------------------------------------------

-- | Utility reader to use in parsing 'BaseUrl'.
baseUrlReader :: ReadM BaseUrl
baseUrlReader :: ReadM BaseUrl
baseUrlReader = (FilePath -> Either FilePath BaseUrl) -> ReadM BaseUrl
forall a. (FilePath -> Either FilePath a) -> ReadM a
eitherReader ((FilePath -> Either FilePath BaseUrl) -> ReadM BaseUrl)
-> (FilePath -> Either FilePath BaseUrl) -> ReadM BaseUrl
forall a b. (a -> b) -> a -> b
$ (SomeException -> FilePath)
-> Either SomeException BaseUrl -> Either FilePath BaseUrl
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first SomeException -> FilePath
forall e. Exception e => e -> FilePath
displayException (Either SomeException BaseUrl -> Either FilePath BaseUrl)
-> (FilePath -> Either SomeException BaseUrl)
-> FilePath
-> Either FilePath BaseUrl
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> Either SomeException BaseUrl
forall (m :: * -> *). MonadThrow m => FilePath -> m BaseUrl
parseBaseUrl