Solana Transactions

A general Solana transaction is used mainly for invoking non-transfer transactions.

Fordefi supports creating arbitrary Solana transactions, including both legacy and versioned transactions.

Transaction input format

The Create Transaction API supports two formats for specifying a Solana transaction. You can choose which format to use by setting the details->type field in your request.

  • solana_serialized_transaction_messageis the serialized input format, where you specify the transaction you want to create by passing a serialized Transaction Message object, encoded in base64, as the details->data field of the request. A Solana Message object is essentially an unsigned transaction. (See the Solana documentation for more details about this object.) This is the preferred format since all standard Solana SDKs support converting an unsigned transaction into a Message.

  • solana_raw_transactionis an "unpacked" format. When using this format, you need to pass the individual fields comprising a Solana transaction: the list of accounts, address lookup tables, and instructions. This low-level format is rarely the right choice.

    🚧

    Solana Messages

    There is an unfortunate ambiguity of the term "Message" in Solana. Users typically refer to Solana messages as the equivalent of "Personal Messages" on EVM chain—an unstructured text blob that a user can sign with their wallet to prove possession of their private key. Fordefi supports signing such messages with both the Browser Extension and the API (see below). In contrast, a Solana (transaction) Message is essentially an unsigned Solana transaction.

Below we provide examples of how to generate the serialized Solana Transaction Message using common Solana SDKs in TypeScript and Python.

Recent blockhash

Every Solana transaction must contain a recent blockhash—a hash of a block from the last 150 slots, which corresponds to roughly 1–1.5 minutes. (The exception is transactions that use a durable nonce, which are outside of the scope of this guide.)

When using the Fordefi API, the Fordefi server will set the recent blockhash right before the transaction is signed. This is optimal, since it makes sure that the recent blockhash is as fresh as possible before signing. (If the recent block were set by the request, a lengthy transaction-approval process might make it stale by the time the transaction is signed.) Nevertheless, when using some Solana SDKs, constructing a serialized transaction message requires specifying some recent blockhash. In this case, you should set it to any value, and the Fordefi server will override it with a fresh value right before signing the transaction. The exception to this is when the transaction consists of partial signatures - that topic is coming up next.

Transactions with multiple signers

Transactions of some Solana applications require multiple signatures. In such cases, the Fordefi vault is only one of the signers, and the transaction needs to be signed by additional signers.

When using Fordefi to sign transactions with multiple signers, you have three options:

  • Pre-sign the transaction with the additional (non-Fordefi) signers, and pass those partial signatures as part of your request, in the details->signatures field. Fordefi will then provide the remaining signature and send the fully-signed transaction to the blockchain. With this option, the partial signatures in the request already bind the transaction to a particular recent blockhash and set into motion the "expiration clock" of the transaction. Any delay in signing the transaction (for example, if the policy requires a manual approval of the transaction) will likely invalidate the recent blockhash.
  • Partially sign the transaction using the Fordefi API and later add the other signatures. With this approach, you will first use the Fordefi API to partially sign the transaction with the key of your Fordefi vault. Then, retrieve the partially signed transaction from the Fordefi API, add the signatures of the remaining (non-Fordefi) signers, and manually broadcast the transaction to the blockchain. (To do that, set the transaction's "push mode" to "manual" in your request.) As in the previous approach, this approach also has the downside that the recent blockhash is fixed at the time of the first signature (Fordefi's in this case).
  • Don't presign the transaction. Instead, provide the additional signing keys as part of the request, specifically in the details->ephemeral_keysfield . Fordefi will then fix the recent blockhash right and sign the transaction on behalf of all the required signers: the Fordefi vault and the additional signers, whose keys are provided with the request. Sending private keys as part of the request might sound like a huge security red flag, but in many cases, multiple signers are essentially one-time use keys corresponding to ephemeral accounts, created as part of the transaction. In such cases, sending their private keys is not a problem. The advantage of this approach is that the recent blockhash can be set right before signing - so avoiding the risk of the transaction becoming stale.

Fees

Solana has a priority fee mechanism, and correctly setting the fee is crucial to increase the chances of the transaction being included in the blockchain.

When creating Solana transactions with the API you have two options:

  • If you want to set the priority fee yourself, you can use the standard ComputeBudget program as part of your transaction. See the Solana documentation for more information. When your transaction contains instructions that execute the ComputeBudget program, Fordefi will not change the priority fee that these instructions specify.
  • If you want Fordefi to automatically set the priority fee for your transaction, do not include any ComputeBudget instructions in your transaction. Fordefi will then automatically set the priority fee of your transaction based on the current fees of the network. Currently, we don't yet support specifying the "level" of fees (low/medium/high) that Fordefi will use, but this will be added in the near future.

Batch transactions

Certain Solana applications generate a batch (also know as "bundle") of transactions that need to be jointly executed. Historically, there was a limit on the number of accounts in a single transaction, which required splitting large transactions into a batch of smaller transactions. With the introduction of Versioned Transactions and Address Lookup Tables (ALTs), the restriction on the number of accounts within a single transaction no longer applies. Therefore, it is recommended to use a single Versioned Transaction instead of a batch of legacy transactions whenever possible.

To create a batch of transactions using the Fordefi API, use the Create Batch Transaction endpoint, and pass the entire batch of transactions as input.

Batch transactions undergo policy evaluation as a whole: the policy is applied to a “virtual transaction” whose list of recipients is the union of the recipients of the individual transactions in the batch, and whose balance changes are the aggregate of balance changes of the individual transactions.

Batch transactions are always signed jointly and sent to the blockchain according to their order in the batch.

Examples of constructing the request

📘

Note

This page focuses on the Solana-specific details of generating the Create Transaction request. Make sure to follow all the general steps of using the Fordefi Create Transaction API. Specifically, recall that API Users must strongly authenticate transaction requests by signing them. Learn more.

TypeScript with solana/web3.jsv1.x

When using solana/web3.jsversion 1.x, first construct a Message object in one of the following ways:

Once you have a Message object, call serialize to obtain the raw bytes, encode them as base64, and use the result as the details->data field in your Fordefi API request.

TypeScript with solana/web3.jsv2

When using solana/web3.jsversion 2, given a TransactionMessage, call compileTransaction to obtain a Transaction object. Its messageBytes field then contains the serialized transaction message. Encode it in base64 and use it as the details->data field in your Fordefi API request.

Fordefi can handle any Solana transaction. While raw Solana transactions can be used to create transfers, it is recommended to use their request formats.

Python with solders

When using the solders Python library, create a Messageobject, use to_bytes_versioned to serialize it, and encode the result in base64.