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

# 25.11.0

> Transaction v1 support, explicit signing APIs, and migration from 25.10.0.

## What changes

* Build transaction format v1 with `TxBuilder`, including transactions up to 4,096 bytes
  and configuration for priority fees, compute units, loaded account data, and heap size.
* Choose signer matching explicitly with `signByKey` and `signInOrder`.
* Read v1 transactions through `getTransaction` and full `getBlock` responses. The client
  advertises support through version 1; `BlockTx.skeleton()` exposes each block entry's
  format and configuration from its wire data.
* Import JSON keys with fields in any order, skip unrelated fields, and receive
  errors that identify missing required fields.
* Use equal instructions interchangeably in hash-based collections, even when their
  data comes from different arrays or offsets.

Start with the [transaction guide](/guides/transactions) for a complete v1 flow.
V1 submission requires a cluster that has activated the format. Upgrading Sava does
not change cluster support or automatically convert existing transactions to v1.

## Upgrading from 25.10.0

25.11.0 introduces transaction format v1 and removes APIs that were already
deprecated in 25.10.0. These removals are intentional breaking changes.
Applications using them need source changes and recompilation. Legacy and v0
transaction factories remain available; their deprecation is deferred until v1 is
activated on mainnet, with removal to follow later. The deprecated RecentBlockhashes
sysvar accessors also remain.

| Removed API                                                       | Replacement                                                                                        |
| ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `PublicKey.verifySignature` overloads taking a `String` signature | Pass the decoded signature as `byte[]`.                                                            |
| `Hmac.hmacSHA512(byte[], byte[])`                                 | Obtain a `Mac` from `Hmac.hmacSHA512()`, initialize it with the key, and authenticate the message. |
| `Token2022.extensions()` and `Token2022Account.extensions()`      | Use `tokenExtensions()`, which returns a `Set<TokenExtension>`.                                    |
| `ExtensionType` and `TokenExtension.extensionType()`              | Use concrete extension types for dispatch and `ordinal()` for the on-chain type ID.                |
| `RpcEncoding.base58`                                              | Request `RpcEncoding.base64`, or `base64_zstd` where supported.                                    |
| `Transaction.MAX_SERIALIZED_LENGTH`                               | Use the transaction's `exceedsSizeLimit()` method.                                                 |

## JSON key import

`PrivateKeyEncoding.fromJsonPrivateKey` accepts `encoding`, `secret`, and the optional
`pubKey` in any order. Unknown fields are skipped, including nested objects and
arrays; fields inside them cannot supply or override the imported key. A supplied
public key is still checked against the derived key. Missing `encoding` or `secret`
fields now raise `IllegalStateException` naming the missing field.

## Instructions in hash-based collections

For valid data spans, factory-created instructions now hash their data by content,
consistently with `equals`. Equal instructions can be used interchangeably as
`HashMap` keys and `HashSet` entries even when backed by different arrays or offsets.
Hash values change; do not persist them as identifiers. Keep the retained account
list, public keys, and data unchanged while an instruction is stored in a hash-based
collection, or copy mutable inputs before construction.

## Signature verification

A signature is binary data. Decode a textual signature using its actual encoding
before passing it to the existing byte-array overload. For example, for a base58
signature:

```java theme={null}
boolean valid = publicKey.verifySignature(message, Base58.decode(signatureBase58));
```

The removed overload encoded the signature string as UTF-8. That cannot generally
preserve an Ed25519 signature. The overloads accepting a `String` message remain.

## Token-2022 extensions

The map keyed by `ExtensionType` is removed. Iterate `tokenExtensions()` and match
the concrete type, for example:

```java theme={null}
for (var extension : token2022.tokenExtensions()) {
  if (extension instanceof TransferFeeConfig transferFees) {
    // Use transferFees here.
  }
}
```

`ordinal()` is the stable on-chain numeric type ID, not an index into a Java enum.
Known extensions retain their existing IDs and serialized layouts. Unknown type
IDs remain represented by `UnknownTokenExtension`, including their raw bytes, so
consumers should preserve them when reading and writing accounts.

## RPC encodings and transaction limits

Base58 account data in RPC responses remains readable. Removing the request enum
member does not remove the response decoder. `RpcEncoding.parseEncoding` now
returns `null` for `"base58"`, just as it does for other unsupported request names.

The single transaction-size constant could not describe every transaction format.
It carried plain `@Deprecated` in 25.10.0, without `forRemoval = true`, so builds
that checked only removal warnings did not receive advance notice of this removal.
`exceedsSizeLimit()` applies the built-in transaction's limit: 1,232 bytes for
legacy/v0 and 4,096 bytes for v1. Its interface default retains the 1,232-byte
compatibility limit for third-party implementations. A transaction fitting its
format's size limit does not imply that the destination cluster accepts that format.

## Newly deprecated transaction signing APIs

These methods remain available with their existing behavior for this release, but
are now marked `@Deprecated(forRemoval = true)`.

The `SequencedCollection<Signer>` overloads of `sign` and `signAndBase64Encode` sign
positionally. A `List<Signer>` selects these overloads even when the caller expects
the by-key behavior of `sign(Collection<Signer>)`.

Use the explicit names to choose the behavior:

```java theme={null}
tx.signInOrder(signers); // Preserves positional signing; supply message signer order.
tx.signByKey(signers);   // Matches required signer keys, regardless of list order.
```

Both families include blockhash and Base64 conveniences, such as
`signInOrderAndBase64Encode(recentBlockHash, signers)` and
`signByKeyAndBase64Encode(recentBlockHash, signers)`. The static raw-buffer helpers
use `Transaction.signInOrder(...)` and `Transaction.signInOrderAndBase64Encode(...)`.
Transaction-aware positional overloads retain count validation without checking each
signer's key against its signature position; the explicit-offset helper trusts the supplied spans.
By-key signing validates the complete assignment before writing signatures.

The existing single-signer, explicit-index, and `Collection<Signer>` overloads remain
undeprecated. Named instance positional aliases delegate to the corresponding existing overload,
including custom convenience overrides. New instance methods have defaults, so existing
`Transaction` implementations do not need additional method overrides.
