Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make transaction view emit JSON #319

Merged
merged 5 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cardano-cli/src/Cardano/CLI/EraBased/Commands/Transaction.hs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ data TransactionCmds era
| TxGetTxId
InputTxBodyOrTxFile
| TxView
TxViewOutputFormat
(Maybe (File () Out))
InputTxBodyOrTxFile

renderTransactionCmds :: TransactionCmds era -> Text
Expand Down
12 changes: 12 additions & 0 deletions cardano-cli/src/Cardano/CLI/EraBased/Options/Common.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1560,6 +1560,18 @@ pPoolIdOutputFormat =
, Opt.value IdOutputFormatBech32
]

pTxViewOutputFormat :: Parser TxViewOutputFormat
pTxViewOutputFormat =
Opt.option readTxViewOutputFormat $ mconcat
[ Opt.long "output-format"
, Opt.metavar "STRING"
, Opt.help $ mconcat
[ "Optional transaction view output format. Accepted output formats are \"json\" "
, "and \"yaml\" (default is \"json\")."
]
, Opt.value TxViewOutputFormatJson
]

pMaybeOutputFile :: Parser (Maybe (File content Out))
pMaybeOutputFile =
optional $ fmap File $ Opt.strOption $ mconcat
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,4 +276,4 @@ pTransactionId :: Parser (TransactionCmds era)
pTransactionId = TxGetTxId <$> pInputTxOrTxBodyFile

pTransactionView :: Parser (TransactionCmds era)
pTransactionView = TxView <$> pInputTxOrTxBodyFile
pTransactionView = TxView <$> pTxViewOutputFormat <*> pMaybeOutputFile <*> pInputTxOrTxBodyFile
carlhammann marked this conversation as resolved.
Show resolved Hide resolved
31 changes: 21 additions & 10 deletions cardano-cli/src/Cardano/CLI/EraBased/Run/Transaction.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ import Cardano.Api.Shelley

import Cardano.CLI.EraBased.Commands.Transaction
import Cardano.CLI.EraBased.Run.Genesis
import Cardano.CLI.Json.Friendly (friendlyTxBS, friendlyTxBodyBS)
import Cardano.CLI.Json.Friendly (friendlyTxBodyJson, friendlyTxBodyYaml, friendlyTxJson,
friendlyTxYaml)
import Cardano.CLI.Read
import Cardano.CLI.Types.Common
import Cardano.CLI.Types.Errors.BootstrapWitnessError
Expand Down Expand Up @@ -103,8 +104,8 @@ runTransactionCmds cmd =
runTxHashScriptDataCmd scriptDataOrFile
TxGetTxId txinfile ->
runTxGetTxIdCmd txinfile
TxView txinfile ->
runTxViewCmd txinfile
TxView outFormat mOutFile txinfile ->
runTxViewCmd outFormat mOutFile txinfile
TxMintedPolicyId sFile ->
runTxCreatePolicyIdCmd sFile
TxCreateWitness txBodyfile witSignData mbNw outFile ->
Expand Down Expand Up @@ -1173,9 +1174,11 @@ runTxGetTxIdCmd txfile = do
liftIO $ BS.putStrLn $ serialiseToRawBytesHex (getTxId txbody)

runTxViewCmd :: ()
=> InputTxBodyOrTxFile
=> TxViewOutputFormat
-> Maybe (File () Out)
-> InputTxBodyOrTxFile
-> ExceptT TxCmdError IO ()
runTxViewCmd = \case
runTxViewCmd yamlOrJson mOutFile = \case
InputTxBodyFile (File txbodyFilePath) -> do
txbodyFile <- liftIO $ fileOrPipe txbodyFilePath
unwitnessed <- firstExceptT TxCmdCddlError . newExceptT
Expand All @@ -1185,14 +1188,22 @@ runTxViewCmd = \case
UnwitnessedCliFormattedTxBody anyTxBody -> pure anyTxBody
IncompleteCddlFormattedTx (InAnyCardanoEra era tx) ->
pure $ InAnyCardanoEra era (getTxBody tx)
--TODO: Why are we maintaining friendlyTxBodyBS and friendlyTxBS?
-- In the case of a transaction body, we can simply call makeSignedTransaction []
-- to get a transaction which allows us to reuse friendlyTxBS!
liftIO $ BS.putStr $ friendlyTxBodyBS era txbody
-- Why are we differentiating between a transaction body and a transaction?
-- In the case of a transaction body, we /could/ simply call @makeSignedTransaction []@
-- to get a transaction which would allow us to reuse friendlyTxBS. However,
-- this would mean that we'd have an empty list of witnesses mentioned in the output, which
-- is arguably not part of the transaction body.
firstExceptT TxCmdWriteFileError . newExceptT $
case yamlOrJson of
TxViewOutputFormatYaml -> friendlyTxBodyYaml mOutFile era txbody
TxViewOutputFormatJson -> friendlyTxBodyJson mOutFile era txbody
InputTxFile (File txFilePath) -> do
txFile <- liftIO $ fileOrPipe txFilePath
InAnyCardanoEra era tx <- lift (readFileTx txFile) & onLeft (left . TxCmdCddlError)
liftIO $ BS.putStr $ friendlyTxBS era tx
firstExceptT TxCmdWriteFileError . newExceptT $
case yamlOrJson of
TxViewOutputFormatYaml -> friendlyTxYaml mOutFile era tx
TxViewOutputFormatJson -> friendlyTxJson mOutFile era tx


