Skip to main content

How to Update Your Solana Client to Handle Versioned Transactions

Updated on
Sep 28, 2026

4 min read

Transaction v1 Is Live

This guide covers the 2022 migration from legacy to version 0. Solana has since added a third transaction version, v1, which activated on mainnet on September 15, 2026. Setting maxSupportedTransactionVersion to 0 now fails on any response that contains a v1 transaction. For the full v1 format changes, see How to Read and Send Solana v1 Transactions.

Overview​

On October 10, 2022 (Epoch 358), Solana added support for new transaction version types through a concept known as "Versioned Transactions". After this change, the Solana runtime supports three transaction versions: "legacy" (older transactions), "0" (transactions that include Address Lookup Tables), and "1" (transaction v1, live on mainnet since September 15, 2026, which raises the size limit to 4,096 bytes and drops Address Lookup Tables in favor of up to 64 inline accounts). Though onchain programs do not have to adopt the change, many client-side applications need to be updated to prevent errors due to different transaction types.

In this guide, you will learn about the technical changes as a result of Solana's Versioned Transactions launch and how to update your client-side code to handle those changes.

What You Will Need​

Client-Side Code Changes: Max Supported Transaction Version​

For Solana JSON RPC requests that return a Transaction now include an optional parameter, maxSupportedTransactionVersion. This parameter tells the runtime the highest version of transactions the application should expect. Three values can be passed:

  • legacy: older transaction format with no additional benefit
  • 0: added support for Address Lookup Tables
  • 1: raised the size limit to 4,096 bytes, replaced Address Lookup Tables with up to 64 inline accounts, and moved compute budget settings out of instructions into the message config

If the request returns a versioned transaction higher than what is set in maxSupportedTransactionVersion, the runtime returns an error. That covers a version 0 transaction returned when legacy is selected, and a version 1 transaction returned when 0 is selected. For getBlock, a single v1 transaction fails the entire response.

How to Avoid Errors in Existing Applications​

Several Solana JSON RPC methods are impacted by this change and should include a maxSupportedTransactionVersion parameter:

blockSubscribe fails without an error. When a v1 transaction arrives and the subscription omits the parameter, the stream emits block: null and stops delivering blocks. No error frame arrives, so your logs will not point at the version parameter.

Though the maxSupportedTransactionVersion parameter is optional in these methods, the best practice is to set maxSupportedTransactionVersion to 1 to capture all transaction types and avoid errors. Pass it as a JSON integer (1); the string "1" is rejected.

getBlock()​

getBlock method calls should add { maxSupportedTransactionVersion: 1 } after the desired slot to search:

const web3 = require("@solana/web3.js");
(async () => {
const solana = new web3.Connection("https://example.solana-mainnet.quiknode.pro/0123456/");
console.log(
await solana.getBlock(
94101948,
//ADD THIS 👇
{ maxSupportedTransactionVersion: 1 })
);
})();

The returned class, VersionedBlockResponse, is very similar to BlockResponse, but it has one key difference. Each transaction's message is a VersionedMessage, a union of Message (legacy), MessageV0, and MessageV1. A single block can return all three, so check the version field on each entry before reading a field that exists on only one of them, such as addressTableLookups on MessageV0.

v1 transactions deserialize to MessageV1, added in @solana/web3.js 1.99.0. A v1 message has no addressTableLookups key, since every account travels inline (up to 64 of them). It carries a transactionConfig object instead, holding priorityFee, computeUnitLimit, loadedAccountsDataSizeLimit, and heapSize. Code that reads compute budget settings out of the instruction list finds nothing on a v1 transaction.

getTransaction()​

getTransaction method calls should add { maxSupportedTransactionVersion: 1 } after the desired transaction ID to search:

const web3 = require("@solana/web3.js");
(async () => {
const solana = new web3.Connection("https://example.solana-mainnet.quiknode.pro/0123456/");
console.log(
await solana.getTransaction(
"D13jTJYXoQBcRY9AfT5xRtsew7ENgCkNs6mwwwAcUCp4ZZCEM7YwZ7en4tVsoDa7Gu75Jjj2FgLXNUz8Zmgedff",
//ADD THIS 👇
{ maxSupportedTransactionVersion: 1 }
)
);
})();

JSON Parsed Results​

For v0 transactions, the Solana Foundation recommends using JSON Parsed encoding because it includes all transaction account keys (including those from lookup tables) in the message "accountKeys" list. This makes it straightforward to resolve balance changes detailed in preBalances / postBalances and preTokenBalances / postTokenBalances. If the "json" encoding is used instead, entries in preBalances / postBalances and preTokenBalances / postTokenBalances may refer to account keys that are NOT in the "accountKeys" list and need to be resolved using "loadedAddresses" entries in the transaction metadata. (Source: Solana Foundation).

This applies to v0. A v1 transaction carries every account inline and returns an empty meta.loadedAddresses, so json encoding has nothing left to resolve.

For your javascript applications, this simply means changing

  • getTransaction() to getParsedTransaction() and
  • getBlock() to getParsedBlock()

For cURL/CURL requests set encoding to jsonParsed:

{"encoding": "Parsed"}

Recap​

If you're running existing client-side code, and you use getBlock or getTransaction, adding the parameter is the whole change. Streaming consumers need two more fixes. blockSubscribe stops delivering blocks on v1 without raising an error, and Yellowstone Geyser plugin builds older than 15.1.1 downgrade v1 transactions to v0 and drop the config object, so pin 15.1.1 or newer on any Geyser or gRPC consumer.

Versioned Transactions are here to stay, and as new versions are implemented, you will need to keep up with network updates to ensure your dApp can support the latest versions. To stay up to date on the latest Solana news and information, subscribe to our newsletter or follow us on Twitter.

If you have any questions or want to discuss your project, drop us a line on Discord.