CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-solders

Python bindings for Solana Rust tools providing high-performance blockchain development primitives, RPC functionality, and testing infrastructure.

Pending
Overview
Eval results
Files

account-management.mddocs/

Account Management

Account data structures, encoding formats, and metadata handling for both raw and parsed account information. This includes account state management, commitment levels, data encoding options, and parsing utilities for program-specific account data.

Capabilities

Account Data Structures

Core account representations containing balance, data, ownership, and metadata information.

class Account:
    """
    Solana account containing balance, data, owner, and metadata.
    """
    def __init__(self, lamports: int, data: bytes, owner: Pubkey, executable: bool, rent_epoch: int):
        """
        Create account with balance, data, and metadata.
        
        Parameters:
        - lamports: int, account balance in lamports (1 SOL = 1e9 lamports)
        - data: bytes, account data (program-specific)
        - owner: Pubkey, program that owns this account
        - executable: bool, whether account contains executable program code
        - rent_epoch: int, epoch when rent was last collected
        """

    @classmethod
    def default() -> 'Account':
        """
        Create default empty account.
        
        Returns:
        Account with zero balance, empty data, system program owner
        """

    @property
    def lamports(self) -> int:
        """Account balance in lamports."""

    @property
    def data(self) -> bytes:
        """Account data bytes."""

    @property
    def owner(self) -> Pubkey:
        """Program that owns this account."""

    @property
    def executable(self) -> bool:
        """Whether account contains executable code."""

    @property
    def rent_epoch(self) -> int:
        """Epoch when rent was last collected."""

    def serialize(self) -> bytes:
        """
        Serialize account to bytes.
        
        Returns:
        bytes, serialized account data
        """

    @classmethod
    def deserialize(cls, data: bytes) -> 'Account':
        """
        Deserialize account from bytes.
        
        Parameters:
        - data: bytes, serialized account data
        
        Returns:
        Account object
        """
class AccountJSON:
    """
    JSON-serializable account representation for RPC responses.
    """
    def __init__(
        self,
        lamports: int,
        data: Union[str, List[str]],
        owner: str,
        executable: bool,
        rent_epoch: int
    ):
        """
        Create JSON account representation.
        
        Parameters:
        - lamports: int, account balance
        - data: Union[str, List[str]], encoded account data
        - owner: str, base58 owner pubkey
        - executable: bool, executable flag
        - rent_epoch: int, rent epoch
        """

    def to_json(self) -> dict:
        """
        Convert to JSON dictionary.
        
        Returns:
        dict, JSON-compatible account data
        """

    @classmethod
    def from_json(cls, data: dict) -> 'AccountJSON':
        """
        Create from JSON dictionary.
        
        Parameters:
        - data: dict, JSON account data
        
        Returns:
        AccountJSON object
        """

Account Encoding and Parsing

Data encoding formats and parsing utilities for account data representation.

class UiAccountEncoding:
    """
    Account data encoding format enumeration.
    """
    Base64: 'UiAccountEncoding'          # Base64 encoded data
    JsonParsed: 'UiAccountEncoding'      # Parsed JSON format (program-specific)
    Base58: 'UiAccountEncoding'          # Base58 encoded data
    Base64Zstd: 'UiAccountEncoding'      # Base64 + Zstandard compression

    def __str__(self) -> str:
        """String representation of encoding type."""
class ParsedAccount:
    """
    Account with parsed/decoded program-specific data.
    """
    def __init__(self, account: Account, parsed_data: Optional[dict]):
        """
        Create parsed account with structured data.
        
        Parameters:
        - account: Account, base account information
        - parsed_data: Optional[dict], program-specific parsed data
        """

    @property
    def account(self) -> Account:
        """Base account information."""

    @property
    def parsed_data(self) -> Optional[dict]:
        """Program-specific parsed data."""

    def is_token_account(self) -> bool:
        """
        Check if account contains SPL token data.
        
        Returns:
        bool, True if account is token account
        """

    def is_mint_account(self) -> bool:
        """
        Check if account contains SPL mint data.
        
        Returns:
        bool, True if account is mint account
        """
class UiDataSliceConfig:
    """
    Configuration for slicing account data in RPC requests.
    """
    def __init__(self, offset: int, length: int):
        """
        Create data slice configuration.
        
        Parameters:
        - offset: int, byte offset to start slice
        - length: int, number of bytes to return
        """

    @property
    def offset(self) -> int:
        """Slice offset in bytes."""

    @property
    def length(self) -> int:
        """Slice length in bytes."""

Token Amount Handling

Specialized handling for token amounts with proper decimal representation.

