Skip to content

Widen Exp.SignedTx to all Shelley-based eras#1199

Merged
Jimbo4350 merged 2 commits intomasterfrom
jordan/widen-ledger-era-family
May 6, 2026
Merged

Widen Exp.SignedTx to all Shelley-based eras#1199
Jimbo4350 merged 2 commits intomasterfrom
jordan/widen-ledger-era-family

Conversation

@Jimbo4350
Copy link
Copy Markdown
Contributor

Context

Reparameterise Cardano.Api.Experimental.SignedTx and its SerialiseAsRawBytes instance on ShelleyLedgerEra era instead of LedgerEra era, so SignedTx era types for every Shelley-based era (Shelley → Dijkstra) — not just Conway+.

The motivation is unblocking the cardano-cli debug transaction view (runTransactionViewCmd handles InAnyShelleyBasedEra). Migrating it off the legacy TxBodyContent decomposition onto Exp.SignedTx era + ledger-side lenses regresses on pre-Conway tx files unless Exp.SignedTx is reachable for all Shelley-based eras.

How to trust this PR

The change is deliberately surgical — 12 lines across two files, plus a changelog fragment.

Why the LedgerEra family is left alone: EraCommonConstraints (Era.hs:301) bundles Conway-onwards ledger constraints (L.ConwayEraGov, L.ConwayEraTxBody, L.ConwayEraTxCert, L.ConwayEraCertState, L.GovState ~ L.ConwayGovState) over LedgerEra era. Widening LedgerEra would break every site that uses obtainCommonConstraints or IsEra era — i.e. Tx.hs builders, Certificate.hs, BodyContent/New.hs. Switching only SignedTx (which needs only L.EraTx (ShelleyLedgerEra era), available for every Shelley-based era via ShelleyBasedEraConstraints) avoids that ripple entirely.

Build paths still Conway+ gated: signTx, makeKeyWitness, and convertTxBodyToUnsignedTx take Era era, whose constructors are ConwayEra/DijkstraEra only. For those eras, LedgerEra era ~ ShelleyLedgerEra era is supplied by obtainCommonConstraints, so SignedTx signedTx (Tx.hs:332) elaborates without code change.

Byron is irrelevant: ShelleyLedgerEra is undefined for Byron, and runTransactionViewCmd already excludes Byron via InAnyShelleyBasedEra. Byron tx is the separate ATxAux type.

Reachability: ShelleyLedgerEra is already reachable to downstream code via import Cardano.Api (transitively re-exported through Cardano.Api.EraCardano.Api.Era.Internal.Eon.ShelleyBasedEra), so no new exports were needed.

To verify:

  • cabal build cardano-api -j4 — clean.
  • cabal test cardano-api:cardano-api-test --test-show-details=direct -j4 — all 220 tests pass locally.

Checklist

  • Commit sequence broadly makes sense and commits have useful messages
  • New tests are added if needed and existing tests are updated. See Running tests for more details
  • Self-reviewed the diff
  • Changelog fragment added in .changes/

Reparameterise Cardano.Api.Experimental.SignedTx and its
SerialiseAsRawBytes instance on ShelleyLedgerEra era instead of
LedgerEra era. This lets SignedTx and its raw-bytes deserialisation
type for every Shelley-based era (Shelley through Dijkstra) without
widening the LedgerEra family or its Conway-onwards constraint
surface (EraCommonConstraints), which would have rippled into the
experimental tx builders.

Build paths (signTx, makeKeyWitness, convertTxBodyToUnsignedTx) take
Era era, whose constructors only cover Conway/Dijkstra, so they
remain Conway+ gated; for those eras LedgerEra era ~ ShelleyLedgerEra
era is provided by obtainCommonConstraints, so the SignedTx
constructor application elaborates with no further changes.

