Architecture
Balancing pipeline
Transaction balancing transforms a partial transaction (user-specified
outputs, no inputs or fees) into a fully balanced transaction ready for
signing. The core entry point is balanceTx in
Cardano.Balance.Tx.Balance.
Pipeline stages
flowchart TD
A["Partial Tx + UTxO + Protocol Params"] --> B
B["1. Coin Selection\n(CoinSelection)"]
B -- "inputs selected" --> C
C["2. Fee Estimation\n(SizeEstimation)"]
C -- "fee computed" --> D
D["3. Change Outputs\n(Surplus, TokenBundleSize)"]
D -- "change distributed" --> E
E["4. Redeemer Assignment\n(Redeemers)"]
E -- "redeemers reindexed" --> F
F["5. Validation"]
F --> G["Balanced Tx (ready to sign)"]
Iteration
The algorithm must iterate because adding inputs changes the transaction size and therefore the fee. Each iteration:
- Estimates the fee for the current transaction
- Runs coin selection if more inputs are needed
- Recomputes change outputs
- Checks if the fee has stabilized
Convergence is guaranteed because each round can only add inputs (never remove them), and the UTxO set is finite.
flowchart TD
A["Estimate fee"] --> B["Run coin selection"]
B --> C["Recompute change outputs"]
C --> D{"Fee stabilized?"}
D -- "No" --> A
D -- "Yes" --> E["Proceed to validation"]
Module organization
The library is organized into three layers:
Core types
Primitive— lightweight value types (coin, token bundle, address) inlined fromcardano-wallet-primitive, bridging to ledger types viaPrimitive.ConvertTx— transaction-level types, key witness countingTxWithUTxO— a transaction paired with its resolved UTxO contextEras— era definitions (RecentEracovering Babbage/Conway)
Balancing logic
Balance— the mainbalanceTxfunction and error typesBalance.CoinSelection— adapter between ledger types and thecardano-coin-selectionlibraryBalance.Surplus— distributing fee surplus between padding and changeBalance.TokenBundleSize— assessing whether token bundles fit in a single output
Utilities
SizeEstimation— predicting serialized transaction sizeRedeemers— assigning script redeemer indicesSign— transaction signingTimeTranslation— slot/time conversion from epoch infoUTxOAssumptions— assumptions about UTxO script types for size estimation
graph TD
subgraph Core["Core types"]
Primitive
Tx
TxWithUTxO
Eras
end
subgraph Balancing["Balancing logic"]
Balance
CoinSelection["Balance.CoinSelection"]
Surplus["Balance.Surplus"]
TokenBundleSize["Balance.TokenBundleSize"]
end
subgraph Utilities
SizeEstimation
Redeemers
Sign
TimeTranslation
UTxOAssumptions
end
Balance --> CoinSelection
Balance --> Surplus
Balance --> TokenBundleSize
Balance --> SizeEstimation
Balance --> Redeemers
Balancing --> Core
Utilities --> Core
Era support
The library uses a RecentEra GADT to support Babbage and Conway. All
era-specific logic is isolated in Eras and pattern-matched where
needed, keeping the core balancing algorithm era-polymorphic.