class UiTokenAmount:
    """
    Token amount with decimal precision handling.
    """
    def __init__(self, ui_amount: Optional[float], decimals: int, amount: str, ui_amount_string: str):
        """
        Create token amount with decimal handling.
        
        Parameters:
        - ui_amount: Optional[float], human-readable amount (may be None for large numbers)
        - decimals: int, number of decimal places for token
        - amount: str, raw amount as string (no decimal adjustment)
        - ui_amount_string: str, human-readable amount as string
        """

    @property
    def ui_amount(self) -> Optional[float]:
        """Human-readable amount (float, may be None for large values)."""

    @property
    def decimals(self) -> int:
        """Number of decimal places for this token."""

    @property
    def amount(self) -> str:
        """Raw token amount as string."""

    @property
    def ui_amount_string(self) -> str:
        """Human-readable amount as string."""

    def to_float(self) -> float:
        """
        Convert to float value.
        
        Returns:
        float, token amount as floating point
        
        Raises:
        - ValueError: if amount cannot be represented as float
        """

    def to_decimal(self) -> 'Decimal':
        """
        Convert to decimal for precise arithmetic.
        
        Returns:
        Decimal, exact token amount
        """

Commitment and Configuration

Transaction commitment levels and account query configuration.

class CommitmentLevel:
    """
    Transaction confirmation levels.
    """
    Processed: 'CommitmentLevel'    # Transaction processed but not confirmed
    Confirmed: 'CommitmentLevel'    # Transaction confirmed by cluster
    Finalized: 'CommitmentLevel'    # Transaction finalized (cannot be rolled back)

    def __str__(self) -> str:
        """String representation of commitment level."""
class CommitmentConfig:
    """
    Configuration for RPC request commitment level.
    """
    def __init__(self, commitment: CommitmentLevel):
        """
        Create commitment configuration.
        
        Parameters:
        - commitment: CommitmentLevel, desired confirmation level
        """

    @classmethod
    def processed() -> 'CommitmentConfig':
        """
        Create processed commitment config.
        
        Returns:
        CommitmentConfig for processed transactions
        """

    @classmethod
    def confirmed() -> 'CommitmentConfig':
        """
        Create confirmed commitment config.
        
        Returns:
        CommitmentConfig for confirmed transactions
        """

    @classmethod
    def finalized() -> 'CommitmentConfig':
        """
        Create finalized commitment config.
        
        Returns:
        CommitmentConfig for finalized transactions
        """

    @property
    def commitment(self) -> CommitmentLevel:
        """Commitment level."""

Usage Examples

Basic Account Operations

from solders.account import Account
from solders.pubkey import Pubkey

# Create account
owner = Pubkey.from_string("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")
account_data = b"token_account_data_here"

account = Account(
    lamports=2039280,  # Rent-exempt minimum
    data=account_data,
    owner=owner,
    executable=False,
    rent_epoch=361
)

print(f"Account balance: {account.lamports / 1e9:.9f} SOL")
print(f"Data length: {len(account.data)} bytes")
print(f"Owner: {account.owner}")
print(f"Executable: {account.executable}")

Working with Token Amounts

from solders.account_decoder import UiTokenAmount
from decimal import Decimal

# Token amount with 6 decimals (USDC-style)
token_amount = UiTokenAmount(
    ui_amount=1000.50,
    decimals=6,
    amount="1000500000",  # Raw amount: 1000.5 * 10^6
    ui_amount_string="1000.5"
)

print(f"UI amount: {token_amount.ui_amount}")
print(f"Raw amount: {token_amount.amount}")
print(f"Decimals: {token_amount.decimals}")

# Precise decimal arithmetic
precise_amount = token_amount.to_decimal()
print(f"Precise amount: {precise_amount}")

# Large number handling (ui_amount may be None)
large_amount = UiTokenAmount(
    ui_amount=None,  # Too large for float
    decimals=9,
    amount="999999999999999999999",
    ui_amount_string="999999999999.999999999"
)

Account Data Slicing

from solders.account_decoder import UiDataSliceConfig

# Get first 64 bytes of account data
slice_config = UiDataSliceConfig(offset=0, length=64)

# Get specific portion (e.g., skip mint info, get owner)
token_account_slice = UiDataSliceConfig(offset=32, length=32)

print(f"Slice offset: {slice_config.offset}")
print(f"Slice length: {slice_config.length}")

Commitment Level Usage

from solders.commitment_config import CommitmentLevel, CommitmentConfig

# Different commitment levels
processed_config = CommitmentConfig.processed()
confirmed_config = CommitmentConfig.confirmed()
finalized_config = CommitmentConfig.finalized()

# Check commitment level
if confirmed_config.commitment == CommitmentLevel.Confirmed:
    print("Using confirmed commitment level")

# Custom commitment
custom_config = CommitmentConfig(CommitmentLevel.Finalized)

