From b90841962a7b32c0024800926047da6177b45d92 Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Wed, 28 Jan 2026 11:32:39 -0400 Subject: [PATCH 1/6] Fix TxMintValue to only accept script witnesses --- cardano-api/src/Cardano/Api/Experimental.hs | 2 ++ .../Experimental/Tx/Internal/AnyWitness.hs | 7 +++++ .../Tx/Internal/BodyContent/New.hs | 11 ++++---- .../Api/Experimental/Tx/Internal/Fee.hs | 28 +++++++++++++++---- .../Api/Transaction/Body/Plutus/Scripts.hs | 2 +- 5 files changed, 39 insertions(+), 11 deletions(-) diff --git a/cardano-api/src/Cardano/Api/Experimental.hs b/cardano-api/src/Cardano/Api/Experimental.hs index 9bf24a2c06..e2241a34d9 100644 --- a/cardano-api/src/Cardano/Api/Experimental.hs +++ b/cardano-api/src/Cardano/Api/Experimental.hs @@ -86,6 +86,7 @@ module Cardano.Api.Experimental , AsType (..) -- ** Internal + , anyScriptWitnessToAnyWitness , getAnyWitnessRedeemerPointerMap , toPlutusScriptPurpose @@ -103,5 +104,6 @@ import Cardano.Api.Experimental.Plutus.Internal.ScriptWitness import Cardano.Api.Experimental.Plutus.Internal.Shim.LegacyScripts import Cardano.Api.Experimental.Simple.Script import Cardano.Api.Experimental.Tx +import Cardano.Api.Experimental.Tx.Internal.AnyWitness import Cardano.Api.Experimental.Tx.Internal.Fee import Cardano.Api.Tx.Internal.Fee (evaluateTransactionExecutionUnitsShelley) diff --git a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/AnyWitness.hs b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/AnyWitness.hs index 561ac155c6..655c425ab9 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/AnyWitness.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/AnyWitness.hs @@ -7,6 +7,7 @@ module Cardano.Api.Experimental.Tx.Internal.AnyWitness ( -- * Any witness (key, simple script, plutus script). AnyWitness (..) + , anyScriptWitnessToAnyWitness , getAnyWitnessScript , getAnyWitnessSimpleScript , getAnyWitnessPlutusLanguage @@ -127,3 +128,9 @@ getPlutusDatum L.SPlutusV3 (SpendingScriptDatum d) = d getPlutusDatum L.SPlutusV4 (SpendingScriptDatum _d) = error "dijkstra" getPlutusDatum _ InlineDatum = Nothing getPlutusDatum _ NoScriptDatum = Nothing + +anyScriptWitnessToAnyWitness + :: AnyScriptWitness era + -> AnyWitness era +anyScriptWitnessToAnyWitness (AnyScriptWitnessSimple s) = AnySimpleScriptWitness s +anyScriptWitnessToAnyWitness (AnyScriptWitnessPlutus sw) = AnyPlutusScriptWitness sw diff --git a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs index 088636192b..7b5e018187 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs @@ -65,6 +65,7 @@ module Cardano.Api.Experimental.Tx.Internal.BodyContent.New where import Cardano.Api.Address +import Cardano.Api.Experimental.AnyScriptWitness import Cardano.Api.Experimental.Certificate qualified as Exp import Cardano.Api.Experimental.Era import Cardano.Api.Experimental.Plutus @@ -76,6 +77,7 @@ import Cardano.Api.Experimental.Plutus import Cardano.Api.Experimental.Simple.Script import Cardano.Api.Experimental.Tx.Internal.AnyWitness ( AnyWitness (..) + , anyScriptWitnessToAnyWitness ) import Cardano.Api.Experimental.Tx.Internal.Certificate.Compatible (getTxCertWitness) import Cardano.Api.Experimental.Tx.Internal.TxScriptWitnessRequirements @@ -399,14 +401,13 @@ mkTxCertificates era certs = TxCertificates . OMap.fromList $ map getStakeCred c getStakeCred (c@(Exp.Certificate cert), wit) = (c, (,wit) <$> getTxCertWitness (convert era) (obtainCommonConstraints era cert)) --- This is incorrect. Only scripts can witness minting! newtype TxMintValue era = TxMintValue { unTxMintValue :: Map PolicyId ( PolicyAssets - , AnyWitness era + , AnyScriptWitness era ) } deriving (Eq, Show) @@ -548,7 +549,7 @@ extractAllIndexedPlutusScriptWitnesses extractAllIndexedPlutusScriptWitnesses era b = obtainCommonConstraints era $ do let txInWits = extractWitnessableTxIns $ txIns b certWits = extractWitnessableCertificates $ txCertificates b - mintWits = extractWitnessableMints $ txMintValue b + mintWits = [(wit, anyScriptWitnessToAnyWitness sw) | (wit, sw) <- extractWitnessableMints $ txMintValue b] withdrawalWits = extractWitnessableWithdrawals $ txWithdrawals b proposalScriptWits = extractWitnessableProposals $ txProposalProcedures b voteWits = extractWitnessableVotes $ txVotingProcedures b @@ -598,7 +599,7 @@ extractWitnessableMints :: forall era . IsEra era => TxMintValue (LedgerEra era) - -> [(Witnessable MintItem (LedgerEra era), AnyWitness (LedgerEra era))] + -> [(Witnessable MintItem (LedgerEra era), AnyScriptWitness (LedgerEra era))] extractWitnessableMints mVal = obtainCommonConstraints (useEra @era) $ List.nub @@ -700,7 +701,7 @@ collectTxBodyScriptWitnessRequirements extractWitnessableCertificates txCertificates txMintWits = obtainMonoidConstraint (useEra @era) getTxScriptWitnessesRequirements $ - extractWitnessableMints txMintValue + [(wit, anyScriptWitnessToAnyWitness sw) | (wit, sw) <- extractWitnessableMints txMintValue] txVotingWits = obtainMonoidConstraint (useEra @era) getTxScriptWitnessesRequirements $ extractWitnessableVotes txVotingProcedures diff --git a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs index 663a4beaf2..6e0042432c 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs @@ -750,6 +750,19 @@ substituteExecutionUnits & setTxVotingProcedures mappedVotes & setTxProposalProcedures mappedProposals where + substitudeExecUnitsTxMint + :: ScriptWitnessIndex + -> AnyScriptWitness (LedgerEra era) + -> Either (TxBodyErrorAutoBalance (LedgerEra era)) (AnyScriptWitness (LedgerEra era)) + substitudeExecUnitsTxMint _ w@AnyScriptWitnessSimple{} = Right w + substitudeExecUnitsTxMint idx (AnyScriptWitnessPlutus psw) = + case Map.lookup idx exUnitsMap of + Nothing -> + Left $ TxBodyErrorScriptWitnessIndexMissingFromExecUnitsMap idx exUnitsMap + Just exunits -> + Right $ + AnyScriptWitnessPlutus $ + updatePlutusScriptWitnessExecutionUnits exunits psw substituteExecUnits :: ScriptWitnessIndex -> AnyWitness (LedgerEra era) @@ -829,10 +842,15 @@ substituteExecutionUnits :: TxMintValue (LedgerEra era) -> Either (TxBodyErrorAutoBalance (LedgerEra era)) (TxMintValue (LedgerEra era)) mapScriptWitnessesMinting txMintValue' = do - let mappedScriptWitnesses = + let mappedScriptWitnesses + :: [ ( PolicyId + , Either (TxBodyErrorAutoBalance (LedgerEra era)) (PolicyAssets, AnyScriptWitness (LedgerEra era)) + ) + ] + mappedScriptWitnesses = [ (policyId, (assets,) <$> substitutedWitness) | (ix, policyId, assets, wit) <- indexTxMintValue txMintValue' - , let substitutedWitness = substituteExecUnits ix wit + , let substitutedWitness = substitudeExecUnitsTxMint ix wit ] -- merge map values, wit1 == wit2 will always hold mergeValues (assets1, wit1) (assets2, _wit2) = (assets1 <> assets2, wit1) @@ -931,8 +949,8 @@ collectTxBodyScriptWitnesses scriptWitnessesMinting txMintValue' = List.nub [ (ix, wit) - | (ix, _, _, Just wit@AnyScriptWitnessPlutus{}) <- - fmap toAnyScriptWitness <$> indexTxMintValue txMintValue' + | (ix, _, _, wit@AnyScriptWitnessPlutus{}) <- + indexTxMintValue txMintValue' ] scriptWitnessesVoting @@ -1021,7 +1039,7 @@ indexTxMintValue -> [ ( ScriptWitnessIndex , PolicyId , PolicyAssets - , AnyWitness era + , AnyScriptWitness era ) ] indexTxMintValue (TxMintValue policiesWithAssets) = diff --git a/cardano-api/test/cardano-api-test/Test/Cardano/Api/Transaction/Body/Plutus/Scripts.hs b/cardano-api/test/cardano-api-test/Test/Cardano/Api/Transaction/Body/Plutus/Scripts.hs index 28f3228912..8a14fc0ce5 100644 --- a/cardano-api/test/cardano-api-test/Test/Cardano/Api/Transaction/Body/Plutus/Scripts.hs +++ b/cardano-api/test/cardano-api-test/Test/Cardano/Api/Transaction/Body/Plutus/Scripts.hs @@ -180,7 +180,7 @@ prop_extractAllIndexedPlutusScriptWitnesses = mconcat [ createIndexedPlutusScriptWitnesses $ [(Exp.WitTxIn tIn, sWit) | (tIn, sWit) <- generatedTxInWits] , createIndexedPlutusScriptWitnesses $ - [ (Exp.WitMint pid pAssets, sWit) + [ (Exp.WitMint pid pAssets, anyScriptWitnessToAnyWitness sWit) | (pid, (pAssets, sWit)) <- Map.toList $ Exp.unTxMintValue generatedTxMintWits ] , createIndexedPlutusScriptWitnesses From fe4f64fa3a86aa427f478b6ad356b6ca7703f112 Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Wed, 28 Jan 2026 12:14:25 -0400 Subject: [PATCH 2/6] Remove Datum ctx era from TxOut --- .../Tx/Internal/BodyContent/New.hs | 50 ++++++++++++++----- .../Api/Experimental/Tx/Internal/Fee.hs | 47 +++++++++-------- .../Test/Golden/Cardano/Api/Tx.hs | 2 +- .../Test/Cardano/Api/Experimental.hs | 3 +- 4 files changed, 62 insertions(+), 40 deletions(-) diff --git a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs index 7b5e018187..ebe03dedfe 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs @@ -115,6 +115,7 @@ import Cardano.Ledger.Keys qualified as L import Cardano.Ledger.Plutus.Language qualified as Plutus import Control.Monad +import Data.ByteString.Short qualified as SBS import Data.Functor import Data.List qualified as List import Data.Map.Ordered.Strict (OMap) @@ -148,7 +149,7 @@ makeUnsignedTx era@ConwayEra bc = obtainCommonConstraints era $ do txins = convTxIns $ txIns bc collTxIns = convCollateralTxIns bc refTxIns = convReferenceInputs apiReferenceInputs - outs = fromList [o | TxOut o _ <- txOuts bc] + outs = fromList [o | TxOut o <- txOuts bc] protocolParameters = txProtocolParams bc fee = txFee bc withdrawals = convWithdrawals $ txWithdrawals bc @@ -312,12 +313,12 @@ eraSpecificLedgerTxBody era ledgerbody bc = & L.currentTreasuryValueTxBodyL .~ L.maybeToStrictMaybe currentTreasuryValue -data TxOut ctx era where - TxOut :: L.EraTxOut era => L.TxOut era -> Maybe (Datum ctx era) -> TxOut ctx era +data TxOut era where + TxOut :: L.EraTxOut era => L.TxOut era -> TxOut era -deriving instance (Show (TxOut ctx era)) +deriving instance (Show (TxOut era)) -deriving instance (Eq (TxOut ctx era)) +deriving instance (Eq (TxOut era)) data Datum ctx era where TxOutDatumHash @@ -356,10 +357,29 @@ legacyDatumToDatum (OldApi.TxOutDatumInline _ hd) = do Just (TxOutDatumInline hash d) legacyDatumToDatum OldApi.TxOutDatumNone = Nothing -fromLegacyTxOut :: forall era. IsEra era => OldApi.TxOut CtxTx era -> TxOut CtxTx (LedgerEra era) -fromLegacyTxOut tOut@(OldApi.TxOut _ _ d _) = +fromLegacyTxOut + :: forall era. IsEra era => OldApi.TxOut CtxTx era -> Either DatumDecodingError (TxOut (LedgerEra era)) +fromLegacyTxOut tOut@(OldApi.TxOut _ _ d _) = do let o = OldApi.toShelleyTxOutAny (convert $ useEra @era) tOut - in obtainCommonConstraints (useEra @era) $ TxOut o (legacyDatumToDatum d) + newDatum :: L.Datum (LedgerEra era) <- obtainCommonConstraints (useEra @era) $ toLedgerDatum d + return $ obtainCommonConstraints (useEra @era) $ TxOut $ o & L.datumTxOutL .~ newDatum + +data DatumDecodingError = DataDecodingError String + deriving (Show, Eq) + +toLedgerDatum + :: L.Era (LedgerEra era) + => OldApi.TxOutDatum CtxTx era -> Either DatumDecodingError (L.Datum (LedgerEra era)) +toLedgerDatum OldApi.TxOutDatumNone = Right L.NoDatum +toLedgerDatum (OldApi.TxOutDatumHash _ (Api.ScriptDataHash h)) = Right $ L.DatumHash h +toLedgerDatum (OldApi.TxOutSupplementalDatum _ h) = + case L.makeBinaryData $ SBS.toShort $ Api.getOriginalScriptDataBytes h of + Left e -> Left $ DataDecodingError e + Right bd -> Right $ L.Datum bd +toLedgerDatum (OldApi.TxOutDatumInline _ h) = + case L.makeBinaryData $ SBS.toShort $ Api.getOriginalScriptDataBytes h of + Left e -> Left $ DataDecodingError e + Right bd -> Right $ L.Datum bd data TxInsReference era = TxInsReference [TxIn] (Set (Datum CtxTx era)) @@ -490,7 +510,7 @@ data TxBodyContent era { txIns :: [(TxIn, AnyWitness era)] , txInsCollateral :: [TxIn] , txInsReference :: TxInsReference era - , txOuts :: [TxOut CtxTx era] + , txOuts :: [TxOut era] , txTotalCollateral :: Maybe TxTotalCollateral , txReturnCollateral :: Maybe (TxReturnCollateral era) , txFee :: L.Coin @@ -739,14 +759,18 @@ getDatums . IsEra era => TxInsReference (LedgerEra era) -- ^ reference inputs - -> [TxOut CtxTx (LedgerEra era)] + -> [TxOut (LedgerEra era)] -> L.TxDats (LedgerEra era) getDatums txInsRef txOutsFromTx = do let TxInsReference _ datumSet = txInsRef refInDatums = mapMaybe extractDatumsAndHashes $ Set.toList datumSet -- use only supplemental datum txOutsDats = - [(h, d) | TxOut _ (Just (TxOutSupplementalDatum h d)) <- txOutsFromTx] + [ (L.hashData d, d) + | TxOut txout <- txOutsFromTx + , d <- + maybeToList $ L.strictMaybeToMaybe $ txout ^. obtainCommonConstraints (useEra @era) L.dataTxOutL + ] :: [(L.DataHash, L.Data (LedgerEra era))] obtainCommonConstraints (useEra @era) $ L.TxDats $ @@ -791,7 +815,7 @@ setTxMetadata v txBodyContent = txBodyContent{txMetadata = v} setTxFee :: L.Coin -> TxBodyContent era -> TxBodyContent era setTxFee v txBodyContent = txBodyContent{txFee = v} -setTxOuts :: [TxOut CtxTx era] -> TxBodyContent era -> TxBodyContent era +setTxOuts :: [TxOut era] -> TxBodyContent era -> TxBodyContent era setTxOuts v txBodyContent = txBodyContent{txOuts = v} setTxMintValue :: TxMintValue era -> TxBodyContent era -> TxBodyContent era @@ -819,5 +843,5 @@ setTxTreasuryDonation :: L.Coin -> TxBodyContent era -> TxBodyContent era setTxTreasuryDonation v txBodyContent = txBodyContent{txTreasuryDonation = Just v} modTxOuts - :: ([TxOut CtxTx era] -> [TxOut CtxTx era]) -> TxBodyContent era -> TxBodyContent era + :: ([TxOut era] -> [TxOut era]) -> TxBodyContent era -> TxBodyContent era modTxOuts f txBodyContent = txBodyContent{txOuts = f (txOuts txBodyContent)} diff --git a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs index 6e0042432c..ec62ed88bd 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs @@ -48,8 +48,7 @@ import Cardano.Api.Pretty import Cardano.Api.ProtocolParameters import Cardano.Api.Query.Internal.Type.QueryInMode import Cardano.Api.Tx.Internal.Body - ( CtxTx - , ScriptWitnessIndex (..) + ( ScriptWitnessIndex (..) , renderScriptWitnessIndex , toScriptIndex ) @@ -100,7 +99,7 @@ data TxBodyErrorAutoBalance era -- new UTXO entries. The transaction should be changed to provide more -- input ada. TxBodyErrorAdaBalanceTooSmall - (TxOut CtxTx era) + (TxOut era) -- ^ Offending TxOut L.Coin -- ^ Minimum UTxO @@ -108,7 +107,7 @@ data TxBodyErrorAutoBalance era -- ^ Tx balance | -- | The minimum spendable UTxO threshold has not been met. TxBodyErrorMinUTxONotMet - (TxOut CtxTx era) + (TxOut era) -- ^ Offending TxOut L.Coin -- ^ Minimum UTXO @@ -365,7 +364,7 @@ estimateBalancedTxBody' txbodycontent1 { txFee = maxLovelaceFee , txOuts = - obtainCommonConstraints (useEra @era) (TxOut changeTxOut Nothing) + obtainCommonConstraints (useEra @era) (TxOut changeTxOut) : txOuts txbodycontent , txReturnCollateral = mDummyReturnCollateral , txTotalCollateral = mDummyTotalCollateral @@ -411,10 +410,10 @@ estimateBalancedTxBody' coinBalance :: L.Coin coinBalance = obtainCommonConstraints (useEra @era) $ L.coin balance - balanceTxOut :: TxOut CtxTx (LedgerEra era) + balanceTxOut :: TxOut (LedgerEra era) balanceTxOut = obtainCommonConstraints (useEra @era) $ - TxOut (L.mkBasicTxOut (toShelleyAddr changeaddr) balance) Nothing + TxOut (L.mkBasicTxOut (toShelleyAddr changeaddr) balance) case useEra @era of DijkstraEra -> error "estimateBalancedTxBody: DijkstraEra is not supported for fee estimation" ConwayEra -> do @@ -459,10 +458,10 @@ checkNonNegative :: forall era . IsEra era => Ledger.PParams (LedgerEra era) - -> TxOut CtxTx (LedgerEra era) + -> TxOut (LedgerEra era) -> Either (TxBodyErrorAutoBalance (LedgerEra era)) IsEmpty -- ^ result of check if txout is empty -checkNonNegative bpparams txout@(TxOut balance _) = do +checkNonNegative bpparams txout@(TxOut balance) = do let outValue@(L.MaryValue coin multiAsset) = balance ^. obtainCommonConstraints (useEra @era) L.valueTxOutL isPositiveValue = L.pointwise (>) outValue mempty if @@ -486,10 +485,10 @@ checkAndIncludeChange :: forall era . IsEra era => Ledger.PParams (LedgerEra era) - -> TxOut CtxTx (LedgerEra era) - -> [TxOut CtxTx (LedgerEra era)] - -> Either (TxBodyErrorAutoBalance (LedgerEra era)) [TxOut CtxTx (LedgerEra era)] -checkAndIncludeChange pp change@(TxOut changeOutput _) rest = do + -> TxOut (LedgerEra era) + -> [TxOut (LedgerEra era)] + -> Either (TxBodyErrorAutoBalance (LedgerEra era)) [TxOut (LedgerEra era)] +checkAndIncludeChange pp change@(TxOut changeOutput) rest = do isChangeEmpty <- checkNonNegative pp change case isChangeEmpty of Empty -> pure rest @@ -502,10 +501,10 @@ checkAndIncludeChange pp change@(TxOut changeOutput _) rest = do checkMinUTxOValue :: Ledger.PParams (LedgerEra era) - -> TxOut CtxTx (LedgerEra era) - -> Either (TxOut CtxTx (LedgerEra era), Coin) () + -> TxOut (LedgerEra era) + -> Either (TxOut (LedgerEra era), Coin) () -- ^ @Left (offending txout, minimum required utxo)@ or @Right ()@ when txout is ok -checkMinUTxOValue bpp txout@(TxOut out _) = do +checkMinUTxOValue bpp txout@(TxOut out) = do let minUTxO = calculateMinimumUTxO bpp txout if out ^. L.coinTxOutL >= minUTxO then Right () @@ -514,9 +513,9 @@ checkMinUTxOValue bpp txout@(TxOut out _) = do calculateMinimumUTxO :: HasCallStack => Ledger.PParams (LedgerEra era) - -> TxOut CtxTx (LedgerEra era) + -> TxOut (LedgerEra era) -> L.Coin -calculateMinimumUTxO pp (TxOut txout _) = +calculateMinimumUTxO pp (TxOut txout) = let txOutWithMinCoin = L.setMinCoinTxOut pp txout in txOutWithMinCoin ^. L.coinTxOutL @@ -573,7 +572,7 @@ createFakeUTxO :: TxBodyContent era -> Coin -> L.UTxO era createFakeUTxO txbodycontent totalAdaInUTxO = let singleTxIn = maybe [] (return . toShelleyTxIn . fst) $ List.uncons [txin | (txin, _) <- txIns txbodycontent] singleTxOut = - maybe [] (\(TxOut firstOut _, _rest) -> return $ firstOut & L.coinTxOutL .~ totalAdaInUTxO) $ + maybe [] (\(TxOut firstOut, _rest) -> return $ firstOut & L.coinTxOutL .~ totalAdaInUTxO) $ List.uncons $ txOuts txbodycontent in -- Take one txin and one txout. Replace the out value with totalAdaInUTxO @@ -701,7 +700,7 @@ calculatePartialChangeValue incoming txbodycontent = do where newUtxoValue = mconcat - [out ^. obtainCommonConstraints (useEra @era) L.valueTxOutL | (TxOut out _) <- txOuts txbodycontent] + [out ^. obtainCommonConstraints (useEra @era) L.valueTxOutL | (TxOut out) <- txOuts txbodycontent] substituteExecutionUnits :: forall era @@ -1220,9 +1219,9 @@ makeTransactionBodyAutoBalance let initialChangeTxOutValue :: Ledger.Value (LedgerEra era) = evaluateTransactionBalance pp poolids stakeDelegDeposits drepDelegDeposits utxo txbodyForChange - initialChangeTxOut :: TxOut CtxTx (LedgerEra era) = + initialChangeTxOut :: TxOut (LedgerEra era) = obtainCommonConstraints (useEra @era) $ - TxOut (L.mkBasicTxOut (toShelleyAddr changeaddr) initialChangeTxOutValue) Nothing + TxOut (L.mkBasicTxOut (toShelleyAddr changeaddr) initialChangeTxOutValue) -- Initial change is only used for execution units evaluation, so we don't require minimum UTXO requirement -- to be satisfied at this point @@ -1335,9 +1334,9 @@ makeTransactionBodyAutoBalance let -- The multiasset output of evaluateTransactionBalance will be negative when -- minting a multiasset. Therefore we must make the multiasset balance positive - balanceTxOut :: TxOut CtxTx (LedgerEra era) = + balanceTxOut :: TxOut (LedgerEra era) = obtainCommonConstraints (useEra @era) $ - TxOut (L.mkBasicTxOut (toShelleyAddr changeaddr) balance) Nothing + TxOut (L.mkBasicTxOut (toShelleyAddr changeaddr) balance) first (uncurry TxBodyErrorMinUTxONotMet) . mapM_ (checkMinUTxOValue pp) $ txOuts txbodycontent1 diff --git a/cardano-api/test/cardano-api-golden/Test/Golden/Cardano/Api/Tx.hs b/cardano-api/test/cardano-api-golden/Test/Golden/Cardano/Api/Tx.hs index cebaa082a4..e76d98b8c3 100644 --- a/cardano-api/test/cardano-api-golden/Test/Golden/Cardano/Api/Tx.hs +++ b/cardano-api/test/cardano-api-golden/Test/Golden/Cardano/Api/Tx.hs @@ -86,7 +86,7 @@ tx_canonical = H.propertyOnce $ do txOut = Exp.TxOut basicOut - Nothing + txRetColl = Exp.TxReturnCollateral basicOut txTotalColl = Exp.TxTotalCollateral (L.inject $ L.Coin 1) txBodyContent' = diff --git a/cardano-api/test/cardano-api-test/Test/Cardano/Api/Experimental.hs b/cardano-api/test/cardano-api-test/Test/Cardano/Api/Experimental.hs index 304f3c6745..51b9dec4f1 100644 --- a/cardano-api/test/cardano-api-test/Test/Cardano/Api/Experimental.hs +++ b/cardano-api/test/cardano-api-test/Test/Cardano/Api/Experimental.hs @@ -318,7 +318,7 @@ exampleTxBodyContentExperimental era = do ) ] & Exp.setTxOuts - [ Exp.obtainCommonConstraints era $ Exp.TxOut out Nothing + [ Exp.obtainCommonConstraints era $ Exp.TxOut out ] & Exp.setTxFee 2_000_000 return txBodyContent @@ -395,7 +395,6 @@ exampleOldAndNewStyleTxBodyContent era = do ( Exp.obtainCommonConstraints era $ Ledger.mkBasicTxOut (Api.toShelleyAddr destAddress) (Ledger.valueFromList 10_000_000 []) ) - Nothing ] & Exp.setTxFee 2_000_000 return (txBodyContentOldApi, txBodyContentNewApi) From d667c53fae9104c1b728b987484b63e4ff120a9f Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Thu, 29 Jan 2026 09:56:09 -0400 Subject: [PATCH 3/6] Parameterize UnsignedTx on ledger's era --- .../src/Cardano/Api/Experimental/Era.hs | 2 ++ .../src/Cardano/Api/Experimental/Tx.hs | 16 ++++----- .../Tx/Internal/BodyContent/New.hs | 3 +- .../Api/Experimental/Tx/Internal/Fee.hs | 14 ++++---- .../Api/Experimental/Tx/Internal/Type.hs | 9 +++-- .../src/Cardano/Api/Internal/Orphans/Misc.hs | 34 +++++++++++++++++++ 6 files changed, 58 insertions(+), 20 deletions(-) diff --git a/cardano-api/src/Cardano/Api/Experimental/Era.hs b/cardano-api/src/Cardano/Api/Experimental/Era.hs index 3a1777fea8..f3d6a66ccc 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Era.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Era.hs @@ -44,6 +44,7 @@ import Cardano.Api.Era.Internal.Eon.ConwayEraOnwards import Cardano.Api.Era.Internal.Eon.MaryEraOnwards import Cardano.Api.Era.Internal.Eon.ShelleyBasedEra (ShelleyBasedEra (..), ShelleyLedgerEra) import Cardano.Api.Error +import Cardano.Api.HasTypeProxy import Cardano.Api.Ledger.Internal.Reexport qualified as L import Cardano.Api.Pretty.Internal.ShowOf @@ -311,6 +312,7 @@ type EraCommonConstraints era = , L.EraTxCert (LedgerEra era) , L.EraTxOut (LedgerEra era) , L.EraUTxO (LedgerEra era) + , HasTypeProxy (LedgerEra era) , Ord (L.PlutusPurpose L.AsIx (LedgerEra era)) , L.ScriptsNeeded (LedgerEra era) ~ L.AlonzoScriptsNeeded (LedgerEra era) , L.Val (L.Value (LedgerEra era)) diff --git a/cardano-api/src/Cardano/Api/Experimental/Tx.hs b/cardano-api/src/Cardano/Api/Experimental/Tx.hs index 5d69a0afd7..992274290d 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Tx.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Tx.hs @@ -154,6 +154,7 @@ module Cardano.Api.Experimental.Tx , setTxWithdrawals -- * Legacy Conversions + , DatumDecodingError (..) , legacyDatumToDatum , fromLegacyTxOut @@ -247,7 +248,7 @@ hashTxBody = L.extractHash . L.hashAnnotated makeKeyWitness :: Era era - -> UnsignedTx era + -> UnsignedTx (LedgerEra era) -> ShelleyWitnessSigningKey -> L.WitVKey L.Witness makeKeyWitness era (UnsignedTx unsignedTx) wsk = @@ -297,7 +298,7 @@ signTx :: Era era -> [L.BootstrapWitness] -> [L.WitVKey L.Witness] - -> UnsignedTx era + -> UnsignedTx (LedgerEra era) -> SignedTx era signTx era bootstrapWits shelleyKeyWits (UnsignedTx unsigned) = obtainCommonConstraints era $ @@ -315,7 +316,7 @@ signTx era bootstrapWits shelleyKeyWits (UnsignedTx unsigned) = -- Compatibility related. Will be removed once the old api has been deprecated and deleted. convertTxBodyToUnsignedTx - :: HasCallStack => ShelleyBasedEra era -> TxBody era -> UnsignedTx era + :: HasCallStack => ShelleyBasedEra era -> TxBody era -> UnsignedTx (LedgerEra era) convertTxBodyToUnsignedTx sbe txbody = Api.forEraInEon (Api.toCardanoEra sbe) @@ -330,7 +331,7 @@ convertTxBodyToUnsignedTx sbe txbody = collectPlutusScriptHashes :: forall era . IsEra era - => UnsignedTx era + => UnsignedTx (LedgerEra era) -> L.UTxO (LedgerEra era) -> Map Api.ScriptWitnessIndex Api.ScriptHash collectPlutusScriptHashes (UnsignedTx tx) utxo = @@ -346,10 +347,9 @@ getPurposes (L.AlonzoScriptsNeeded purposes) = Map.fromList $ Prelude.map ( bimap - ( \pp -> - obtainCommonConstraints (useEra @era) $ - Api.toScriptIndex (convert (useEra @era)) $ - purposeAsIxItemToAsIx pp + ( obtainCommonConstraints (useEra @era) $ + Api.toScriptIndex (convert (useEra @era)) + . purposeAsIxItemToAsIx ) Api.fromShelleyScriptHash ) diff --git a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs index ebe03dedfe..5d1e690829 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs @@ -59,6 +59,7 @@ module Cardano.Api.Experimental.Tx.Internal.BodyContent.New , convProposalProcedures -- * Legacy conversions + , DatumDecodingError (..) , legacyDatumToDatum , fromLegacyTxOut ) @@ -135,7 +136,7 @@ makeUnsignedTx :: forall era . Era era -> TxBodyContent (LedgerEra era) - -> UnsignedTx era + -> UnsignedTx (LedgerEra era) makeUnsignedTx DijkstraEra _ = error "makeUnsignedTx: Dijkstra era not supported yet" makeUnsignedTx era@ConwayEra bc = obtainCommonConstraints era $ do let TxScriptWitnessRequirements languages scripts datums redeemers = collectTxBodyScriptWitnessRequirements bc diff --git a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs index ec62ed88bd..4f74e21396 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs @@ -122,7 +122,7 @@ data TxBodyErrorAutoBalance era | BalanceIsNegative L.Coin -- ^ Negative balance - (UnsignedTx ConwayEra) + (UnsignedTx (LedgerEra ConwayEra)) -- ^ The transaction body | NotEnoughAdaInUTxO L.MaryValue @@ -533,7 +533,7 @@ evaluateTransactionBalance -> Map StakeCredential L.Coin -> Map (Ledger.Credential Ledger.DRepRole) L.Coin -> L.UTxO (LedgerEra era) - -> UnsignedTx era + -> UnsignedTx (LedgerEra era) -> L.Value (LedgerEra era) evaluateTransactionBalance pp poolids stakeDelegDeposits drepDelegDeposits utxo (UnsignedTx unsignedTx) = let txbody = unsignedTx ^. L.bodyTxL @@ -645,7 +645,7 @@ calcReturnAndTotalCollateral fee pp' _ mTxReturnCollateral mTxTotalCollateral cA -- estimate: evaluateTransactionFee :: Ledger.PParams (LedgerEra era) - -> UnsignedTx era + -> UnsignedTx (LedgerEra era) -> Word -- ^ The number of Shelley key witnesses -> Word @@ -1076,7 +1076,7 @@ indexWitnessedTxProposalProcedures (TxProposalProcedures proposals) = do | (ix, (proposal, anyWitness)) <- allProposalsList ] -toUnsigned :: forall era. Era era -> L.Tx (LedgerEra era) -> UnsignedTx era +toUnsigned :: forall era. Era era -> L.Tx (LedgerEra era) -> UnsignedTx (LedgerEra era) toUnsigned e tx = obtainCommonConstraints e $ UnsignedTx tx @@ -1194,7 +1194,9 @@ makeTransactionBodyAutoBalance -- ^ Change address -> Maybe Word -- ^ Override key witnesses - -> Either (TxBodyErrorAutoBalance (LedgerEra era)) (UnsignedTx era, TxBodyContent (LedgerEra era)) + -> Either + (TxBodyErrorAutoBalance (LedgerEra era)) + (UnsignedTx (LedgerEra era), TxBodyContent (LedgerEra era)) makeTransactionBodyAutoBalance systemstart history @@ -1466,7 +1468,7 @@ calculateMinTxFee . IsEra era => Ledger.PParams (LedgerEra era) -> L.UTxO (LedgerEra era) - -> UnsignedTx era + -> UnsignedTx (LedgerEra era) -> Word -- ^ The number of Shelley key witnesses -> L.Coin diff --git a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Type.hs b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Type.hs index da74dc00ed..5ae398fc54 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Type.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Type.hs @@ -16,7 +16,6 @@ module Cardano.Api.Experimental.Tx.Internal.Type ) where -import Cardano.Api.Experimental.Era import Cardano.Api.HasTypeProxy (HasTypeProxy (..), Proxy, asType) import Cardano.Api.Ledger.Internal.Reexport qualified as L import Cardano.Api.ProtocolParameters @@ -35,7 +34,7 @@ import Data.ByteString.Lazy (fromStrict) -- | A transaction that can contain everything -- except key witnesses. data UnsignedTx era - = L.EraTx (LedgerEra era) => UnsignedTx (Ledger.Tx (LedgerEra era)) + = L.EraTx era => UnsignedTx (Ledger.Tx era) instance HasTypeProxy era => HasTypeProxy (UnsignedTx era) where data AsType (UnsignedTx era) = AsUnsignedTx (AsType era) @@ -44,16 +43,16 @@ instance HasTypeProxy era => HasTypeProxy (UnsignedTx era) where instance ( HasTypeProxy era - , L.EraTx (LedgerEra era) + , L.EraTx era ) => SerialiseAsRawBytes (UnsignedTx era) where serialiseToRawBytes (UnsignedTx tx) = - Ledger.serialize' (Ledger.eraProtVerHigh @(LedgerEra era)) tx + Ledger.serialize' (Ledger.eraProtVerHigh @era) tx deserialiseFromRawBytes _ = bimap wrapError UnsignedTx . Ledger.decodeFullAnnotator - (Ledger.eraProtVerHigh @(LedgerEra era)) + (Ledger.eraProtVerHigh @era) "UnsignedTx" Ledger.decCBOR . fromStrict diff --git a/cardano-api/src/Cardano/Api/Internal/Orphans/Misc.hs b/cardano-api/src/Cardano/Api/Internal/Orphans/Misc.hs index dfe75284c1..74ba3a1fad 100644 --- a/cardano-api/src/Cardano/Api/Internal/Orphans/Misc.hs +++ b/cardano-api/src/Cardano/Api/Internal/Orphans/Misc.hs @@ -16,10 +16,12 @@ module Cardano.Api.Internal.Orphans.Misc where import Cardano.Api.Error +import Cardano.Api.HasTypeProxy import Cardano.Api.Pretty import Cardano.Chain.Genesis qualified as Byron import Cardano.Ledger.Alonzo.PParams qualified as Ledger +import Cardano.Ledger.Api qualified as L import Cardano.Ledger.Babbage.PParams qualified as Ledger import Cardano.Ledger.BaseTypes (strictMaybeToMaybe) import Cardano.Ledger.BaseTypes qualified as Ledger @@ -308,3 +310,35 @@ instance TestEquality L.SLanguage where (L.SPlutusV3, L.SPlutusV3) -> Just Refl (L.SPlutusV4, L.SPlutusV4) -> Just Refl _ -> Nothing + +instance HasTypeProxy L.ByronEra where + data AsType L.ByronEra = AsByronEra + proxyToAsType _ = AsByronEra + +instance HasTypeProxy L.ShelleyEra where + data AsType L.ShelleyEra = AsShelleyEra + proxyToAsType _ = AsShelleyEra + +instance HasTypeProxy L.AllegraEra where + data AsType L.AllegraEra = AsAllegraEra + proxyToAsType _ = AsAllegraEra + +instance HasTypeProxy L.MaryEra where + data AsType L.MaryEra = AsMaryEra + proxyToAsType _ = AsMaryEra + +instance HasTypeProxy L.AlonzoEra where + data AsType L.AlonzoEra = AsAlonzoEra + proxyToAsType _ = AsAlonzoEra + +instance HasTypeProxy L.BabbageEra where + data AsType L.BabbageEra = AsBabbageEra + proxyToAsType _ = AsBabbageEra + +instance HasTypeProxy L.ConwayEra where + data AsType L.ConwayEra = AsConwayEra + proxyToAsType _ = AsConwayEra + +instance HasTypeProxy L.DijkstraEra where + data AsType L.DijkstraEra = AsDijkstraEra + proxyToAsType _ = AsDijkstraEra From 4389cd62c1ecd4a47543059d0e890c8f206086e3 Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Thu, 29 Jan 2026 12:31:39 -0400 Subject: [PATCH 4/6] Expose functions for cardano-cli integration --- .../src/Cardano/Api/Experimental/AnyScriptWitness.hs | 11 +++++++++++ .../Api/Experimental/Tx/Internal/BodyContent/New.hs | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/cardano-api/src/Cardano/Api/Experimental/AnyScriptWitness.hs b/cardano-api/src/Cardano/Api/Experimental/AnyScriptWitness.hs index 9c4bc83561..096a9cf781 100644 --- a/cardano-api/src/Cardano/Api/Experimental/AnyScriptWitness.hs +++ b/cardano-api/src/Cardano/Api/Experimental/AnyScriptWitness.hs @@ -9,6 +9,7 @@ module Cardano.Api.Experimental.AnyScriptWitness ( AnyScriptWitness (..) , AnyPlutusScriptWitness (..) , PlutusSpendingScriptWitness (..) + , getAnyScriptWitnessReferenceInput , createPlutusSpendingScriptWitness , getAnyPlutusScriptData , getAnyPlutusScriptWitnessExecutionUnits @@ -180,6 +181,16 @@ getAnyPlutusScriptWitnessLanguage (AnyPlutusCertifyingScriptWitness s) = getPlut getAnyPlutusScriptWitnessLanguage (AnyPlutusProposingScriptWitness s) = getPlutusScriptWitnessLanguage s getAnyPlutusScriptWitnessLanguage (AnyPlutusVotingScriptWitness s) = getPlutusScriptWitnessLanguage s +getAnyScriptWitnessReferenceInput + :: AnyScriptWitness era + -> Maybe TxIn +getAnyScriptWitnessReferenceInput (AnyScriptWitnessSimple s) = + case s of + SReferenceScript txin -> Just txin + SScript{} -> Nothing +getAnyScriptWitnessReferenceInput (AnyScriptWitnessPlutus psw) = + getAnyPlutusScriptWitnessReferenceInput psw + getAnyPlutusScriptWitnessReferenceInput :: AnyPlutusScriptWitness lang purpose era -> Maybe TxIn diff --git a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs index 5d1e690829..5c9a8a2067 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs @@ -365,7 +365,7 @@ fromLegacyTxOut tOut@(OldApi.TxOut _ _ d _) = do newDatum :: L.Datum (LedgerEra era) <- obtainCommonConstraints (useEra @era) $ toLedgerDatum d return $ obtainCommonConstraints (useEra @era) $ TxOut $ o & L.datumTxOutL .~ newDatum -data DatumDecodingError = DataDecodingError String +newtype DatumDecodingError = DataDecodingError String deriving (Show, Eq) toLedgerDatum From b210b64a9525f4fe36ac9768aaac8efc19ee04ac Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Thu, 29 Jan 2026 13:50:49 -0400 Subject: [PATCH 5/6] Expose Datum and extractDatumAndHashes Expose calculateMinimumUTxO --- cardano-api/src/Cardano/Api/Experimental/Tx.hs | 6 ++++++ .../Api/Experimental/Tx/Internal/BodyContent/New.hs | 7 +++++++ .../src/Cardano/Api/Experimental/Tx/Internal/Fee.hs | 1 + 3 files changed, 14 insertions(+) diff --git a/cardano-api/src/Cardano/Api/Experimental/Tx.hs b/cardano-api/src/Cardano/Api/Experimental/Tx.hs index 992274290d..f0c3473390 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Tx.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Tx.hs @@ -182,6 +182,11 @@ module Cardano.Api.Experimental.Tx -- ** All the parts that constitute a plutus script witness but also including simple scripts , TxScriptWitnessRequirements (..) + -- ** Plutus related + , Datum (..) + , getDatums + , extractDatumsAndHashes + -- ** Collecting plutus script witness related transaction requirements. , collectPlutusScriptHashes , extractAllIndexedPlutusScriptWitnesses @@ -189,6 +194,7 @@ module Cardano.Api.Experimental.Tx , obtainMonoidConstraint -- * Balancing transactions + , calculateMinimumUTxO , evaluateTransactionExecutionUnits , makeTransactionBodyAutoBalance , TxBodyErrorAutoBalance (..) diff --git a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs index 5c9a8a2067..dac166a490 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs @@ -23,6 +23,8 @@ module Cardano.Api.Experimental.Tx.Internal.BodyContent.New , TxBodyContent (..) , Datum (..) , defaultTxBodyContent + , extractDatumsAndHashes + , getDatums , collectTxBodyScriptWitnessRequirements , makeUnsignedTx , extractAllIndexedPlutusScriptWitnesses @@ -66,6 +68,7 @@ module Cardano.Api.Experimental.Tx.Internal.BodyContent.New where import Cardano.Api.Address +import Cardano.Api.Error import Cardano.Api.Experimental.AnyScriptWitness import Cardano.Api.Experimental.Certificate qualified as Exp import Cardano.Api.Experimental.Era @@ -94,6 +97,7 @@ import Cardano.Api.Key.Internal import Cardano.Api.Ledger.Internal.Reexport (StrictMaybe (..)) import Cardano.Api.Ledger.Internal.Reexport qualified as L import Cardano.Api.Plutus.Internal.ScriptData qualified as Api +import Cardano.Api.Pretty import Cardano.Api.Tx.Internal.Body ( CtxTx , TxIn @@ -368,6 +372,9 @@ fromLegacyTxOut tOut@(OldApi.TxOut _ _ d _) = do newtype DatumDecodingError = DataDecodingError String deriving (Show, Eq) +instance Error DatumDecodingError where + prettyError (DataDecodingError msg) = "Datum decoding error: " <> pshow msg + toLedgerDatum :: L.Era (LedgerEra era) => OldApi.TxOutDatum CtxTx era -> Either DatumDecodingError (L.Datum (LedgerEra era)) diff --git a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs index 4f74e21396..b200701668 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs @@ -15,6 +15,7 @@ module Cardano.Api.Experimental.Tx.Internal.Fee ( TxBodyErrorAutoBalance (..) , TxFeeEstimationError (..) + , calculateMinimumUTxO , collectTxBodyScriptWitnesses , estimateBalancedTxBody , evaluateTransactionExecutionUnits From f3ddf9e5fd383b4daa923a0637f9c3779e99d460 Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Mon, 2 Feb 2026 09:53:57 -0400 Subject: [PATCH 6/6] Fix cardano-wasm compilation errors --- cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs b/cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs index ce9346f4e5..a3618aea63 100644 --- a/cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs +++ b/cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs @@ -56,7 +56,7 @@ import Lens.Micro ((%~), (&), (.~), (<>~)) data UnsignedTxObject = forall era. UnsignedTxObject { unsignedTxEra :: Exp.Era era - , unsignedTx :: Exp.UnsignedTx era + , unsignedTx :: Exp.UnsignedTx (Exp.LedgerEra era) } deriving instance Show UnsignedTxObject