The motivation is unblocking cardano-cli's debug transaction view,
which handles InAnyShelleyBasedEra and needs to deserialise into
Exp.SignedTx era for pre-Conway tx files.
Copilot AI review requested due to automatic review settings May 6, 2026 13:50
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR widens the experimental Cardano.Api.Experimental.SignedTx wrapper (and its SerialiseAsRawBytes instance) from being parameterised by the experimental LedgerEra family to using ShelleyLedgerEra, with the goal of making SignedTx era usable across all Shelley-based eras (Shelley → Dijkstra) without widening the Conway+-specific LedgerEra constraint surface.

Changes:

  • Reparameterise Exp.SignedTx and its SerialiseAsRawBytes instance to use ShelleyLedgerEra era instead of LedgerEra era.
  • Update a test type annotation to match the new SignedTx underlying ledger-era parameterisation.
  • Add a Herald changelog fragment describing the widening change.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
cardano-api/src/Cardano/Api/Experimental/Tx.hs Reparameterises SignedTx and raw-bytes serialisation to use ShelleyLedgerEra so it can apply to all Shelley-based eras.
cardano-api/test/cardano-api-test/Test/Cardano/Api/Experimental.hs Adjusts a test’s ledger-era type annotation to align with the updated SignedTx representation.
.changes/20260505_cardano_api_widen_signed_tx_to_shelley_based_eras.yml Declares the change as compatible and documents the motivation/approach.

Comment on lines +4 to +6
- compatible
description: |
Widen `Cardano.Api.Experimental.SignedTx era` to all Shelley-based eras (Shelley through Dijkstra) by reparameterising it on `ShelleyLedgerEra era` instead of `LedgerEra era`. This allows deserialising `SignedTx` for any Shelley-based era via `SerialiseAsRawBytes` without widening the `LedgerEra` family or its Conway-onwards constraint surface.
Comment on lines 283 to 307
@@ -294,16 +294,16 @@ instance HasTypeProxy era => HasTypeProxy (SignedTx era) where

instance
( HasTypeProxy era
, L.EraTx (LedgerEra era)
, L.EraTx (ShelleyLedgerEra era)
)
=> SerialiseAsRawBytes (SignedTx era)
where
serialiseToRawBytes (SignedTx tx) =
Ledger.serialize' (Ledger.eraProtVerHigh @(LedgerEra era)) tx
Ledger.serialize' (Ledger.eraProtVerHigh @(ShelleyLedgerEra era)) tx
deserialiseFromRawBytes _ =
bimap wrapError SignedTx
. Ledger.decodeFullAnnotator
(Ledger.eraProtVerHigh @(LedgerEra era))
(Ledger.eraProtVerHigh @(ShelleyLedgerEra era))
"SignedTx"
@@ -281,7 +281,7 @@ makeKeyWitness era (UnsignedTx unsignedTx) wsk =

-- | A transaction that has been witnesssed
data SignedTx era
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should switch to ledger eras here eventually

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯

@Jimbo4350 Jimbo4350 added this pull request to the merge queue May 6, 2026
Merged via the queue into master with commit fa48c82 May 6, 2026
31 checks passed
@Jimbo4350 Jimbo4350 deleted the jordan/widen-ledger-era-family branch May 6, 2026 21:32
Jimbo4350 added a commit to IntersectMBO/cardano-cli that referenced this pull request May 6, 2026
friendlyTx and friendlyTxBody now take ShelleyBasedEra era (instead of
Exp.Era era), accepting Exp.SignedTx era / Exp.UnsignedTx
(ShelleyLedgerEra era). This unblocks transaction view for pre-Conway
tx files.

friendlyTxBodyImpl dispatches on ShelleyBasedEra at the top level and
each branch renders its full body inline. Era-gated fields (mint,
collateral, reference inputs, governance actions, etc.) are present
only in branches whose era supports them.

The eon-based dispatchers (forShelleyBasedEraInEon, AlonzoEraOnwards,
ConwayEraOnwards, ...) are no longer used in this module.

