> ## Documentation Index
> Fetch the complete documentation index at: https://sava.software/llms.txt
> Use this file to discover all available pages before exploring further.

# Transactions

> Build, simulate, sign, and submit Solana transactions.

## Transaction Formats

| Format | Construction                                                | Address lookup tables |
| ------ | ----------------------------------------------------------- | --------------------- |
| Legacy | `Transaction.createTx(feePayer, instruction)`               | No                    |
| v0     | `Transaction.createTx(feePayer, instructions, lookupTable)` | Yes                   |
| v1     | `TxBuilder.createBuilder()`                                 | No                    |

`TxBuilder` builds v1 transactions. Use it with a cluster that has activated v1;
legacy and v0 factories remain available.

## Build, Simulate, Sign, and Submit

```java theme={null}
final var tx = TxBuilder.createBuilder()
    .feePayer(signer.publicKey())
    .addInstruction(instruction)
    .priorityFeeLamports(priorityFeeLamports)
    .createTransaction();

final var simulation = rpcClient.simulateTransaction(Commitment.CONFIRMED, tx, true).join();
if (simulation.error() != null) {
  throw new IllegalStateException("Simulation failed: " + simulation.error());
}

simulation.unitsConsumed().ifPresent(used -> {
  final long limit = used + Math.max(1_000L, used / 10);
  tx.setComputeUnitLimit(Math.clamp(limit, 0, 1_400_000));
});
final int loadedBytes = simulation.loadedAccountsDataSize();
if (loadedBytes > 0) {
  final long limit = loadedBytes + Math.max(1_024L, loadedBytes / 10);
  tx.setAccountDataSizeLimit(Math.clamp(limit, 0, 64 * 1024 * 1024));
}

tx.setRecentBlockHash(simulation.replacementBlockHash().blockhash());
tx.sign(signer);
final var signature = rpcClient.sendTransaction(Commitment.CONFIRMED, tx.base64EncodeToString()).join();
```

Simulation supplies the blockhash. The example adds budget margins; adjust them for
your program. Submission returns a signature; confirmation is a separate step.

## Budgets and Priority Fees

The builder defaults to 1,400,000 compute units and 64 MiB of loaded account data.
Zero omits either field and leaves a zero budget, so do not use zero to request defaults.
V1 transaction setters update fields already present; rebuild to add an omitted field.

V1 priority fees are **total lamports**. To convert a legacy/v0 price in
**micro-lamports per compute unit**:

```java theme={null}
final var builder = TxBuilder.createBuilder()
    .computeUnitLimit(200_000)
    .priorityFeeLamportsFromComputeUnitPrice(5_000);
// Priority fee: 1,000 lamports.
```

The conversion uses the current compute limit once. Changing that limit later does
not change the fee; convert again if needed.

## Read and Rebuild

`TransactionSkeleton.deserializeSkeleton` reads all three formats. For legacy or v1:

```java theme={null}
final var skeleton = TransactionSkeleton.deserializeSkeleton(serializedTransaction);
final var accounts = skeleton.parseAccounts();
final var instructions = skeleton.parseInstructions(accounts);
```

For v0 with lookup-table accounts, use `skeleton.parseAccounts(lookupTables)` with a
`Map<PublicKey, AddressLookupTable>` before parsing instructions.
`skeleton.prototypeTransaction(instructions)` creates a v1 builder from the resolved
instructions and budgets. Set a fresh blockhash and sign the rebuilt transaction.