-- ----------------------------------------------------------------------------
Expand Down
57 changes: 49 additions & 8 deletions cardano-cli/src/Cardano/CLI/Json/Friendly.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
{-# LANGUAGE TypeOperators #-}

-- | User-friendly pretty-printing for textual user interfaces (TUI)
module Cardano.CLI.Json.Friendly (friendlyTxBS, friendlyTxBodyBS) where
module Cardano.CLI.Json.Friendly (friendlyTxYaml, friendlyTxBodyYaml, friendlyTxJson, friendlyTxBodyJson) where

import Cardano.Api as Api
import Cardano.Api.Byron (KeyWitness (ByronKeyWitness))
Expand All @@ -29,7 +29,6 @@ import Data.Aeson (Value (..), object, toJSON, (.=))
import qualified Data.Aeson as Aeson
import qualified Data.Aeson.Key as Aeson
import qualified Data.Aeson.Types as Aeson
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as BSC
import Data.Char (isAscii)
import Data.Function ((&))
Expand All @@ -43,12 +42,58 @@ import Data.Yaml.Pretty (setConfCompare)
import qualified Data.Yaml.Pretty as Yaml
import GHC.Real (denominator)
import GHC.Unicode (isAlphaNum)
import qualified Data.Aeson.Encode.Pretty as Aeson
import Control.Monad.Trans (MonadIO)

jsonConfig :: Aeson.Config
jsonConfig = Aeson.defConfig {Aeson.confCompare = compare}

friendlyTxJson ::
(MonadIO m, IsCardanoEra era)
carlhammann marked this conversation as resolved.
Show resolved Hide resolved
=> Maybe (File () Out)
-> CardanoEra era
-> Tx era
-> m (Either (FileError e) ())
friendlyTxJson mOutFile era = writeLazyByteStringOutput mOutFile .
Aeson.encodePretty' jsonConfig .
object .
friendlyTx era

friendlyTxBodyJson ::
(MonadIO m, IsCardanoEra era)
carlhammann marked this conversation as resolved.
Show resolved Hide resolved
=> Maybe (File () Out)
-> CardanoEra era
-> TxBody era
-> m (Either (FileError e) ())
friendlyTxBodyJson mOutFile era = writeLazyByteStringOutput mOutFile .
Aeson.encodePretty' jsonConfig .
object .
friendlyTxBody era

yamlConfig :: Yaml.Config
yamlConfig = Yaml.defConfig & setConfCompare compare

friendlyTxBS :: IsCardanoEra era => CardanoEra era -> Tx era -> ByteString
friendlyTxBS era = Yaml.encodePretty yamlConfig . object . friendlyTx era
friendlyTxYaml ::
(MonadIO m, IsCardanoEra era)
carlhammann marked this conversation as resolved.
Show resolved Hide resolved
=> Maybe (File () Out)
-> CardanoEra era
-> Tx era
-> m (Either (FileError e) ())
friendlyTxYaml mOutFile era = writeByteStringOutput mOutFile .
Yaml.encodePretty yamlConfig .
object .
friendlyTx era

friendlyTxBodyYaml ::
(MonadIO m, IsCardanoEra era)
carlhammann marked this conversation as resolved.
Show resolved Hide resolved
=> Maybe (File () Out)
-> CardanoEra era
-> TxBody era
-> m (Either (FileError e) ())
friendlyTxBodyYaml mOutFile era = writeByteStringOutput mOutFile .
Yaml.encodePretty yamlConfig .
object .
friendlyTxBody era

friendlyTx :: IsCardanoEra era => CardanoEra era -> Tx era -> [Aeson.Pair]
friendlyTx era (Tx body witnesses) =
Expand All @@ -64,10 +109,6 @@ friendlyKeyWitness =
ShelleyKeyWitness _era (Shelley.WitVKey key signature) ->
["key" .= textShow key, "signature" .= textShow signature]

friendlyTxBodyBS :: IsCardanoEra era => CardanoEra era -> TxBody era -> ByteString
friendlyTxBodyBS era =
Yaml.encodePretty yamlConfig . object . friendlyTxBody era

friendlyTxBody :: IsCardanoEra era => CardanoEra era -> TxBody era -> [Aeson.Pair]
friendlyTxBody
era
Expand Down
2 changes: 2 additions & 0 deletions cardano-cli/src/Cardano/CLI/Legacy/Commands/Transaction.hs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ data LegacyTransactionCmds
| TxGetTxId
InputTxBodyOrTxFile
| TxView
TxViewOutputFormat
(Maybe (File () Out))
InputTxBodyOrTxFile

renderLegacyTransactionCmds :: LegacyTransactionCmds -> Text
Expand Down
2 changes: 1 addition & 1 deletion cardano-cli/src/Cardano/CLI/Legacy/Options.hs
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ pTransaction envCli =
pTransactionId = TxGetTxId <$> pInputTxOrTxBodyFile

pTransactionView :: Parser LegacyTransactionCmds
pTransactionView = TxView <$> pInputTxOrTxBodyFile
pTransactionView = TxView <$> pTxViewOutputFormat <*> pMaybeOutputFile <*> pInputTxOrTxBodyFile
carlhammann marked this conversation as resolved.
Show resolved Hide resolved

pNodeCmds :: Parser LegacyNodeCmds
pNodeCmds =
Expand Down
6 changes: 3 additions & 3 deletions cardano-cli/src/Cardano/CLI/Legacy/Run/Transaction.hs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ runLegacyTransactionCmds cmd =
runLegacyTxHashScriptDataCmd scriptDataOrFile
TxGetTxId txinfile ->
runLegacyTxGetTxIdCmd txinfile
TxView txinfile ->
runLegacyTxViewCmd txinfile
TxView yamlOrJson mOutFile txinfile ->
runLegacyTxViewCmd yamlOrJson mOutFile txinfile
TxMintedPolicyId sFile ->
runLegacyTxCreatePolicyIdCmd sFile
TxCreateWitness txBodyfile witSignData mbNw outFile ->
Expand Down Expand Up @@ -158,7 +158,7 @@ runLegacyTxHashScriptDataCmd = runTxHashScriptDataCmd
runLegacyTxGetTxIdCmd :: InputTxBodyOrTxFile -> ExceptT TxCmdError IO ()
runLegacyTxGetTxIdCmd = runTxGetTxIdCmd

runLegacyTxViewCmd :: InputTxBodyOrTxFile -> ExceptT TxCmdError IO ()
runLegacyTxViewCmd :: TxViewOutputFormat -> Maybe (File () Out) -> InputTxBodyOrTxFile -> ExceptT TxCmdError IO ()
runLegacyTxViewCmd = runTxViewCmd

runLegacyTxCreateWitnessCmd :: ()
Expand Down
13 changes: 13 additions & 0 deletions cardano-cli/src/Cardano/CLI/Parser.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module Cardano.CLI.Parser
, readFractionAsRational
, readKeyOutputFormat
, readIdOutputFormat
, readTxViewOutputFormat
, readRational
, readRationalUnitInterval
, readStringOfMaxLength
Expand Down Expand Up @@ -49,6 +50,18 @@ readKeyOutputFormat = do
, ". Accepted output formats are \"text-envelope\" and \"bech32\"."
]

