Skip to Content
APIsUtilityCoin Selection API

Coin Selection API

The Coin Selection API provides strategies for selecting UTXOs when building transactions. It includes built-in algorithms and extension points for custom selection logic.

Overview

  • Multiple strategies: default, largest-first, random-improve
  • Configurable limits and datum handling
  • Inline datum and datum hash aware
  • Fallback chaining for robustness
  • UTXO discovery helpers via UtxoSelector

Core Interfaces

UtxoSelectionStrategy

public interface UtxoSelectionStrategy { Set<Utxo> select(AddressIterator addressIterator, List<Amount> outputAmounts, String datumHash, PlutusData inlineDatum, Set<Utxo> utxosToExclude, int maxUtxoSelectionLimit); UtxoSelectionStrategy fallback(); void setIgnoreUtxosWithDatumHash(boolean ignore); }

UtxoSelector

Utility interface to query UTXOs by predicate:

Optional<Utxo> findFirst(String address, Predicate<Utxo> predicate); List<Utxo> findAll(String address, Predicate<Utxo> predicate); default void setSearchByAddressVkh(boolean flag) { }

Built-in Selection Strategies

Default

UtxoSelectionStrategy strategy = new DefaultUtxoSelectionStrategyImpl(utxoSupplier); strategy.setIgnoreUtxosWithDatumHash(true); // default true Set<Utxo> selected = strategy.select( AddressIterators.of(senderAddress), List.of(Amount.ada(10)), null, // datumHash null, // inline datum Collections.emptySet(), 20);

Largest First

UtxoSelectionStrategy strategy = new LargestFirstUtxoSelectionStrategy(utxoSupplier); Set<Utxo> selected = strategy.select( AddressIterators.of(senderAddress), List.of(Amount.ada(5)), null, null, Collections.emptySet(), 10);

Random Improve

UtxoSelectionStrategy strategy = new RandomImproveUtxoSelectionStrategy(utxoSupplier); strategy.setIgnoreUtxosWithDatumHash(false); Set<Utxo> selected = strategy.select( AddressIterators.of(senderAddress), List.of(Amount.ada(15)), null, null, Collections.emptySet(), 15);

Using UtxoSelector

UtxoSelector utxoSelector = new DefaultUtxoSelector(utxoSupplier); List<Utxo> adaUtxos = utxoSelector.findAll( senderAddress, utxo -> utxo.containsUnit("lovelace")); Optional<Utxo> firstScriptUtxo = utxoSelector.findFirst( scriptAddress, utxo -> utxo.getReferenceScriptHash() != null);

If your backend supports lookup by address verification hash (addr_vkh), enable it:

utxoSelector.setSearchByAddressVkh(true); utxoSupplier.setSearchByAddressVkh(true); // only if supported by your supplier/backend

Advanced Scenarios

Multi-Address Selection

To select UTXOs across multiple addresses, query each address individually:

Set<Utxo> allSelected = new HashSet<>(); for (String addr : List.of(addr1, addr2, addr3)) { Set<Utxo> selected = strategy.select( AddressIterators.of(addr), List.of(Amount.ada(20)), null, null, allSelected, // exclude already-selected UTXOs 30); allSelected.addAll(selected); }

Datum Requirements

String requiredDatumHash = "..."; PlutusData requiredInlineDatum = PlutusData.of("hello"); Set<Utxo> withHash = strategy.select( AddressIterators.of(contractAddress), List.of(Amount.ada(5)), requiredDatumHash, null, Collections.emptySet(), 10); Set<Utxo> withInline = strategy.select( AddressIterators.of(contractAddress), List.of(Amount.ada(5)), null, requiredInlineDatum, Collections.emptySet(), 10);

Excluding Specific UTXOs

Set<Utxo> exclusions = Set.of(pendingUtxo1, pendingUtxo2); Set<Utxo> selected = strategy.select( AddressIterators.of(senderAddress), List.of(Amount.ada(10)), null, null, exclusions, 20);

Global Configuration

CoinselectionConfig.INSTANCE.setCoinSelectionLimit(50); int current = CoinselectionConfig.INSTANCE.getCoinSelectionLimit();

Custom Strategy

public class CustomUtxoSelectionStrategy implements UtxoSelectionStrategy { private final UtxoSupplier utxoSupplier; private boolean ignoreUtxosWithDatumHash = true; // implement select(...) using your own ordering/filtering @Override public UtxoSelectionStrategy fallback() { return new DefaultUtxoSelectionStrategyImpl(utxoSupplier); } @Override public void setIgnoreUtxosWithDatumHash(boolean ignore) { this.ignoreUtxosWithDatumHash = ignore; } }

QuickTx Integration

Provide a custom strategy per composition:

UtxoSelectionStrategy custom = new LargestFirstUtxoSelectionStrategy(utxoSupplier); Tx tx = new Tx() .payToAddress(receiverAddress, Amount.ada(10)) .from(senderAddress); TxResult result = new QuickTxBuilder(backendService) .compose(tx) .withUtxoSelectionStrategy(custom) .withSigner(SignerProviders.signerFrom(sender)) .complete();
Last updated on