Home / Input Output / cardano-wallet
Apr 18, 10-11 AM (0)
Apr 18, 11-12 PM (0)
Apr 18, 12-1 PM (0)
Apr 18, 1-2 PM (0)
Apr 18, 2-3 PM (0)
Apr 18, 3-4 PM (0)
Apr 18, 4-5 PM (0)
Apr 18, 5-6 PM (0)
Apr 18, 6-7 PM (0)
Apr 18, 7-8 PM (0)
Apr 18, 8-9 PM (0)
Apr 18, 9-10 PM (0)
Apr 18, 10-11 PM (0)
Apr 18, 11-12 AM (0)
Apr 19, 12-1 AM (0)
Apr 19, 1-2 AM (0)
Apr 19, 2-3 AM (0)
Apr 19, 3-4 AM (0)
Apr 19, 4-5 AM (0)
Apr 19, 5-6 AM (0)
Apr 19, 6-7 AM (0)
Apr 19, 7-8 AM (0)
Apr 19, 8-9 AM (0)
Apr 19, 9-10 AM (0)
Apr 19, 10-11 AM (0)
Apr 19, 11-12 PM (0)
Apr 19, 12-1 PM (0)
Apr 19, 1-2 PM (0)
Apr 19, 2-3 PM (0)
Apr 19, 3-4 PM (0)
Apr 19, 4-5 PM (0)
Apr 19, 5-6 PM (0)
Apr 19, 6-7 PM (0)
Apr 19, 7-8 PM (0)
Apr 19, 8-9 PM (0)
Apr 19, 9-10 PM (0)
Apr 19, 10-11 PM (0)
Apr 19, 11-12 AM (0)
Apr 20, 12-1 AM (0)
Apr 20, 1-2 AM (0)
Apr 20, 2-3 AM (0)
Apr 20, 3-4 AM (0)
Apr 20, 4-5 AM (0)
Apr 20, 5-6 AM (0)
Apr 20, 6-7 AM (0)
Apr 20, 7-8 AM (0)
Apr 20, 8-9 AM (0)
Apr 20, 9-10 AM (0)
Apr 20, 10-11 AM (0)
Apr 20, 11-12 PM (0)
Apr 20, 12-1 PM (0)
Apr 20, 1-2 PM (2)
Apr 20, 2-3 PM (5)
Apr 20, 3-4 PM (0)
Apr 20, 4-5 PM (1)
Apr 20, 5-6 PM (0)
Apr 20, 6-7 PM (0)
Apr 20, 7-8 PM (0)
Apr 20, 8-9 PM (0)
Apr 20, 9-10 PM (0)
Apr 20, 10-11 PM (0)
Apr 20, 11-12 AM (0)
Apr 21, 12-1 AM (0)
Apr 21, 1-2 AM (0)
Apr 21, 2-3 AM (0)
Apr 21, 3-4 AM (0)
Apr 21, 4-5 AM (0)
Apr 21, 5-6 AM (0)
Apr 21, 6-7 AM (0)
Apr 21, 7-8 AM (0)
Apr 21, 8-9 AM (3)
Apr 21, 9-10 AM (0)
Apr 21, 10-11 AM (0)
Apr 21, 11-12 PM (0)
Apr 21, 12-1 PM (0)
Apr 21, 1-2 PM (0)
Apr 21, 2-3 PM (0)
Apr 21, 3-4 PM (0)
Apr 21, 4-5 PM (0)
Apr 21, 5-6 PM (0)
Apr 21, 6-7 PM (0)
Apr 21, 7-8 PM (0)
Apr 21, 8-9 PM (0)
Apr 21, 9-10 PM (0)
Apr 21, 10-11 PM (0)
Apr 21, 11-12 AM (0)
Apr 22, 12-1 AM (0)
Apr 22, 1-2 AM (0)
Apr 22, 2-3 AM (0)
Apr 22, 3-4 AM (4)
Apr 22, 4-5 AM (0)
Apr 22, 5-6 AM (0)
Apr 22, 6-7 AM (0)
Apr 22, 7-8 AM (0)
Apr 22, 8-9 AM (0)
Apr 22, 9-10 AM (0)
Apr 22, 10-11 AM (0)
Apr 22, 11-12 PM (0)
Apr 22, 12-1 PM (0)
Apr 22, 1-2 PM (0)
Apr 22, 2-3 PM (0)
Apr 22, 3-4 PM (7)
Apr 22, 4-5 PM (0)
Apr 22, 5-6 PM (0)
Apr 22, 6-7 PM (1)
Apr 22, 7-8 PM (4)
Apr 22, 8-9 PM (0)
Apr 22, 9-10 PM (0)
Apr 22, 10-11 PM (0)
Apr 22, 11-12 AM (0)
Apr 23, 12-1 AM (0)
Apr 23, 1-2 AM (0)
Apr 23, 2-3 AM (0)
Apr 23, 3-4 AM (0)
Apr 23, 4-5 AM (0)
Apr 23, 5-6 AM (0)
Apr 23, 6-7 AM (0)
Apr 23, 7-8 AM (2)
Apr 23, 8-9 AM (0)
Apr 23, 9-10 AM (1)
Apr 23, 10-11 AM (0)
Apr 23, 11-12 PM (0)
Apr 23, 12-1 PM (0)
Apr 23, 1-2 PM (9)
Apr 23, 2-3 PM (1)
Apr 23, 3-4 PM (3)
Apr 23, 4-5 PM (6)
Apr 23, 5-6 PM (0)
Apr 23, 6-7 PM (0)
Apr 23, 7-8 PM (0)
Apr 23, 8-9 PM (0)
Apr 23, 9-10 PM (0)
Apr 23, 10-11 PM (0)
Apr 23, 11-12 AM (0)
Apr 24, 12-1 AM (0)
Apr 24, 1-2 AM (0)
Apr 24, 2-3 AM (0)
Apr 24, 3-4 AM (4)
Apr 24, 4-5 AM (0)
Apr 24, 5-6 AM (0)
Apr 24, 6-7 AM (0)
Apr 24, 7-8 AM (2)
Apr 24, 8-9 AM (0)
Apr 24, 9-10 AM (0)
Apr 24, 10-11 AM (0)
Apr 24, 11-12 PM (0)
Apr 24, 12-1 PM (0)
Apr 24, 1-2 PM (2)
Apr 24, 2-3 PM (0)
Apr 24, 3-4 PM (0)
Apr 24, 4-5 PM (4)
Apr 24, 5-6 PM (0)
Apr 24, 6-7 PM (0)
Apr 24, 7-8 PM (0)
Apr 24, 8-9 PM (0)
Apr 24, 9-10 PM (0)
Apr 24, 10-11 PM (0)
Apr 24, 11-12 AM (0)
Apr 25, 12-1 AM (0)
Apr 25, 1-2 AM (0)
Apr 25, 2-3 AM (0)
Apr 25, 3-4 AM (0)
Apr 25, 4-5 AM (0)
Apr 25, 5-6 AM (0)
Apr 25, 6-7 AM (1)
Apr 25, 7-8 AM (0)
Apr 25, 8-9 AM (19)
Apr 25, 9-10 AM (0)
Apr 25, 10-11 AM (0)
81 commits this week Apr 18, 2026 - Apr 25, 2026
docs: plan for finishing SealedTx cardano-api decommission
Enumerates every remaining caller of the deprecated surface after
#5271: production (Cardano.Wallet.hs, Server.hs), old tx builder
(Shelley/Transaction.hs, partially overlaps with #5243), integration
tests (Shared/Transactions.hs, addRequiredSigners in TransactionsNew)
and unit tests (TransactionSpec, TransactionLedgerSpec).

Organises the work into three phases:
  A. reachable without #5243 (4 sites)
  B. unit-test migration (~20 sites, two files)
  C. delete the bridge functions and the three Cardano.Api*
     imports in SealedTx.hs
refactor: drop dead cardano-api body in addRequiredSigners
The function has been an ADP-3077 TODO stub (error "...") for a long
time; the commented-out cardano-api body still referenced
getSealedTxBody and sealedTxFromCardanoBody, which blocks their
removal. Drop the dead block and note that a future implementation
should operate on Read.Tx era via reqSignerHashesTxBodyL.
refactor: drop local sealWriteTx cardano-api bridge in Server.hs
Server.hs carried a local copy of sealWriteTx that re-entered
cardano-api (toCardanoApiTx + sealedTxFromCardano) to wrap an already
ledger-native balanceTx result. Import the ledger-native sealWriteTx
from Transaction.Ledger instead; the local helper goes away. Two call
sites now pass Write.recentEra explicitly.

Drops the cardano-api bridges cardanoEraFromRecentEra, toCardanoApiTx
and W.sealedTxFromCardano from this module's imports.
refactor: port metadata extraction in Shared/Transactions to ledger-native
Mirror the TransactionsNew.hs:getMetadataFromTx port: project metadata
directly from Read.Tx era via Meta.getMetadata . Meta.getEraMetadata
instead of round-tripping through cardano-api. Drops the two callers
of cardanoTxIdeallyNoLaterThan in this file and the Cardano.Api /
ApiEra qualified imports.
refactor: migrate buildAndSignTransactionPure to ledger-native seal
The signedTx wrapping in Cardano.Wallet went through
toCardanoApiTx -> inAnyCardanoEra -> sealedTxFromCardano purely to
smuggle the already-ledger tx back through cardano-api. Use the
existing ledger-native sealWriteTx from Transaction.Ledger instead
(now exported). Drops the two cardano-api bridges inAnyCardanoEra and
sealedTxFromCardano from this module.

Also refresh the sealWriteTx haddock (the function has been ledger-
native since the last revamp; the stale comment claimed otherwise).
feat: add sealedTxFromLedgerTx and migrate sealWriteTx off cardano-api
Introduce sealedTxFromLedgerTx :: Read.IsEra era => Read.Tx era -> SealedTx.
Serialises via Read.serializeTx (ledger-native) and wraps in EraValue
without any cardano-api involvement.

Migrate sealWriteTx in Transaction.Ledger.hs to use the new
constructor, pattern-matching on RecentEra to witness the era.
Removes the toCardanoApiTx -> sealedTxFromCardano' roundtrip,
dropping the Cardano.Api.Extra import from that module.

Step 2a of SealedTx decommission plan.
feat: add sealedTxWitnessCount (ledger-native) and migrate Server.hs
Introduce sealedTxWitnessCount :: SealedTx -> Int, counting VKey
plus bootstrap witnesses via 'addrTxWitsL'/'bootAddrTxWitsL' on the
stored 'EraValue Read.Tx'. Byron txs counted as 0 (wallet doesn't
construct them through SealedTx).

Migrate Server.hs's two 'length $ getSealedTxWitnesses sealedTx'
sites (redeemer and witness accounting) to use it. Drops
'getSealedTxWitnesses' from Server.hs's import list.

Step 2b of SealedTx decommission plan.
refactor: use ledger-native deserialisation in parsePartialTx
Replace cardanoTxInExactEra (cardano-api path) with
deserializeTx (ledger-native) in the redeemer-bearing
partial tx parser. Pattern-matches on RecentEra era so
the era singleton witnesses the target ledger type.

One fewer caller of cardano-api's
'deserialiseFromCBOR / InAnyCardanoEra Cardano.Tx' path.
'fromCardanoApiTx' → direct use of 'Read.Tx era' unwrapped
into 'Write.Tx era'.
feat: port getMetadataFromTx in TransactionsNew to ledger-native
Replace cardano-api round-trip with direct Read.Tx era projection via
Meta.getMetadata . Meta.getEraMetadata. Drops the four callers of
cardanoTxIdeallyNoLaterThan in this file (the cardano-api re-decode
was only used to feed getTxBody/txMetadata).

No behavioural change: the ledger metadata path is what Server.hs and
DB.TransactionInfo already use.
refactor: migrate _postSealedTx to ledger-native GenTx via EraValue Read.Tx
Replace the cardano-api path
(SealedTx → unsealShelleyTx → TxInMode → toConsensusGenTx → GenTx)
with a direct ledger-native path
(SealedTx → unsafeReadTx :: EraValue Read.Tx → consensusGenTxFromTxRecent → GenTx).

The stored 'EraValue Read.Tx' already knows its era, so the
separate 'readCurrentEra' query is no longer needed, and
'TxInMode' / 'toConsensusGenTx' / 'unsealShelleyTx' /
'UnsealException' all become unused.

Deletes:
  - Cardano.Wallet.Primitive.Ledger.Shelley.unsealShelleyTx
  - Cardano.Wallet.Primitive.Ledger.Shelley.UnsealException
  - cardano-api 'TxInMode' import in primitive
  - cardano-api 'toConsensusGenTx' import in network-layer

Adds 'unsafeReadTx' to the re-export of 'SealedTx' in
Cardano.Wallet.Primitive.Types.Tx. Step 1 of SealedTx decommission
plan. One fewer caller of 'cardanoTxIdeallyNoLaterThan'; the
submission path no longer touches cardano-api.
feat: wallet-owned types + ledger-native builders (drop-cardano-api foundation) (#5270)
## Summary

**Foundation layer** of the cardano-api removal (phase A of the split of
#5236). Adds wallet-owned types and ledger-native builders **without
switching any existing call site** — the new code paths exist alongside
the cardano-api paths and are only exercised by the new test duplicate.
Low risk, reviewable in one sitting.

Companion PR (call-site migration) will be opened against this branch
once merged. The review-response commit also tightens one existing
address-network-tag helper to delegate the mainnet/testnet bit to
ledger, with unchanged semantics.

## What lands here (15 commits, all bisect-safe)

| # | SHA | Purpose |
|---|---|---|
| 1–4 | docs | spec / plan / tasks artifacts (speckit) under
`specs/001-drop-cardano-api/` |
| 5 | `7307a0fe` | Add the initial `SNetworkId n -> Ledger.Network`
conversion, now exposed as `sNetworkIdToLedger` after review feedback |
| 6 | `e1a1acaf` | Rewrite `SealedTx` internals to `EraValue Read.Tx`
(previous cardano-api reconstruction helpers retained as temporary
bridges) |
| 7 | `fd5fe22f` | Replace `Cardano.Api.NetworkId` with wallet-owned
`NetworkId` in 4 files |
| 8 | `393eaa28` | Add wallet-owned `TxMetadata` module
(`lib/primitive/.../Types/Tx/TxMetadata.hs`) with JSON schema conversion
ported from cardano-api |
| 9 | `92a7699d` | Add `Transaction.Build.mkLedgerTx` — builds a ledger
`Tx era` from its components using `mkBasicTxBody` + lenses |
| 10 | `726656ab` | Add `Transaction.Ledger` — ledger-native tx
construction (`mkTransactionLedger`, `constructUnsignedTxLedger`,
`buildLedgerTx`, `TxPayload`, `mkRewardAccount`) |
| 11 | `68e441c5` | Complete `Transaction.Ledger` exports |
| 12 | `13e76caa` | Duplicate `TransactionSpec.hs` →
`TransactionLedgerSpec.hs` as baseline for exercising the new builder in
tests |
| 13 | `984e8177` | Add ledger-native cert helpers:
`certificateFromDelegationActionLedger`,
`certificateFromVotingActionLedger`, `toLedgerStakeCred`, `toLedgerCoin`
|
| 14 | `d8e74e41` | Wire ledger-native witness construction
(`mkShelleyWitnessLedger`, `mkByronWitnessLedger`) into
`TransactionLedgerSpec` |
| 15 | `2e210821` | Address reviewer feedback: use
`Ledger.networkToWord8` for address network tags; document wallet
`NetworkId` vs ledger `Network`; try Dijkstra in ledger-native
`SealedTx` decode; document why `TxMetadata` keeps the
wallet/cardano-api-compatible surface while converting to ledger
metadata internally |

## Ledger 1.19/1.20 adaptations applied

- `Ledger.Tx era` → `Write.Tx era` (balance-tx's `type Tx era = Core.Tx
Core.TopTx era` alias for the 1.19 `TxLevel` kind lift)
- `Ledger.TxBody era` → `Write.TxBody era`
- `Ledger.RewardAccount` pattern synonym → `Ledger.AccountAddress
(Ledger.AccountId …)` (1.20 rename)
- `KeyRole (Witness)` import → `Keys.Witness` qualified (1.20 reorg —
`Witness` is a standalone type, not a `KeyRole` data constructor)
- `hashAnnotated body` → `hashAnnotated @_ @EraIndependentTxBody body`
(1.20 `HashAnnotated x i | x -> i` functional dep can't resolve through
`Write.TxBody era` type synonym)

## What is NOT in this PR

- No transaction construction, `balanceTx`, signing, cert construction,
or `TxMetadata` consumer migration lands here. Those paths still go
through cardano-api; the new ledger-native paths sit alongside for now.
The only existing-path tweak is the equivalent `postAnyAddress` network
tag helper change from manual 1/0 matching to `Ledger.networkToWord8`.
- No bridges are added or removed: `Cardano.Api.Extra` shim,
`sealWriteTx`, and `certToLedger`/`unCert` helpers are untouched.
- No cabal changes to drop `cardano-api` (the dependency is still pulled
in by the unchanged call sites).

## Per-commit CI gate

The original 14 commits were gated through `fourmolu --mode check` +
`hlint lib` + `nix build .#cardano-wallet` and PASS individually.

The review-response commit `2e210821` was checked with direct Fourmolu
on the touched Haskell files and a library-only Cabal build of
`cardano-wallet-primitive`, `cardano-wallet-api`, and `cardano-wallet`
inside `nix develop`. The stricter `just build` path currently stops in
pre-existing `cardano-wallet-read` warnings promoted to errors before
reaching the changed modules.

## Test plan

Review response:
- [x] `nix develop --command fourmolu --mode check` on touched Haskell
files
- [x] `nix develop --command cabal build lib:cardano-wallet-primitive
lib:cardano-wallet-api lib:cardano-wallet -O0 -v0`
- [ ] `nix develop --command just build 'cardano-wallet-primitive
cardano-wallet-api cardano-wallet'` with `-Werror` is blocked by
pre-existing `cardano-wallet-read` warnings

Original branch:

- [x] `nix build .#cardano-wallet` succeeds at every commit
(bisect-safe)
- [x] `fourmolu --mode check` clean
- [x] `hlint lib` no hints
- [x] Full `build-gate (Linux)` CI on the previous tip before
review-response commit
- [ ] Full CI on the new review-response tip
- [x] `unit-cardano-wallet-unit` test suite (deferred to CI)
refactor: drop local sealWriteTx cardano-api bridge in Server.hs
Server.hs carried a local copy of sealWriteTx that re-entered
cardano-api (toCardanoApiTx + sealedTxFromCardano) to wrap an already
ledger-native balanceTx result. Import the ledger-native sealWriteTx
from Transaction.Ledger instead; the local helper goes away. Two call
sites now pass Write.recentEra explicitly.

Drops the cardano-api bridges cardanoEraFromRecentEra, toCardanoApiTx
and W.sealedTxFromCardano from this module's imports.
refactor: migrate buildAndSignTransactionPure to ledger-native seal
The signedTx wrapping in Cardano.Wallet went through
toCardanoApiTx -> inAnyCardanoEra -> sealedTxFromCardano purely to
smuggle the already-ledger tx back through cardano-api. Use the
existing ledger-native sealWriteTx from Transaction.Ledger instead
(now exported). Drops the two cardano-api bridges inAnyCardanoEra and
sealedTxFromCardano from this module.

Also refresh the sealWriteTx haddock (the function has been ledger-
native since the last revamp; the stale comment claimed otherwise).
refactor: drop dead cardano-api body in addRequiredSigners
The function has been an ADP-3077 TODO stub (error "...") for a long
time; the commented-out cardano-api body still referenced
getSealedTxBody and sealedTxFromCardanoBody, which blocks their
removal. Drop the dead block and note that a future implementation
should operate on Read.Tx era via reqSignerHashesTxBodyL.
refactor: port metadata extraction in Shared/Transactions to ledger-native
Mirror the TransactionsNew.hs:getMetadataFromTx port: project metadata
directly from Read.Tx era via Meta.getMetadata . Meta.getEraMetadata
instead of round-tripping through cardano-api. Drops the two callers
of cardanoTxIdeallyNoLaterThan in this file and the Cardano.Api /
ApiEra qualified imports.
feat: port getMetadataFromTx in TransactionsNew to ledger-native
Replace cardano-api round-trip with direct Read.Tx era projection via
Meta.getMetadata . Meta.getEraMetadata. Drops the four callers of
cardanoTxIdeallyNoLaterThan in this file (the cardano-api re-decode
was only used to feed getTxBody/txMetadata).

No behavioural change: the ledger metadata path is what Server.hs and
DB.TransactionInfo already use.