readTxViewOutputFormat :: Opt.ReadM TxViewOutputFormat
readTxViewOutputFormat = do
s <- Opt.str @String
case s of
"json" -> pure TxViewOutputFormatJson
"yaml" -> pure TxViewOutputFormatYaml
_ ->
fail $ mconcat
[ "Invalid transaction view output format: " <> show s
, ". Accepted output formats are \"json\" and \"yaml\"."
]

readURIOfMaxLength :: Int -> Opt.ReadM Text
readURIOfMaxLength maxLen =
Text.pack <$> readStringOfMaxLength maxLen
Expand Down
6 changes: 6 additions & 0 deletions cardano-cli/src/Cardano/CLI/Types/Common.hs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ module Cardano.CLI.Types.Common
, TxOutCount(..)
, TxOutDatumAnyEra (..)
, TxShelleyWitnessCount(..)
, TxViewOutputFormat(..)
, UpdateProposalFile (..)
, VerificationKeyBase64(..)
, VerificationKeyFile
Expand Down Expand Up @@ -431,6 +432,11 @@ data TxMempoolQuery =
| TxMempoolQueryInfo
deriving Show

data TxViewOutputFormat
= TxViewOutputFormatJson
| TxViewOutputFormatYaml
deriving Show

--
-- Shelley CLI flag/option data types
--
Expand Down
Loading