Adds a temporary source-repository-package for cardano-api at the
widen-Exp.SignedTx-to-Shelley-based-eras branch (PR
IntersectMBO/cardano-api#1199). To be removed once that PR merges and
ships in CHaP.
Jimbo4350 added a commit to IntersectMBO/cardano-cli that referenced this pull request May 7, 2026
friendlyTx and friendlyTxBody now take ShelleyBasedEra era (instead of
Exp.Era era), accepting Exp.SignedTx era / Exp.UnsignedTx
(ShelleyLedgerEra era). This unblocks transaction view for pre-Conway
tx files.

friendlyTxBodyImpl dispatches on ShelleyBasedEra at the top level and
each branch renders its full body inline. Era-gated fields (mint,
collateral, reference inputs, governance actions, etc.) are present
only in branches whose era supports them.

The eon-based dispatchers (forShelleyBasedEraInEon, AlonzoEraOnwards,
ConwayEraOnwards, ...) are no longer used in this module.

Adds a temporary source-repository-package for cardano-api at the
widen-Exp.SignedTx-to-Shelley-based-eras branch (PR
IntersectMBO/cardano-api#1199). To be removed once that PR merges and
ships in CHaP.
Jimbo4350 added a commit to IntersectMBO/cardano-cli that referenced this pull request May 7, 2026
friendlyTx and friendlyTxBody now take ShelleyBasedEra era (instead of
Exp.Era era), accepting Exp.SignedTx era / Exp.UnsignedTx
(ShelleyLedgerEra era). This unblocks transaction view for pre-Conway
tx files.

friendlyTxBodyImpl dispatches on ShelleyBasedEra at the top level and
each branch renders its full body inline. Era-gated fields (mint,
collateral, reference inputs, governance actions, etc.) are present
only in branches whose era supports them.

The eon-based dispatchers (forShelleyBasedEraInEon, AlonzoEraOnwards,
ConwayEraOnwards, ...) are no longer used in this module.

Adds a temporary source-repository-package for cardano-api at the
widen-Exp.SignedTx-to-Shelley-based-eras branch (PR
IntersectMBO/cardano-api#1199). To be removed once that PR merges and
ships in CHaP.
Jimbo4350 added a commit to IntersectMBO/cardano-cli that referenced this pull request May 8, 2026
… Shelley-based eras

friendlyTx and friendlyTxBody now take ShelleyBasedEra era and accept
Exp.SignedTx era / Exp.UnsignedTx (ShelleyLedgerEra era). They are no
longer parameterised by Exp.Era era (which is Conway-only) — the
renderer works for Shelley through Conway tx and tx-body files,
unblocking transaction view for pre-Conway tx files.

friendlyTxBodyImpl reads every field directly from the ledger TxBody
via lenses, so the old API's TxBodyContent constructor and
getTxBodyContent are no longer used in this module.

The body dispatches on ShelleyBasedEra at the top level and each
branch renders its full body inline. Era-gated fields (mint,
collateral, reference inputs, governance actions, etc.) are present
only in branches whose era supports them. The eon-based dispatchers
(forShelleyBasedEraInEon, AlonzoEraOnwards, ConwayEraOnwards, ...) are
no longer used in this module.

Relies on cardano-api 11.1.0.0 (PR IntersectMBO/cardano-api#1199),
which widened Exp.SignedTx / Exp.UnsignedTx to all Shelley-based eras.
Jimbo4350 added a commit to IntersectMBO/cardano-cli that referenced this pull request May 8, 2026
…elley-based eras, and refactor with per-feature helpers

friendlyTx and friendlyTxBody now take ShelleyBasedEra era and accept
Exp.SignedTx era / Exp.UnsignedTx (ShelleyLedgerEra era). They are no
longer parameterised by Exp.Era era (which is Conway-only) — the
renderer works for Shelley through Conway tx and tx-body files,
unblocking transaction view for pre-Conway tx files.

friendlyTxBodyImpl reads every field directly from the ledger TxBody
via lenses, so the old API's TxBodyContent constructor and
getTxBodyContent are no longer used in this module.

The body composes a list of pairs from per-feature helpers
(validityRangePair, mintPairFor, collateralInputsPairFor,
requiredSignersPairFor, referenceInputsPairFor, totalCollateralPairFor,
returnCollateralPairFor, alonzoScriptWitnessPairsFor,
conwayBodyPairsFor). Era-gated helpers return [Aeson.Pair] and emit []
in eras that don't have the field, so JSON keys for absent-in-this-era
fields (e.g. "mint" in Shelley, "collateral inputs" in Mary) are
omitted from the output rather than rendered as null. The eon-based
dispatchers (forShelleyBasedEraInEon, AlonzoEraOnwards,
ConwayEraOnwards, ...) are no longer used in this module.

Also adds an Alonzo YAML golden test alongside the existing JSON
golden to cover the YAML output path for that era.

Relies on cardano-api 11.1.0.0 (PR IntersectMBO/cardano-api#1199),
which widened Exp.SignedTx / Exp.UnsignedTx to all Shelley-based eras.
Jimbo4350 added a commit to IntersectMBO/cardano-cli that referenced this pull request May 8, 2026
…elley-based eras, and refactor with per-feature helpers

friendlyTx and friendlyTxBody now take ShelleyBasedEra era and accept
Exp.SignedTx era / Exp.UnsignedTx (ShelleyLedgerEra era). They are no
longer parameterised by Exp.Era era (which is Conway-only) — the
renderer works for Shelley through Conway tx and tx-body files,
unblocking transaction view for pre-Conway tx files.

friendlyTxBodyImpl reads every field directly from the ledger TxBody
via lenses, so the old API's TxBodyContent constructor and
getTxBodyContent are no longer used in this module.

The body composes a list of pairs from per-feature helpers
(validityRangePair, mintPairFor, collateralInputsPairFor,
requiredSignersPairFor, referenceInputsPairFor, totalCollateralPairFor,
returnCollateralPairFor, alonzoScriptWitnessPairsFor,
conwayBodyPairsFor). Era-gated helpers return [Aeson.Pair] and emit []
in eras that don't have the field, so JSON keys for absent-in-this-era
fields (e.g. "mint" in Shelley, "collateral inputs" in Mary) are
omitted from the output rather than rendered as null. The eon-based
dispatchers (forShelleyBasedEraInEon, AlonzoEraOnwards,
ConwayEraOnwards, ...) are no longer used in this module.

Also adds an Alonzo YAML golden test alongside the existing JSON
golden to cover the YAML output path for that era.

Relies on cardano-api 11.1.0.0 (PR IntersectMBO/cardano-api#1199),
which widened Exp.SignedTx / Exp.UnsignedTx to all Shelley-based eras.
Jimbo4350 added a commit to IntersectMBO/cardano-cli that referenced this pull request May 8, 2026
…elley-based eras, and refactor with per-feature helpers

friendlyTx and friendlyTxBody now take ShelleyBasedEra era and accept
Exp.SignedTx era / Exp.UnsignedTx (ShelleyLedgerEra era). They are no
longer parameterised by Exp.Era era (which is Conway-only) — the
renderer works for Shelley through Conway tx and tx-body files,
unblocking transaction view for pre-Conway tx files.

friendlyTxBodyImpl reads every field directly from the ledger TxBody
via lenses, so the old API's TxBodyContent constructor and
getTxBodyContent are no longer used in this module.

The body composes a list of pairs from per-feature helpers
(validityRangePair, mintPairFor, collateralInputsPairFor,
requiredSignersPairFor, referenceInputsPairFor, totalCollateralPairFor,
returnCollateralPairFor, alonzoScriptWitnessPairsFor,
conwayBodyPairsFor). Era-gated helpers return [Aeson.Pair] and emit []
in eras that don't have the field, so JSON keys for absent-in-this-era
fields (e.g. "mint" in Shelley, "collateral inputs" in Mary) are
omitted from the output rather than rendered as null. The eon-based
dispatchers (forShelleyBasedEraInEon, AlonzoEraOnwards,
ConwayEraOnwards, ...) are no longer used in this module.

Also adds an Alonzo YAML golden test alongside the existing JSON
golden to cover the YAML output path for that era.

Relies on cardano-api 11.1.0.0 (PR IntersectMBO/cardano-api#1199),
which widened Exp.SignedTx / Exp.UnsignedTx to all Shelley-based eras.
Jimbo4350 added a commit to IntersectMBO/cardano-cli that referenced this pull request May 8, 2026
…elley-based eras, and refactor with per-feature helpers

friendlyTx and friendlyTxBody now take ShelleyBasedEra era and accept
Exp.SignedTx era / Exp.UnsignedTx (ShelleyLedgerEra era). They are no
longer parameterised by Exp.Era era (which is Conway-only) — the
renderer works for Shelley through Conway tx and tx-body files,
unblocking transaction view for pre-Conway tx files.

friendlyTxBodyImpl reads every field directly from the ledger TxBody
via lenses, so the old API's TxBodyContent constructor and
getTxBodyContent are no longer used in this module.

The body composes a list of pairs from per-feature helpers
(validityRangePair, mintPairFor, collateralInputsPairFor,
requiredSignersPairFor, referenceInputsPairFor, totalCollateralPairFor,
returnCollateralPairFor, alonzoScriptWitnessPairsFor,
conwayBodyPairsFor). Era-gated helpers return [Aeson.Pair] and emit []
in eras that don't have the field, so JSON keys for absent-in-this-era
fields (e.g. "mint" in Shelley, "collateral inputs" in Mary) are
omitted from the output rather than rendered as null. The eon-based
dispatchers (forShelleyBasedEraInEon, AlonzoEraOnwards,
ConwayEraOnwards, ...) are no longer used in this module.

Also adds an Alonzo YAML golden test alongside the existing JSON
golden to cover the YAML output path for that era.

Relies on cardano-api 11.1.0.0 (PR IntersectMBO/cardano-api#1199),
which widened Exp.SignedTx / Exp.UnsignedTx to all Shelley-based eras.
Jimbo4350 added a commit to IntersectMBO/cardano-cli that referenced this pull request May 8, 2026
…elley-based eras, and refactor with per-feature helpers

friendlyTx and friendlyTxBody now take ShelleyBasedEra era and accept
Exp.SignedTx era / Exp.UnsignedTx (ShelleyLedgerEra era). They are no
longer parameterised by Exp.Era era (which is Conway-only) — the
renderer works for Shelley through Conway tx and tx-body files,
unblocking transaction view for pre-Conway tx files.

friendlyTxBodyImpl reads every field directly from the ledger TxBody
via lenses, so the old API's TxBodyContent constructor and
getTxBodyContent are no longer used in this module.

The body composes a list of pairs from per-feature helpers
(validityRangePair, mintPairFor, collateralInputsPairFor,
requiredSignersPairFor, referenceInputsPairFor, totalCollateralPairFor,
returnCollateralPairFor, alonzoScriptWitnessPairsFor,
conwayBodyPairsFor). Era-gated helpers return [Aeson.Pair] and emit []
in eras that don't have the field, so JSON keys for absent-in-this-era
fields (e.g. "mint" in Shelley, "collateral inputs" in Mary) are
omitted from the output rather than rendered as null. The eon-based
dispatchers (forShelleyBasedEraInEon, AlonzoEraOnwards,
ConwayEraOnwards, ...) are no longer used in this module.

Also adds an Alonzo YAML golden test alongside the existing JSON
golden to cover the YAML output path for that era.

Relies on cardano-api 11.1.0.0 (PR IntersectMBO/cardano-api#1199),
which widened Exp.SignedTx / Exp.UnsignedTx to all Shelley-based eras.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants