Message

class Message

A Solana transaction message.

Some constructors accept an optional payer, the account responsible for paying the cost of executing a transaction. In most cases, callers should specify the payer explicitly in these constructors. In some cases though, the caller is not required to specify the payer, but is still allowed to: in the Message object, the first account is always the fee-payer, so if the caller has knowledge that the first account of the constructed transaction’s Message is both a signer and the expected fee-payer, then redundantly specifying the fee-payer is not strictly required.

Parameters:
  • instructions (Sequence[Instruction]) – The instructions to include in the message.

  • payer (Optional[Pubkey]) – The fee payer. Defaults to None.

Example

>>> from solders.message import Message
>>> from solders.keypair import Keypair
>>> from solders.instruction import Instruction
>>> from solders.hash import Hash
>>> from solders.transaction import Transaction
>>> from solders.pubkey import Pubkey
>>> program_id = Pubkey.default()
>>> arbitrary_instruction_data = bytes([1])
>>> accounts = []
>>> instruction = Instruction(program_id, arbitrary_instruction_data, accounts)
>>> payer = Keypair()
>>> message = Message([instruction], payer.pubkey())
>>> blockhash = Hash.default()  # replace with a real blockhash
>>> tx = Transaction([payer], message, blockhash)
account_keys

All the account keys used by this transaction.

Type:

list[Pubkey]

compile_instruction(ix)

Convert an Instruction into a CompiledInstruction using self.account_keys.

Returns:

The compiled instruction.

Return type:

CompiledInstruction

static default()

Create a new default Message.

Returns:

default Message.

Return type:

Message

static from_bytes(data)

Deserialize a serialized Message object.

Parameters:

data (bytes) – The serialized Message.

Returns:

The deserialized Message.

Return type:

Message

Example

>>> from solders.pubkey import Pubkey
>>> from solders.instruction import AccountMeta, Instruction
>>> from solders.message import Message
>>> from_pubkey = Pubkey.new_unique()
>>> to_pubkey = Pubkey.new_unique()
>>> program_id = Pubkey.new_unique()
>>> instruction_data = bytes([1])
>>> accounts = [AccountMeta(from_pubkey, is_signer=True, is_writable=True), AccountMeta(to_pubkey, is_signer=True, is_writable=True)]
>>> instruction = Instruction(program_id, instruction_data, accounts)
>>> message = Message([instruction])
>>> serialized = bytes(message)
>>> assert Message.from_bytes(serialized) == message
static from_json(raw)

Build from a JSON string.

has_duplicates()

Check if account_keys has any duplicate keys.

Returns:

True if there are duplicates.

Return type:

bool

hash()

Compute the blake3 hash of this transaction’s message.

Returns:

The blake3 hash.

Return type:

Hash

static hash_raw_message(message_bytes)

Compute the blake3 hash of a raw transaction message.

Returns:

The blake3 hash.

Return type:

Hash

header

The message header, identifying signed and read-only account_keys.

Type:

MessageHeader

instructions

Programs that will be executed in sequence and committed in one atomic transaction if all succeed.

Type:

list[CompiledInstruction]

is_key_called_as_program(key_index)

Check if the program_id_index of any of the message’s instructions matches key_index.

Parameters:

key_index (int) – The index to check.

Returns:

The result of the check.

Return type:

bool

is_key_passed_to_program(key_index)

Check if key_index is contained in the accounts of any of the message’s instructions.

Parameters:

key_index (int) – The index to check.

Returns:

True if the key is passed to the program.

Return type:

bool

is_non_loader_key(key_index)

Check if the key is passed to the program OR if the key is not called as program.

Parameters:

key_index (int) – The index to check.

Returns:

The result of the check.

Return type:

bool

is_signer(i)

See https://docs.rs/solana-sdk/latest/solana_sdk/message/legacy/struct.Message.html#method.is_signer

is_upgradeable_loader_present()

See https://docs.rs/solana-sdk/latest/solana_sdk/message/legacy/struct.Message.html#method.is_upgradeable_loader_present

is_writable(i)

See https://docs.rs/solana-sdk/latest/solana_sdk/message/legacy/struct.Message.html#method.is_writable

maybe_executable(i)

