diff --git a/cardano-api/cardano-api.cabal b/cardano-api/cardano-api.cabal index bea034bde34..7803fa9e1d6 100644 --- a/cardano-api/cardano-api.cabal +++ b/cardano-api/cardano-api.cabal @@ -32,6 +32,7 @@ library Cardano.Api.Protocol.Cardano Cardano.Api.Protocol.Shelley Cardano.Api.Protocol.Types + Cardano.Api.Query Cardano.Api.Shelley.Genesis Cardano.Api.TxInMode Cardano.Api.TxSubmit @@ -62,7 +63,7 @@ library Cardano.Api.NetworkId Cardano.Api.OperationalCertificate -- TODO: move here Cardano.Api.ProtocolParameters - Cardano.Api.Query +-- TODO: move here Cardano.Api.Query Cardano.Api.Script Cardano.Api.SerialiseBech32 Cardano.Api.SerialiseCBOR diff --git a/cardano-api/src/Cardano/Api/Address.hs b/cardano-api/src/Cardano/Api/Address.hs index 73e003dacf5..66da0a30dcc 100644 --- a/cardano-api/src/Cardano/Api/Address.hs +++ b/cardano-api/src/Cardano/Api/Address.hs @@ -64,6 +64,8 @@ module Cardano.Api.Address ( import Prelude +import Data.Aeson (ToJSON (..)) +import qualified Data.Aeson as Aeson import qualified Data.ByteString.Base58 as Base58 import Data.Text (Text) import qualified Data.Text.Encoding as Text @@ -312,6 +314,9 @@ data AddressInEra era where -> Address addrtype -> AddressInEra era +instance IsCardanoEra era => ToJSON (AddressInEra era) where + toJSON = Aeson.String . serialiseAddress + instance Eq (AddressInEra era) where (==) (AddressInEra ByronAddressInAnyEra addr1) (AddressInEra ByronAddressInAnyEra addr2) = addr1 == addr2 diff --git a/cardano-api/src/Cardano/Api/Query.hs b/cardano-api/src/Cardano/Api/Query.hs index 1f01f555503..0301c70b9dc 100644 --- a/cardano-api/src/Cardano/Api/Query.hs +++ b/cardano-api/src/Cardano/Api/Query.hs @@ -1,6 +1,8 @@ +{-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE EmptyCase #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GADTs #-} +{-# LANGUAGE GeneralisedNewtypeDeriving #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE StandaloneDeriving #-} @@ -29,6 +31,7 @@ module Cardano.Api.Query ( ProtocolState(..), ) where +import Data.Aeson (ToJSON) import Data.Bifunctor (bimap) import Data.Map (Map) import qualified Data.Map as Map @@ -160,6 +163,7 @@ newtype LedgerState era newtype ProtocolState era = ProtocolState (Serialised (Shelley.ChainDepState (Ledger.Crypto (ShelleyLedgerEra era)))) +deriving newtype instance IsCardanoEra era => ToJSON (UTxO era) toShelleyAddrSet :: CardanoEra era -> Set AddressAny @@ -191,6 +195,10 @@ fromUTxO eraConversion utxo = let Shelley.UTxO sUtxo = utxo in UTxO . Map.fromList . map (bimap fromShelleyTxIn (fromTxOut ShelleyBasedEraMary)) $ Map.toList sUtxo +--toUTxO :: ShelleyBasedEra era -> UTxO era -> Shelley.UTxO +--toUTxO = -- Left off here...perhaps we want to convert to API types instead for printing? + -- I.e instead of exposing the underlying ledger specs types, expose the api types. + fromShelleyPoolDistr :: Shelley.PoolDistr StandardCrypto -> Map (Hash StakePoolKey) Rational fromShelleyPoolDistr = diff --git a/cardano-api/src/Cardano/Api/TxBody.hs b/cardano-api/src/Cardano/Api/TxBody.hs index 3f7db04451c..edcf0fc0dfc 100644 --- a/cardano-api/src/Cardano/Api/TxBody.hs +++ b/cardano-api/src/Cardano/Api/TxBody.hs @@ -1,4 +1,5 @@ -{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE EmptyCase #-} {-# LANGUAGE FlexibleContexts #-} @@ -95,6 +96,9 @@ module Cardano.Api.TxBody ( import Prelude +import Data.Aeson (ToJSON (..)) +import qualified Data.Aeson as Aeson +import Data.Aeson.Types (ToJSONKey (..), toJSONKeyText) import Data.Bifunctor (first) import Data.ByteString (ByteString) import qualified Data.ByteString.Lazy as LBS @@ -106,7 +110,9 @@ import Data.Maybe (fromMaybe) import qualified Data.Sequence.Strict as Seq import qualified Data.Set as Set import Data.String (IsString) +import qualified Data.Text as Text import Data.Word (Word64) +import GHC.Generics import Control.Monad (guard) @@ -169,6 +175,8 @@ newtype TxId = TxId (Shelley.Hash StandardCrypto Shelley.EraIndependentTxBody) deriving newtype (IsString) -- We use the Shelley representation and convert the Byron one +deriving newtype instance ToJSON TxId + instance HasTypeProxy TxId where data AsType TxId = AsTxId proxyToAsType _ = AsTxId @@ -224,11 +232,16 @@ getTxId (ShelleyTxBody era tx _) = -- data TxIn = TxIn TxId TxIx - deriving (Eq, Ord, Show) + deriving (Eq, Generic, Ord, Show) + +deriving instance ToJSON TxIn +instance ToJSONKey TxIn where + toJSONKey = toJSONKeyText (\txIn -> Text.pack $ show txIn) newtype TxIx = TxIx Word deriving stock (Eq, Ord, Show) deriving newtype (Enum) + deriving newtype ToJSON fromByronTxIn :: Byron.TxIn -> TxIn fromByronTxIn (Byron.TxInUtxo txId index) = @@ -255,8 +268,11 @@ fromShelleyTxIn (Shelley.TxIn txid txix) = -- Transaction outputs -- -data TxOut era = TxOut (AddressInEra era) (TxOutValue era) +data TxOut era + = TxOut (AddressInEra era) (TxOutValue era) + deriving Generic +deriving instance IsCardanoEra era => ToJSON (TxOut era) deriving instance Eq (TxOut era) deriving instance Show (TxOut era) @@ -330,6 +346,9 @@ data MultiAssetSupportedInEra era where deriving instance Eq (MultiAssetSupportedInEra era) deriving instance Show (MultiAssetSupportedInEra era) +instance ToJSON (MultiAssetSupportedInEra era) where + toJSON = Aeson.String . Text.pack . show + -- | A representation of whether the era supports only ada transactions. -- -- Prior to the Mary era only ada transactions are supported. Multi-assets are @@ -347,6 +366,9 @@ data OnlyAdaSupportedInEra era where deriving instance Eq (OnlyAdaSupportedInEra era) deriving instance Show (OnlyAdaSupportedInEra era) +instance ToJSON (OnlyAdaSupportedInEra era) where + toJSON = Aeson.String . Text.pack . show + multiAssetSupportedInEra :: CardanoEra era -> Either (OnlyAdaSupportedInEra era) (MultiAssetSupportedInEra era) @@ -589,7 +611,8 @@ data TxOutValue era where deriving instance Eq (TxOutValue era) deriving instance Show (TxOutValue era) - +deriving instance ToJSON (TxOutValue era) +deriving instance Generic (TxOutValue era) -- ---------------------------------------------------------------------------- -- Transaction fees diff --git a/cardano-cli/src/Cardano/CLI/Shelley/Commands.hs b/cardano-cli/src/Cardano/CLI/Shelley/Commands.hs index 53f68c0937c..37801c87991 100644 --- a/cardano-cli/src/Cardano/CLI/Shelley/Commands.hs +++ b/cardano-cli/src/Cardano/CLI/Shelley/Commands.hs @@ -276,7 +276,7 @@ data QueryCmd = | QueryTip AnyConsensusModeParams NetworkId (Maybe OutputFile) | QueryStakeDistribution AnyCardanoEra AnyConsensusModeParams NetworkId (Maybe OutputFile) | QueryStakeAddressInfo AnyCardanoEra AnyConsensusModeParams StakeAddress NetworkId (Maybe OutputFile) - | QueryUTxO AnyCardanoEra Protocol QueryFilter NetworkId (Maybe OutputFile) + | QueryUTxO AnyCardanoEra AnyConsensusModeParams QueryFilter NetworkId (Maybe OutputFile) | QueryLedgerState AnyCardanoEra Protocol NetworkId (Maybe OutputFile) | QueryProtocolState AnyCardanoEra Protocol NetworkId (Maybe OutputFile) deriving Show diff --git a/cardano-cli/src/Cardano/CLI/Shelley/Parsers.hs b/cardano-cli/src/Cardano/CLI/Shelley/Parsers.hs index 704cd68a58b..c643423a435 100644 --- a/cardano-cli/src/Cardano/CLI/Shelley/Parsers.hs +++ b/cardano-cli/src/Cardano/CLI/Shelley/Parsers.hs @@ -677,7 +677,7 @@ pQueryCmd = pQueryUTxO = QueryUTxO <$> pCardanoEra - <*> pProtocol + <*> pConsensusModeParams <*> pQueryFilter <*> pNetworkId <*> pMaybeOutputFile diff --git a/cardano-cli/src/Cardano/CLI/Shelley/Run/Query.hs b/cardano-cli/src/Cardano/CLI/Shelley/Run/Query.hs index 184f2ff99f2..8608fb6827f 100644 --- a/cardano-cli/src/Cardano/CLI/Shelley/Run/Query.hs +++ b/cardano-cli/src/Cardano/CLI/Shelley/Run/Query.hs @@ -42,6 +42,7 @@ import Cardano.Api.Modes (AnyConsensusMode (..), AnyConsensusModeParam import qualified Cardano.Api.Modes as Mode import Cardano.Api.Protocol (Protocol, withlocalNodeConnectInfo) import Cardano.Api.ProtocolParameters +import qualified Cardano.Api.Query as Query import Cardano.Api.Shelley import Cardano.CLI.Environment (EnvSocketError, readEnvSocketPath, renderEnvSocketError) @@ -60,15 +61,9 @@ import qualified Ouroboros.Consensus.Cardano.Block as Consensus import Ouroboros.Consensus.HardFork.Combinator.Degenerate as Consensus import Ouroboros.Network.Block (Serialised (..), getTipPoint) -import qualified Cardano.Ledger.Core as Ledger -import qualified Cardano.Ledger.Era as Ledger - -import qualified Shelley.Spec.Ledger.Address as Ledger import qualified Shelley.Spec.Ledger.API.Protocol as Ledger import Shelley.Spec.Ledger.LedgerState (NewEpochState) import Shelley.Spec.Ledger.Scripts () -import qualified Shelley.Spec.Ledger.TxBody as Shelley (TxId (..), TxIn (..), TxOut (..)) -import qualified Shelley.Spec.Ledger.UTxO as Shelley (UTxO (..)) import qualified Ouroboros.Consensus.Shelley.Ledger as Consensus import Ouroboros.Consensus.Shelley.Protocol (StandardCrypto) @@ -87,6 +82,8 @@ data ShelleyQueryCmdError | ShelleyQueryCmdAcquireFailure !AcquireFailure | ShelleyQueryCmdEraConsensusModeMismatch !AnyCardanoEra !AnyConsensusMode | ShelleyQueryCmdByronEra + | ShelleyQueryCmdByronEraDetected + | ShelleyQueryCmdEraMismatch !EraMismatch deriving Show renderShelleyQueryCmdError :: ShelleyQueryCmdError -> Text @@ -97,10 +94,14 @@ renderShelleyQueryCmdError err = ShelleyQueryCmdWriteFileError fileErr -> Text.pack (displayError fileErr) ShelleyQueryCmdHelpersError helpersErr -> renderHelpersError helpersErr ShelleyQueryCmdAcquireFailure aqFail -> Text.pack $ show aqFail - ShelleyQueryCmdEraConsensusModeMismatch (AnyCardanoEra era) (AnyConsensusMode cmode) -> - "Consensus mode and era mismatch. Consensus mode: " <> show cmode <> - " Era: " <> show era ShelleyQueryCmdByronEra -> "Query was submitted in the Byron era. Expected Shelley era." + ShelleyQueryCmdByronEraDetected -> "This query cannot be used for the Byron era" + ShelleyQueryCmdEraConsensusModeMismatch (AnyCardanoEra era) (AnyConsensusMode cMode) -> + "Consensus mode and era mismatch. Consensus mode: " <> show cMode <> + " Era: " <> show era + ShelleyQueryCmdEraMismatch (EraMismatch ledgerEra queryEra) -> + "An error mismatch occured. Specified query era: " <> queryEra <> + "Current ledger era: " <> ledgerEra runQueryCmd :: QueryCmd -> ExceptT ShelleyQueryCmdError IO () runQueryCmd cmd = @@ -182,29 +183,55 @@ runQueryTip (AnyConsensusModeParams cModeParams) network mOutFile = do Just (OutputFile fpath) -> liftIO $ LBS.writeFile fpath output Nothing -> liftIO $ LBS.putStrLn output +-- | Query the UTxO, filtered by a given set of addresses, from a Shelley node +-- via the local state query protocol. +-- runQueryUTxO :: AnyCardanoEra - -> Protocol + -> AnyConsensusModeParams -> QueryFilter -> NetworkId -> Maybe OutputFile -> ExceptT ShelleyQueryCmdError IO () -runQueryUTxO (AnyCardanoEra era) protocol qfilter network mOutFile - | ShelleyBasedEra era' <- cardanoEraStyle era = +runQueryUTxO anyEra@(AnyCardanoEra era) (AnyConsensusModeParams cModeParams) + qfilter network mOutFile = do + SocketPath sockPath <- firstExceptT ShelleyQueryCmdEnvVarSocketErr readEnvSocketPath + let consensusMode = NewIPC.consensusModeOnly cModeParams + eraInMode <- hoistMaybe (ShelleyQueryCmdEraConsensusModeMismatch anyEra (AnyConsensusMode consensusMode)) + $ toEraInMode era consensusMode + let localNodeConnInfo = NewIPC.LocalNodeConnectInfo cModeParams network sockPath - -- Obtain the required type equality constaints and class constaints - obtainToJSONValue era' $ - obtainLedgerEraClassConstraints era' $ do + sbe <- getSbe $ cardanoEraStyle era - SocketPath sockPath <- firstExceptT ShelleyQueryCmdEnvVarSocketErr readEnvSocketPath - filteredUtxo <- firstExceptT ShelleyQueryCmdLocalStateQueryError $ - withlocalNodeConnectInfo protocol network sockPath $ - queryUTxOFromLocalState era' qfilter - writeFilteredUTxOs era' mOutFile filteredUtxo + qInMode <- createQuery sbe eraInMode + + tip <- liftIO $ NewIPC.getLocalChainTip localNodeConnInfo + eUtxo <- liftIO $ NewIPC.queryNodeLocalState localNodeConnInfo tip qInMode + case eUtxo of + Left aF -> left $ ShelleyQueryCmdAcquireFailure aF + Right eU -> case eU of + Left mismatch -> left $ ShelleyQueryCmdEraMismatch mismatch + Right utxo -> writeFilteredUTxOs sbe mOutFile utxo + where + getSbe :: CardanoEraStyle era -> ExceptT ShelleyQueryCmdError IO (ShelleyBasedEra era) + getSbe LegacyByronEra = left ShelleyQueryCmdByronEra + getSbe (ShelleyBasedEra sbe) = return sbe + + createQuery + :: ShelleyBasedEra era + -> Mode.EraInMode era mode + -> ExceptT ShelleyQueryCmdError IO (Query.QueryInMode mode (Either EraMismatch (Query.UTxO era))) + createQuery sbe e = do + let mFilter = maybeFiltered qfilter + query = (NewIPC.QueryInShelleyBasedEra sbe $ NewIPC.QueryUTxO mFilter) + return $ NewIPC.QueryInEra e query - | otherwise = throwError (ShelleyQueryCmdLocalStateQueryError - ByronProtocolNotSupportedError) + + + maybeFiltered :: QueryFilter -> Maybe (Set AddressAny) + maybeFiltered (FilterByAddress as) = Just as + maybeFiltered NoFilter = Nothing runQueryLedgerState @@ -355,10 +382,9 @@ writeProtocolState mOutFile pstate = handleIOExceptT (ShelleyQueryCmdWriteFileError . FileIOError fpath) $ LBS.writeFile fpath (encodePretty pstate) -writeFilteredUTxOs :: ShelleyLedgerEra era ~ ledgerera - => ShelleyBasedEra era +writeFilteredUTxOs :: ShelleyBasedEra era -> Maybe OutputFile - -> Shelley.UTxO ledgerera + -> Query.UTxO era -> ExceptT ShelleyQueryCmdError IO () writeFilteredUTxOs shelleyBasedEra' mOutFile utxo = case mOutFile of @@ -373,56 +399,54 @@ writeFilteredUTxOs shelleyBasedEra' mOutFile utxo = handleIOExceptT (ShelleyQueryCmdWriteFileError . FileIOError fpath) $ LBS.writeFile fpath (encodePretty utxo') -printFilteredUTxOs :: ShelleyLedgerEra era ~ ledgerera => ShelleyBasedEra era -> Shelley.UTxO ledgerera -> IO () -printFilteredUTxOs shelleyBasedEra' utxo = do +printFilteredUTxOs :: ShelleyBasedEra era -> Query.UTxO era -> IO () +printFilteredUTxOs shelleyBasedEra' (Query.UTxO utxo) = do Text.putStrLn title putStrLn $ replicate (Text.length title + 2) '-' case shelleyBasedEra' of ShelleyBasedEraShelley -> - let Shelley.UTxO utxoMap = utxo - in mapM_ (printUtxo shelleyBasedEra') $ Map.toList utxoMap + mapM_ (printUtxo shelleyBasedEra') $ Map.toList utxo ShelleyBasedEraAllegra -> - let Shelley.UTxO utxoMap = utxo - in mapM_ (printUtxo shelleyBasedEra') $ Map.toList utxoMap + mapM_ (printUtxo shelleyBasedEra') $ Map.toList utxo ShelleyBasedEraMary -> - let Shelley.UTxO utxoMap = utxo - in mapM_ (printUtxo shelleyBasedEra') $ Map.toList utxoMap + mapM_ (printUtxo shelleyBasedEra') $ Map.toList utxo where title :: Text title = " TxHash TxIx Amount" printUtxo - :: ShelleyLedgerEra era ~ ledgerera - => ShelleyBasedEra era - -> (Shelley.TxIn StandardCrypto, Ledger.TxOut ledgerera) + :: ShelleyBasedEra era + -> (TxIn, TxOut era) -> IO () printUtxo shelleyBasedEra' txInOutTuple = case shelleyBasedEra' of ShelleyBasedEraShelley -> - let (Shelley.TxIn (Shelley.TxId txhash) txin, Shelley.TxOut _ value) = txInOutTuple + let ((TxIn (TxId txhash) (TxIx index)),(TxOut _ value)) = txInOutTuple in Text.putStrLn $ mconcat [ Text.decodeLatin1 (hashToBytesAsHex txhash) - , textShowN 6 txin - , " " <> printableValue (convertToApiValue shelleyBasedEra' value) + , textShowN 6 index + , " " <> printableValue value ] + ShelleyBasedEraAllegra -> - let (Shelley.TxIn (Shelley.TxId txhash) txin, Shelley.TxOut _ value) = txInOutTuple + let ((TxIn (TxId txhash) (TxIx index)),(TxOut _ value)) = txInOutTuple in Text.putStrLn $ mconcat [ Text.decodeLatin1 (hashToBytesAsHex txhash) - , textShowN 6 txin - , " " <> printableValue (convertToApiValue shelleyBasedEra' value) + , textShowN 6 index + , " " <> printableValue value ] ShelleyBasedEraMary -> - let (Shelley.TxIn (Shelley.TxId txhash) txin, Shelley.TxOut _ value) = txInOutTuple + let ((TxIn (TxId txhash) (TxIx index)),(TxOut _ value)) = txInOutTuple in Text.putStrLn $ mconcat [ Text.decodeLatin1 (hashToBytesAsHex txhash) - , textShowN 6 txin - , " " <> printableValue (convertToApiValue shelleyBasedEra' value) + , textShowN 6 index + , " " <> printableValue value ] + where textShowN :: Show a => Int -> a -> Text textShowN len x = @@ -430,8 +454,9 @@ printUtxo shelleyBasedEra' txInOutTuple = slen = length str in Text.pack $ replicate (max 1 (len - slen)) ' ' ++ str - printableValue :: Value -> Text - printableValue = renderValue defaultRenderValueOptions + printableValue :: TxOutValue era -> Text + printableValue (TxOutValue _ val) = renderValue defaultRenderValueOptions val + printableValue (TxOutAdaOnly _ (Lovelace i)) = Text.pack $ show i runQueryStakeDistribution @@ -501,64 +526,6 @@ printStakeDistribution stakeDistrib = do , showEFloat (Just 3) (fromRational stakeFraction :: Double) "" ] - --- From Cardano.Api - --- | Query the UTxO, filtered by a given set of addresses, from a Shelley node --- via the local state query protocol. --- --- This one is Shelley-specific because the query is Shelley-specific. --- -queryUTxOFromLocalState - :: forall era ledgerera mode block. - ShelleyLedgerEra era ~ ledgerera - => Ledger.Crypto ledgerera ~ StandardCrypto - => IsShelleyBasedEra era - => ShelleyBasedEra era - -> QueryFilter - -> LocalNodeConnectInfo mode block - -> ExceptT ShelleyQueryCmdLocalStateQueryError IO (Shelley.UTxO ledgerera) -queryUTxOFromLocalState era qFilter - connectInfo@LocalNodeConnectInfo{ - localNodeConsensusMode - } = - case localNodeConsensusMode of - ByronMode{} -> throwError ByronProtocolNotSupportedError - - ShelleyMode{} | ShelleyBasedEraShelley <- era -> do - tip <- liftIO $ getLocalTip connectInfo - Consensus.DegenQueryResult result <- - firstExceptT AcquireFailureError . newExceptT $ - queryNodeLocalState - connectInfo - ( getTipPoint tip - , Consensus.DegenQuery (applyUTxOFilter qFilter) - ) - return result - - ShelleyMode{} | otherwise -> throwError ShelleyProtocolEraMismatch - - CardanoMode{} -> do - tip <- liftIO $ getLocalTip connectInfo - result <- firstExceptT AcquireFailureError . newExceptT $ - queryNodeLocalState - connectInfo - (getTipPoint tip, queryIfCurrentEra era (applyUTxOFilter qFilter)) - case result of - QueryResultEraMismatch err -> throwError (EraMismatchError err) - QueryResultSuccess utxo -> return utxo - where - applyUTxOFilter :: QueryFilter - -> Query (Consensus.ShelleyBlock ledgerera) - (Shelley.UTxO ledgerera) - applyUTxOFilter (FilterByAddress as) = Consensus.GetFilteredUTxO (toShelleyAddrs as) - applyUTxOFilter NoFilter = Consensus.GetUTxO - - toShelleyAddrs :: Set AddressAny -> Set (Ledger.Addr StandardCrypto) - toShelleyAddrs = Set.map (toShelleyAddr - . (anyAddressInShelleyBasedEra - :: AddressAny -> AddressInEra era)) - -- | A mapping of Shelley reward accounts to both the stake pool that they -- delegate to and their reward account balance. newtype DelegationsAndRewards @@ -708,20 +675,3 @@ obtainToJSONNewEpochState ShelleyBasedEraShelley f = f obtainToJSONNewEpochState ShelleyBasedEraAllegra f = f obtainToJSONNewEpochState ShelleyBasedEraMary f = f -obtainToJSONValue - :: ShelleyLedgerEra era ~ ledgerera - => ShelleyBasedEra era - -> (ToJSON (Ledger.Value ledgerera) => a) -> a -obtainToJSONValue ShelleyBasedEraShelley f = f -obtainToJSONValue ShelleyBasedEraAllegra f = f -obtainToJSONValue ShelleyBasedEraMary f = f - --- | Convert a ledger 'Ledger.Value' to a @cardano-api@ 'Value'. -convertToApiValue - :: ShelleyLedgerEra era ~ ledgerera - => ShelleyBasedEra era - -> Ledger.Value ledgerera - -> Value -convertToApiValue ShelleyBasedEraShelley = lovelaceToValue . fromShelleyLovelace -convertToApiValue ShelleyBasedEraAllegra = lovelaceToValue . fromShelleyLovelace -convertToApiValue ShelleyBasedEraMary = fromMaryValue