Skip to content

QuickTx API

QuickTx is a declarative transaction builder layered on top of the Composable Functions API. It keeps common flows concise while still letting you plug in custom UTXO selection, evaluators, script suppliers, and verifiers.

Use QuickTx when you want the happy path to be short and readable, but still need escape hatches for unusual inputs (custom UTXO selection), script fee evaluation, or reference scripts. Behind the scenes, QuickTx constructs a composable-function chain for you, applies balancing/fees, signs, and submits—while exposing hooks to override key steps.

  • Declarative, readable transaction description
  • Payments, NativeScript mint/burn, Plutus script spending/minting, staking, governance
  • Compose multiple Tx/ScriptTx into one transaction
  • Per-tx overrides for UTXO selection, reference scripts, and verifiers

Preview — Unified Tx API: in the 0.8.0 previews, all ScriptTx operations are also available on Tx, and ScriptTx is deprecated there. It isn’t deprecated in the stable 0.7.x releases. See the Unified Tx API documentation for details and migration guide.

Preview — YAML Transaction Plans: Define transactions in YAML with variable substitution and execute them through QuickTxBuilder. See the TxPlan documentation.

  • Group ID: com.bloxbean.cardano
  • Artifact ID: cardano-client-quicktx
  • Depends on: core, function, backend, hd-wallet
// Common: derive all dependencies from the backend
BackendService backendService = ...;
QuickTxBuilder quickTxBuilder = new QuickTxBuilder(backendService);
// Advanced: supply dependencies manually
UtxoSupplier utxoSupplier = new DefaultUtxoSupplier(backendService.getUtxoService());
ProtocolParamsSupplier paramsSupplier = new DefaultProtocolParamsSupplier(backendService.getEpochService());
TransactionProcessor txProcessor = new DefaultTransactionProcessor(backendService.getTransactionService());
QuickTxBuilder quickTxBuilder = new QuickTxBuilder(utxoSupplier, paramsSupplier, txProcessor);
Account sender = ...;
String receiver1 = "...";
String receiver2 = "...";
Tx tx = new Tx()
.payToAddress(receiver1, Amount.ada(1.5))
.payToAddress(receiver2, Amount.ada(2.0))
.from(sender.baseAddress());
TxResult result = quickTxBuilder.compose(tx)
.withSigner(SignerProviders.signerFrom(sender))
.completeAndWait(msg -> log.info(msg));
NativeScript policy = ...; // NativeScript policy
Asset asset = Asset.builder()
.name("MyToken")
.value(BigInteger.valueOf(1_000))
.build();
Tx tx = new Tx()
.mintAssets(policy, asset, receiverAddress)
.from(sender.baseAddress());
TxResult result = quickTxBuilder.compose(tx)
.withSigner(SignerProviders.signerFrom(sender))
.complete();
PlutusScript mintingScript = ...;
Asset asset = Asset.builder()
.name("MyScriptToken")
.value(BigInteger.valueOf(100))
.build();
ScriptTx tx = new ScriptTx()
.mintAsset(mintingScript, asset, PlutusData.unit(), receiverAddress);
TxResult result = quickTxBuilder.compose(tx)
.feePayer(sender.baseAddress())
.withSigner(SignerProviders.signerFrom(sender))
.complete();
String poolId = "...";
Tx delegateTx = new Tx()
.delegateTo(sender.baseAddress(), poolId) // a base or reward address
.from(sender.baseAddress());
Tx withdrawTx = new Tx()
.withdraw(sender.stakeAddress(), BigInteger.valueOf(1_000_000)) // a reward address; the whole balance, in lovelace
.from(sender.baseAddress());
Metadata metadata = MessageMetadata.create()
.add("Transaction message");
Tx tx = new Tx()
.payToAddress(receiver1, Amount.ada(1.0))
.payToAddress(receiver2, Amount.ada(2.0))
.attachMetadata(metadata)
.from(sender.baseAddress());
TxResult result = quickTxBuilder.compose(tx)
.withSigner(SignerProviders.signerFrom(sender))
.completeAndWait();
  • Payments: payToAddress(...), payToContract(...) (datum hash/inline datum, reference scripts)
  • Native mint/burn: mintAssets(NativeScript policy, List<Asset> assets [, String receiver])
  • Staking: delegateTo(String stakeAddress, String poolId), withdraw(String rewardAddress, BigInteger amount [, String receiver])
  • Metadata: attachMetadata(Metadata metadata)
  • Sender: from(String address | Wallet wallet); change via withChangeAddress(String)
  • Governance and other intents: stake registration/deregistration, pool registration/update/retire, governance actions (DRep/committee registration, votes), treasury donation, and more (see Tx methods)
  • Script inputs: collectFrom(...) variants with redeemers/datums
  • Plutus minting: mintAsset(PlutusScript script, List<Asset> assets, PlutusData redeemer [, String receiver, PlutusData outputDatum])
  • Attach validators: attachSpendingValidator / attachMintValidator / ...
  • Change with inline datum: withChangeAddress(String, PlutusData)