See https://docs.rs/solana-sdk/latest/solana_sdk/message/legacy/struct.Message.html#method.maybe_executable

static new_with_blockhash(instructions, payer, blockhash)

Create a new message while setting the blockhash.

Parameters:
  • instructions (Sequence[Instruction]) – The instructions to include in the message.

  • payer (Optional[Pubkey]) – The fee payer. Defaults to None.

  • blockhash (Hash) – a recent blockhash.

Returns:

The message object.

Return type:

Message

Example

>>> from typing import List
>>> from solders.message import Message
>>> from solders.keypair import Keypair
>>> from solders.pubkey import Pubkey
>>> from solders.instruction import Instruction, AccountMeta
>>> from solders.hash import Hash
>>> from solders.transaction import Transaction
>>> program_id = Pubkey.default()
>>> blockhash = Hash.default()  # replace with a real blockhash
>>> arbitrary_instruction_data = bytes([1])
>>> accounts: List[AccountMeta] = []
>>> instruction = Instruction(program_id, arbitrary_instruction_data, accounts)
>>> payer = Keypair()
>>> message = Message.new_with_blockhash([instruction], payer.pubkey(), blockhash)
>>> tx = Transaction.new_unsigned(message)
>>> tx.sign([payer], tx.message.recent_blockhash)
static new_with_compiled_instructions(num_required_signatures, num_readonly_signed_accounts, num_readonly_unsigned_accounts, account_keys, recent_blockhash, instructions)

Create a new message by specifying all the fields required for the message, including the MessageHeader fields.

Parameters:
  • num_required_signatures (int) – The number of signatures required for this message to be considered valid. The signers of those signatures must match the first num_required_signatures of Message.account_keys.

  • num_readonly_signed_accounts (int) – The last num_readonly_signed_accounts of the signed keys are read-only accounts.

  • num_readonly_unsigned_accounts (int) – The last num_readonly_unsigned_accounts of the unsigned keys are read-only accounts.

  • account_keys (list[Pubkey]) – All the account keys used by this transaction.

  • recent_blockhash (Hash) – The id of a recent ledger entry.

  • instructions (list[CompiledInstruction]) – Programs that will be executed in sequence and committed in one atomic transaction if all succeed.

Returns:

The message object.

Return type:

Message

static new_with_nonce(instructions, payer, nonce_account_pubkey, nonce_authority_pubkey)

Create a new message for a nonced transaction.

Parameters:
  • instructions (Sequence[Instruction]) – The instructions to include in the message.

  • payer (Optional[Pubkey]) – The fee payer. Defaults to None.

  • nonce_account_pubkey (Pubkey) – The nonce account pubkey.

  • nonce_authority_pubkey (Pubkey) – The nonce account authority (for advance and close).

In this type of transaction, the blockhash is replaced with a durable transaction nonce, allowing for extended time to pass between the transaction’s signing and submission to the blockchain.

Example

>>> from typing import List
>>> from solders.message import Message
>>> from solders.keypair import Keypair
>>> from solders.pubkey import Pubkey
>>> from solders.instruction import Instruction, AccountMeta
>>> from solders.hash import Hash
>>> from solders.transaction import Transaction
>>> program_id = Pubkey.default()
>>> blockhash = Hash.default()  # replace with a real blockhash
>>> arbitrary_instruction_data = bytes([1])
>>> accounts: List[AccountMeta] = []
>>> instruction = Instruction(program_id, arbitrary_instruction_data, accounts)
>>> payer = Keypair()
>>> nonce_account = Pubkey.default()  # replace with a real nonce account
>>> message = Message.new_with_nonce([instruction], payer.pubkey(), nonce_account, payer.pubkey())
>>> # This transaction will need to be signed later, using the blockhash stored in the nonce account.
>>> tx = Transaction.new_unsigned(message)
program_id(instruction_index)

Return the program ID of an instruction at a particular index in the message.

Parameters:

instruction_index (int) – The position of the instruction in the message’s list of instructions.

Returns:

The program ID.

Return type:

Pubkey

program_ids()

Return the program ID of each instruction in the message.

Returns:

The program IDs.

Return type:

list[Pubkey]

program_index(instruction_index)

