AI Starter Pack
Read this whole document before generating cardano-client-lib code. It is optimized for machine ingestion, not for learning. Humans should start at Your first transaction instead.
Target version: the latest preview · Ledger era: Conway · Java 17+ · Group com.bloxbean.cardano
1. Choose the API before writing a line
Section titled “1. Choose the API before writing a line”| Task | Use | Module |
|---|---|---|
| One transaction — send, mint, delegate, register, vote, call a script | QuickTxBuilder + Tx | cardano-client-quicktx |
| A plan expressed as configuration rather than code | TxPlan (YAML/JSON) | cardano-client-quicktx |
| Several dependent transactions, in order, with rollback handling | FlowEngine | cardano-client-txflow |
| Continuous submission with exactly-once and durable restart | TxFlowStream | cardano-client-txflow |
| A proof an Aiken validator can verify on-chain | MpfTrie | cardano-client-merkle-patricia-forestry |
QuickTx is the default. Only move up this table when the task genuinely needs the extra machinery.
Never generate these
Section titled “Never generate these”| Do not use | Why | Use instead |
|---|---|---|
WatchableQuickTxBuilder | Does not exist. Never shipped in any release. If your training data suggests it, that memory is wrong. | FlowEngine (TxFlow) |
com.bloxbean.cardano.client.function.* (TxBuilder, TxOutputBuilder, InputBuilders, BalanceTxBuilders) | The internal implementation layer beneath QuickTx. It works, but mistakes are silent and it is far more verbose. | QuickTx |
ScriptTx, on 0.8.0 previews | Deprecated in the 0.8.0 previews, where every operation is also on Tx. Not deprecated in stable 0.7.x, where it is the right API for scripts. | Tx on previews |
FlowExecutor | Compatibility API. Combines definition and execution concerns; not the canonical durable path. | FlowEngine |
JellyfishMerkleTree for on-chain proofs | Not Aiken-compatible. Off-chain authenticated state only. | MpfTrie |
2. The five mistakes agents actually make
Section titled “2. The five mistakes agents actually make”2.1 Mismatching the network and the backend URL
Section titled “2.1 Mismatching the network and the backend URL”The Network (used for address derivation) and the backend URL (used for queries) are configured
separately. Nothing validates that they agree, so a mismatch produces addresses on one network
and queries against another.
// WRONG — preview addresses, mainnet backend. Compiles, fails at run time.Account account = Account.createFromMnemonic(Networks.preview(), mnemonic);BackendService backend = new BFBackendService(Constants.BLOCKFROST_MAINNET_URL, projectId);
// RIGHT — both preview.Account account = Account.createFromMnemonic(Networks.preview(), mnemonic);BackendService backend = new BFBackendService(Constants.BLOCKFROST_PREVIEW_URL, projectId);Matched pairs — Constants here is
com.bloxbean.cardano.client.backend.blockfrost.common.Constants:
| Network | Networks factory | Blockfrost URL constant |
|---|---|---|
| Mainnet | Networks.mainnet() | BLOCKFROST_MAINNET_URL |
| Preprod | Networks.preprod() | BLOCKFROST_PREPROD_URL |
| Preview | Networks.preview() | BLOCKFROST_PREVIEW_URL |
| Local devnet (Yaci DevKit) | Networks.testnet() | http://localhost:8080/api/v1/ |
All test networks use network id 0, so Networks.testnet(), Networks.preview() and Networks.preprod() give the same addresses. Use the constant that names your network when you know it.
2.2 Treating complete() as confirmation
Section titled “2.2 Treating complete() as confirmation”TxResult result = quickTxBuilder.compose(tx) .withSigner(SignerProviders.signerFrom(account)) .complete(); // submits ONLY — does not waitcomplete() returns as soon as the node accepts the transaction for propagation. The transaction
may still fail to be included, or be rolled back.
| Method | Returns | Waits for a block? |
|---|---|---|
complete() | TxResult | No |
completeAndWait() | TxResult | Yes |
completeAndWaitAsync() | CompletableFuture<TxResult> | Yes, off-thread |
Use completeAndWait() unless you have a specific reason not to, and check the status:
TxResult result = quickTxBuilder.compose(tx) .withSigner(SignerProviders.signerFrom(account)) .completeAndWait();
if (result.getTxStatus() == TxStatus.CONFIRMED) { System.out.println("Confirmed: " + result.getTxHash());} else { System.err.println("Not confirmed: " + result.getTxStatus());}TxStatus values: SUBMITTED, PENDING, CONFIRMED, FAILED, TIMEOUT.
2.3 Reaching for the function module
Section titled “2.3 Reaching for the function module”If you find yourself writing TxBuilder, TxOutputBuilder, InputBuilders.createFromSender(...)
or BalanceTxBuilders.balanceTx(...), stop. QuickTx expresses the same thing in a few lines:
// The whole of a payment, including balancing and fee calculation.Tx tx = new Tx() .payToAddress(receiverAddress, Amount.ada(10)) .from(senderAddress);The function module is documented under
Composable functions for the rare cases QuickTx cannot cover.
Do not generate it by default.
2.4 Assuming pre-Conway APIs
Section titled “2.4 Assuming pre-Conway APIs”This library targets the Conway era. Governance is first-class on Tx:
import com.bloxbean.cardano.client.governance.GovId;
// A bech32 DRep id (CIP-105) becomes a DRep via GovId.toDrep.DRep drep = GovId.toDrep(account.drepId());
Tx tx = new Tx() .registerDRep(account, anchor) // DRep registration .delegateVotingPowerTo(stakeAddress, drep) // vote delegation .createVote(voter, govActionId, Vote.YES) // voting .createProposal(govAction, rewardAccount, anchor) .from(senderAddress);delegateVotingPowerTo takes a DRep, not a bech32 id string — convert with GovId.toDrep(...).
If your training data has no registerDRep / createVote / delegateVotingPowerTo on Tx, it
predates Conway support. See Governance API.
2.5 Ignoring the datum-hash filter in coin selection
Section titled “2.5 Ignoring the datum-hash filter in coin selection”The default UTXO selection strategy skips UTXOs carrying a datum hash. That is usually right
for ordinary payments and wrong when you mean to spend a script output. When collecting from a
script address, pass the UTXOs explicitly with collectFrom(...) rather than relying on
selection.
3. Canonical patterns
Section titled “3. Canonical patterns”3.1 Send ADA
Section titled “3.1 Send ADA”import com.bloxbean.cardano.client.account.Account;import com.bloxbean.cardano.client.api.model.Amount;import com.bloxbean.cardano.client.backend.api.BackendService;import com.bloxbean.cardano.client.backend.blockfrost.common.Constants;import com.bloxbean.cardano.client.backend.blockfrost.service.BFBackendService;import com.bloxbean.cardano.client.common.model.Networks;import com.bloxbean.cardano.client.function.helper.SignerProviders;import com.bloxbean.cardano.client.quicktx.QuickTxBuilder;import com.bloxbean.cardano.client.quicktx.Tx;import com.bloxbean.cardano.client.quicktx.TxResult;import com.bloxbean.cardano.client.quicktx.TxStatus;
Account sender = Account.createFromMnemonic(Networks.preview(), senderMnemonic);BackendService backend = new BFBackendService(Constants.BLOCKFROST_PREVIEW_URL, projectId);
Tx tx = new Tx() .payToAddress(receiverAddress, Amount.ada(10)) .from(sender.baseAddress());
TxResult result = new QuickTxBuilder(backend) .compose(tx) .withSigner(SignerProviders.signerFrom(sender)) .completeAndWait();SignerProviders lives in the function package but is the correct, canonical way to sign a
QuickTx transaction — it is the one part of that package you should generate.
3.2 Mint a native token
Section titled “3.2 Mint a native token”Policy policy = PolicyUtil.createMultiSigScriptAllPolicy("my-policy", 1);Asset asset = new Asset("MyToken", BigInteger.valueOf(1000));
Tx tx = new Tx() .mintAssets(policy.getPolicyScript(), asset, receiverAddress) .from(sender.baseAddress());
TxResult result = new QuickTxBuilder(backend) .compose(tx) .withSigner(SignerProviders.signerFrom(sender)) .withSigner(SignerProviders.signerFrom(policy)) // policy key must sign too .completeAndWait();Minting needs two signers: the funding account and the policy key.
3.3 Call a Plutus script
Section titled “3.3 Call a Plutus script”On the 0.8.0 previews, use Tx rather than ScriptTx. On stable 0.7.x, use ScriptTx with .feePayer(...):
Tx tx = new Tx() .collectFrom(scriptUtxo, redeemer) .attachSpendingValidator(plutusScript) .payToAddress(receiverAddress, Amount.ada(5)) .from(sender.baseAddress());
TxResult result = new QuickTxBuilder(backend) .compose(tx) .withSigner(SignerProviders.signerFrom(sender)) .completeAndWait();One naming trap: native-script minting is mintAssets (plural), Plutus minting is
mintAsset (singular).
3.4 Stake delegation
Section titled “3.4 Stake delegation”Tx tx = new Tx() .registerStakeAddress(sender.stakeAddress()) .delegateTo(sender.stakeAddress(), poolId) .from(sender.baseAddress());
TxResult result = new QuickTxBuilder(backend) .compose(tx) .withSigner(SignerProviders.signerFrom(sender)) .withSigner(SignerProviders.stakeKeySignerFrom(sender)) // stake key signs .completeAndWait();Delegation, deregistration and withdrawal need the stake key signature in addition to the payment key. Registration alone doesn’t. A withdrawal also needs the stake address to have delegated its vote, for example .delegateVotingPowerTo(address, DRep.abstain()).
4. Signing reference
Section titled “4. Signing reference”| Signer | Use for |
|---|---|
SignerProviders.signerFrom(account) | Payment key. Almost every transaction. |
SignerProviders.signerFrom(policy) | Native-script policy key, when minting or burning. |
SignerProviders.stakeKeySignerFrom(account) | Delegation, vote delegation, deregistration, withdrawal. |
SignerProviders.drepKeySignerFrom(account) | Conway DRep operations. |
SignerProviders.committeeHotKeySignerFrom(account) | Conway committee hot-key votes. |
SignerProviders.committeeColdKeySignerFrom(account) | Conway committee cold-key operations. |
Chain .withSigner(...) once per required key.
5. Dependencies
Section titled “5. Dependencies”Use one version for every CCL module.
def cclVersion = '<version>' // the latest preview, see /start-here/installation/#versions
dependencies { implementation "com.bloxbean.cardano:cardano-client-lib:${cclVersion}" implementation "com.bloxbean.cardano:cardano-client-backend-blockfrost:${cclVersion}"
// Only if the task needs them: implementation "com.bloxbean.cardano:cardano-client-txflow:${cclVersion}" implementation "com.bloxbean.cardano:cardano-client-merkle-patricia-forestry:${cclVersion}"}cardano-client-lib is the aggregate that pulls in the common modules. Add a backend module —
without one there is no way to read UTXOs or submit.
The full generated list of modules, artifact ids and entry points is at
/ai/catalog.json.
6. Verified data structures: which one
Section titled “6. Verified data structures: which one”Answer in this order.
- Must an on-chain Aiken validator verify the proof?
Yes →
MpfTrie. No →JellyfishMerkleTreealso works, for off-chain state only. - Which storage backend?
merkle-patricia-forestry-rocksdbfor embedded single-process.merkle-patricia-forestry-rdbmsfor shared multi-process (PostgreSQL, H2, SQLite).
See Verified structures.
7. Testing generated code
Section titled “7. Testing generated code”Do not hand back transaction code you have not run. Yaci DevKit
gives a local devnet with pre-funded accounts and one-second blocks. devkitMnemonic is the default devnet mnemonic:
BackendService backend = new BFBackendService("http://localhost:8080/api/v1/", "dummy-key");Account sender = Account.createFromMnemonic(Networks.testnet(), devkitMnemonic);No API key, no faucet, no testnet wait. If the code produces a confirmed transaction hash there, the same code works against preview with the URL and network swapped.
8. Where to look next
Section titled “8. Where to look next”| Question | Page |
|---|---|
| Full QuickTx surface | QuickTx overview |
| Declarative YAML plans | TxPlan |
| Multi-step workflows | TxFlow |
| Continuous submission | TxStream |
| Conway governance | Governance API |
| Plutus, blueprints, Aiken | Smart contracts |
| Every module and artifact | Modules & artifacts |