compose(AbstractTx... txs) returns a TxContext:

TxContext ctx = quickTxBuilder.compose(tx1, tx2)
.withSigner(SignerProviders.signerFrom(sender))
.withUtxoSelectionStrategy(new LargestFirstUtxoSelectionStrategy(utxoSupplier))
.validFrom(slotFrom)
.validTo(slotTo);
Transaction unsigned = ctx.build();
Transaction signed = ctx.buildAndSign();
TxResult submitted = ctx.complete(); // submit, and don't wait
TxResult waited = ctx.completeAndWait(); // submit, and wait up to 60 seconds

Call one of complete or completeAndWait once: each of them builds and submits a transaction.

isSuccessful() on the result only means that the submission worked. After completeAndWait, check getTxStatus(), which is CONFIRMED, PENDING, TIMEOUT or FAILED. On PENDING or TIMEOUT, the transaction may still land.

Execution flow:

  • Build one or more Tx/ScriptTx describing intent.
  • compose(...) wraps them in a TxContext.
  • Add signers, optional strategy/evaluator/era/reference scripts.
  • Call build/buildAndSign/complete/completeAndWait.
  • Fees and change are calculated during build/complete
  • Script cost evaluation is performed automatically; failures can be tolerated with ignoreScriptCostEvaluationError(true)
  • Collateral is auto-selected for script transactions unless you set explicit inputs via withCollateralInputs(...)
  • UTXO selection: withUtxoSelectionStrategy(...)
  • Reference scripts for fee accuracy: withReferenceScripts(...)
  • Serialization era: withSerializationEra(Era era) (Conway by default)
  • Verifiers and inspection: withVerifier(...), withTxInspector(...)
  • Fee payer and collateral payer: feePayer(...), collateralPayer(...) (or wallet variants)
  • Required signers: withRequiredSigners(Address... | byte[]...)
  • Validity window: validFrom(slot), validTo(slot)
  • Merge outputs: mergeOutputs(boolean) (deduplicate outputs to same address)
  • Script cost tolerance: ignoreScriptCostEvaluationError(boolean)
  • Duplicate witness cleanup: removeDuplicateScriptWitnesses(boolean) for multi-asset/script-heavy txs
  • UTXO search mode: withSearchUtxoByAddressVkh(boolean) when backend supports addr_vkh lookups
  • Custom transforms: preBalanceTx(...), postBalanceTx(...) to inject custom TxBuilder steps
  • Collateral override: withCollateralInputs(TransactionInput...)
  • Reference-based resolution (Signers Registry): Tx.fromRef(...), feePayerRef(...), collateralPayerRef(...), withSignerRef(...) when using a SignerRegistry

When to choose QuickTx vs. Composable Functions

Section titled “When to choose QuickTx vs. Composable Functions”
  • Choose QuickTx if you want minimal code for common flows and a single entrypoint for build + sign + submit + wait.
  • Choose Composable Functions only if you need to handcraft every step, reuse builders outside QuickTx, or integrate with a highly customized pipeline. It is the internal implementation layer beneath QuickTx, and mistakes there fail in ways that are harder to diagnose.

QuickTx builds and submits one transaction. When that stops being the shape of your problem, three preview APIs sit above it — all built on the same transaction machinery:

You needUseWhy not QuickTx
The same transaction shape with values supplied at run time, reviewable as configTxPlanThe decision belongs in a file operators can read, not in compiled code
A second transaction that spends an output the first one createdTxFlowThe new UTXO is not visible to a backend query yet — selection fails with “not enough funds”
A continuous feed of transactions that must each land exactly once, across restartsTxStreamIdempotency and durable recovery are real machinery, not a retry loop

Most applications never need to leave this page. Move up only when you hit the specific wall in the right-hand column.