Return the program_id_index of the instruction at instruction_index in the message.

Parameters:

instruction_index (int) – The position of the instruction in the message’s list of instructions.

Returns:

The program ID index.

Return type:

int

program_position(index)

See https://docs.rs/solana-sdk/latest/solana_sdk/message/legacy/struct.Message.html#method.program_position

recent_blockhash

The id of a recent ledger entry.

Type:

Hash

signer_keys()

See https://docs.rs/solana-sdk/latest/solana_sdk/message/legacy/struct.Message.html#method.signer_keys

to_json()

Convert to a JSON string.

class MessageHeader

Describes the organization of a Message’s account keys.

Every Instruction specifies which accounts it may reference, or otherwise requires specific permissions of. Those specifications are: whether the account is read-only, or read-write; and whether the account must have signed the transaction containing the instruction.

Whereas an individual Instruction contains a list of all accounts they may access, along with their required permissions, a Message contains a single shared flat list of all accounts required by all instructions in a transaction. When building a Message, this flat list is created and each Instruction is converted to CompiledInstruction. Each CompiledInstruction then references by index the accounts they require in the single shared account list.

The shared account list is ordered by the permissions required of the accounts:

  • accounts that are writable and signers

  • accounts that are read-only and signers

  • accounts that are writable and not signers

  • accounts that are read-only and not signers

Given this ordering, the fields of MessageHeader describe which accounts in a transaction require which permissions.

When multiple transactions access the same read-only accounts, the runtime may process them in parallel, in a single PoH entry. Transactions that access the same read-write accounts are processed sequentially.

Parameters:
  • num_required_signatures (int) – The number of signatures required for this message to be considered valid. The signers of those signatures must match the first num_required_signatures of Message.account_keys.

  • num_readonly_signed_accounts (int) – The last num_readonly_signed_accounts of the signed keys are read-only accounts.

  • num_readonly_unsigned_accounts (int) – The last num_readonly_unsigned_accounts of the unsigned keys are read-only accounts.

LENGTH = 3
static default()

Create a new default MessageHeader.

Returns:

default MessageHeader.

Return type:

MessageHeader

static from_bytes(data)

Deserialize a serialized MessageHeader object.

Parameters:

data (bytes) – The serialized MessageHeader.

Returns:

The deserialized MessageHeader.

Return type:

MessageHeader

static from_json(raw)

Build from a JSON string.

num_readonly_signed_accounts
num_readonly_unsigned_accounts
num_required_signatures
to_json()

Convert to a JSON string.

class MessageV0

A Solana transaction message (v0).

This message format supports succinct account loading with on-chain address lookup tables

Parameters:
  • header (MessageHeader) – The message header, identifying signed and read-only account_keys. Header values only describe static account_keys, they do not describe any additional account keys loaded via address table lookups.

  • account_keys (Sequence[Pubkey]) – List of accounts loaded by this transaction.

  • recent_blockhash (Hash) – Hash of a recent block.

  • instructions (Sequence[Instruction]) – The instructions to include in the message.

  • address_table_lookups (Sequence[MessageAddressTableLookup]) – List of address table lookups used to load additional accounts for this transaction.

Example

>>> from solders.message import MessageV0, MessageHeader, MessageAddressTableLookup
>>> from solders.instruction import CompiledInstruction
>>> from solders.hash import Hash
>>> from solders.pubkey import Pubkey
>>> program_id = Pubkey.default()
>>> arbitrary_instruction_data = bytes([1])
>>> accounts = []
>>> instructions=[CompiledInstruction(program_id_index=4, accounts=bytes([1, 2, 3, 5, 6]), data=bytes([]))]
>>> account_keys = [Pubkey.new_unique()]
>>> header = MessageHeader(1, 0, 0)
>>> lookups = [MessageAddressTableLookup(Pubkey.new_unique(), bytes([1, 2, 3]), bytes([0]))]
>>> blockhash = Hash.default()  # replace with a real blockhash
>>> message = MessageV0(header, account_keys, blockhash, instructions, lookups)
account_keys
address_table_lookups
static default()

Create a new default MessageV0.

Returns:

default MessageV0.

Return type:

MessageV0

static from_bytes(data)