Account Serialization

# Serialize account for storage or transmission
serialized = account.serialize()
print(f"Serialized size: {len(serialized)} bytes")

# Deserialize account
restored_account = Account.deserialize(serialized)
assert restored_account.lamports == account.lamports
assert restored_account.data == account.data
assert restored_account.owner == account.owner

JSON Account Handling

from solders.account import AccountJSON

# Create JSON representation
json_account = AccountJSON(
    lamports=2039280,
    data="dGVzdF9kYXRh",  # Base64 encoded data
    owner="TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
    executable=False,
    rent_epoch=361
)

# Convert to dictionary for JSON serialization
json_dict = json_account.to_json()

# Restore from JSON
restored = AccountJSON.from_json(json_dict)

Parsed Account Analysis

from solders.account_decoder import ParsedAccount

# Parsed token account data
parsed_data = {
    "type": "account",
    "info": {
        "mint": "So11111111111111111111111111111111111111112",
        "owner": "7dHbWXmci3dT8UFYWYZweBLXgycu7Y3iL6trKn1Y7ARj",
        "tokenAmount": {
            "amount": "1000000000",
            "decimals": 9,
            "uiAmount": 1.0,
            "uiAmountString": "1"
        }
    }
}

parsed_account = ParsedAccount(account, parsed_data)

# Check account type
if parsed_account.is_token_account():
    print("This is a token account")
    token_info = parsed_account.parsed_data["info"]
    print(f"Token mint: {token_info['mint']}")
    print(f"Owner: {token_info['owner']}")

if parsed_account.is_mint_account():
    print("This is a mint account")

Account State Management

Account Lifecycle

# New account (empty, system-owned)
new_account = Account.default()
assert new_account.lamports == 0
assert new_account.owner == SYSTEM_PROGRAM_ID
assert not new_account.executable

# Funded account
funded_account = Account(
    lamports=5000000,  # 0.005 SOL
    data=b"",
    owner=SYSTEM_PROGRAM_ID,
    executable=False,
    rent_epoch=361
)

# Program account (executable)
program_account = Account(
    lamports=10000000,
    data=b"program_bytecode_here",
    owner=SYSTEM_PROGRAM_ID,
    executable=True,
    rent_epoch=361
)

Rent Exemption Checking

from solders.rent import Rent

# Calculate rent exemption
rent = Rent.default()
data_size = 165  # Size of token account
minimum_balance = rent.minimum_balance(data_size)

# Check if account is rent exempt
def is_rent_exempt(account: Account) -> bool:
    return account.lamports >= minimum_balance

if is_rent_exempt(account):
    print("Account is rent exempt")
else:
    print(f"Need {minimum_balance - account.lamports} more lamports for rent exemption")

Encoding Utilities

Data Encoding Helpers

import base64
import base58

def encode_account_data(data: bytes, encoding: UiAccountEncoding) -> Union[str, List[str]]:
    """Encode account data in specified format."""
    if encoding == UiAccountEncoding.Base64:
        return base64.b64encode(data).decode()
    elif encoding == UiAccountEncoding.Base58:
        return base58.b58encode(data).decode()
    elif encoding == UiAccountEncoding.JsonParsed:
        # Would require program-specific parsing
        return "parsed"
    else:
        return data.hex()

def decode_account_data(encoded_data: str, encoding: UiAccountEncoding) -> bytes:
    """Decode account data from specified format."""
    if encoding == UiAccountEncoding.Base64:
        return base64.b64decode(encoded_data)
    elif encoding == UiAccountEncoding.Base58:
        return base58.b58decode(encoded_data)
    else:
        return bytes.fromhex(encoded_data)

Constants and Defaults

Well-Known Accounts

# System Program ID (default owner for user accounts)
SYSTEM_PROGRAM_ID: Final[Pubkey] = Pubkey.from_string("11111111111111111111111111111112")

# Native SOL Token Mint
NATIVE_MINT: Final[Pubkey] = Pubkey.from_string("So11111111111111111111111111111111111111112")

Default Values

# Default commitment level for most operations
DEFAULT_COMMITMENT: Final[CommitmentLevel] = CommitmentLevel.Finalized

# Minimum account sizes
MINIMUM_ACCOUNT_SIZE: Final[int] = 0
TOKEN_ACCOUNT_SIZE: Final[int] = 165
MINT_ACCOUNT_SIZE: Final[int] = 82

Install with Tessl CLI

npx tessl i tessl/pypi-solders

docs

account-management.md

cryptographic-primitives.md

error-handling.md

index.md

network-sysvars.md

rpc-functionality.md

system-programs.md

testing-infrastructure.md

token-operations.md

transaction-construction.md

transaction-status.md

tile.json