Deserialize from bytes.

Parameters:

data (bytes) – the serialized object.

Returns: the deserialized object.

static from_json(raw)

Build from a JSON string.

hash()

Compute the blake3 hash of this transaction’s message.

Returns:

The blake3 hash.

Return type:

Hash

static hash_raw_message(message_bytes)

Compute the blake3 hash of a raw transaction message.

Returns:

The blake3 hash.

Return type:

Hash

header
instructions
is_key_called_as_program(key_index)

Returns true if the account at the specified index is called as a program by an instruction

is_maybe_writable(key_index)

Returns true if the account at the specified index was requested as writable. Before loading addresses, we can’t demote write locks for dynamically loaded addresses so this should not be used by the runtime.

is_non_loader_key(key_index)

Returns true if the account at the specified index is not invoked as a program or, if invoked, is passed to a program.

is_signer(index)

Returns true if the account at the specified index signed this message.

recent_blockhash
sanitize()

Sanitize message fields and compiled instruction indexes.

to_json()

Convert to a JSON string.

static try_compile(payer, instructions, address_lookup_table_accounts, recent_blockhash)

Create a signable transaction message from a payer public key, recent_blockhash, list of instructions, and a list of address_lookup_table_accounts.

Parameters:
  • payer (Pubkey) – The fee payer.

  • instructions (Sequence[Instruction]) – The instructions to include in the message.

  • address_table_lookups (Sequence[MessageAddressTableLookup]) – List of address table lookups used to load additional accounts for this transaction.

  • recent_blockhash (Hash) – Hash of a recent block.

Example

>>> from solders.pubkey import Pubkey
>>> from solders.instruction import Instruction, AccountMeta
>>> from solders.message import Message
>>> from solders.address_lookup_table_account import AddressLookupTableAccount
>>> from solders.hash import Hash
>>> keys = [Pubkey.new_unique() for i in range(7)]
>>> payer = keys[0]
>>> program_id = keys[6]
>>> ix_accounts = [AccountMeta(keys[1], True, True), AccountMeta(keys[2], True, False), AccountMeta(keys[3], False, True),AccountMeta(keys[4], False, True),AccountMeta(keys[5], False, False),]
>>> instructions = [Instruction(program_id, bytes([]), ix_accounts)]
>>> lookup_acc0 = AddressLookupTableAccount(key=Pubkey.new_unique(), addresses=[keys[4], keys[5], keys[6]])
>>> lookup_acc1 = AddressLookupTableAccount(key=Pubkey.new_unique(), addresses=[])
>>> lookup_accs = [lookup_acc0, lookup_acc1]
>>> recent_blockhash = Hash.new_unique()
>>> msg = MessageV0.try_compile(payer, instructions, lookup_accs, recent_blockhash)
class MessageAddressTableLookup

Address table lookups describe an on-chain address lookup table to use for loading more readonly and writable accounts in a single tx.

Parameters:
  • account_key (Pubkey) – Address lookup table account key.

  • writable_indexes (bytes) – List of u8 indexes used to load writable account addresses, represented as bytes.

  • readonly_indexes (bytes) – List of u8 indexes used to load readonly account addresses, represented as bytes.

account_key

Address lookup table account key.

Type:

Pubkey

static from_bytes(data)

Deserialize from bytes.

Parameters:

data (bytes) – the serialized object.

Returns: the deserialized object.

static from_json(raw)

Build from a JSON string.

readonly_indexes

List of u8 indexes used to load readonly account addresses, represented as bytes.

Type:

bytes

to_json()

Convert to a JSON string.

writable_indexes

List of u8 indexes used to load writable account addresses, represented as bytes.

Type:

bytes

to_bytes_versioned(msg)

Serialize a versioned message, with a leading byte indicating whether or not it’s a legacy message.

If you want to serialize without the leading byte, use bytes(msg).

Parameters:

msg (VersionedMessage) – The message to serialize.

Returns:

the serialized message.

Return type:

bytes

from_bytes_versioned(raw)

Deserialize a versioned message, where the first byte indicates whether or not it’s a legacy message.

Parameters:

raw (bytes) – The serialized message.

Returns:

the deserialized message.

Return type:

VersionedMessage