Comprehensive Python SDK for interacting with the Solana blockchain network including RPC clients, SPL Token support, and WebSocket subscriptions.
—
Essential utilities for Solana development including cluster configuration, validation helpers, constants, error handling, and development tools. These utilities provide the foundation for robust Solana applications.
Core constants and program identifiers used throughout the Solana ecosystem.
# Core Solana constants
LAMPORTS_PER_SOL: int = 1_000_000_000 # Number of lamports in one SOL
# Program IDs
SYSTEM_PROGRAM_ID: Pubkey # System Program for account creation and transfers
CONFIG_PROGRAM_ID: Pubkey # Config Program for network configuration
STAKE_PROGRAM_ID: Pubkey # Stake Program for staking operations
VOTE_PROGRAM_ID: Pubkey # Vote Program for validator voting
ADDRESS_LOOKUP_TABLE_PROGRAM_ID: Pubkey # Address Lookup Table Program
BPF_LOADER_PROGRAM_ID: Pubkey # BPF Loader Program for program deployment
ED25519_PROGRAM_ID: Pubkey # Ed25519 signature verification program
SECP256K1_PROGRAM_ID: Pubkey # Secp256k1 signature verification program
# SPL Token constants
TOKEN_PROGRAM_ID: Pubkey # SPL Token Program
TOKEN_2022_PROGRAM_ID: Pubkey # SPL Token 2022 Program
ASSOCIATED_TOKEN_PROGRAM_ID: Pubkey # Associated Token Program
WRAPPED_SOL_MINT: Pubkey # Native SOL mint for wrapped SOL
NATIVE_DECIMALS: int = 9 # Decimal places for SOL
# Account size constants
MINT_LEN: int = 82 # Size of token mint account data
ACCOUNT_LEN: int = 165 # Size of token account data
MULTISIG_LEN: int = 355 # Size of multisig account data
# SPL Memo constants
MEMO_PROGRAM_ID: Pubkey # SPL Memo ProgramUtilities for configuring and connecting to different Solana network clusters including mainnet, testnet, and devnet.
def cluster_api_url(cluster: Optional[Cluster] = None, tls: bool = True) -> str:
"""
Get API URL for a Solana cluster.
Parameters:
- cluster: Cluster name ("mainnet-beta", "testnet", "devnet"), defaults to "devnet"
- tls: Whether to use HTTPS (True) or HTTP (False)
Returns:
str: Cluster API URL
"""
# Cluster type definition
Cluster = Literal["mainnet-beta", "testnet", "devnet"]
# Pre-configured cluster endpoints
ENDPOINT: Dict[str, ClusterUrls] # Dictionary of cluster configurations
class ClusterUrls(NamedTuple):
http: str # HTTP RPC endpoint
https: str # HTTPS RPC endpoint
ws: str # WebSocket endpoint
wss: str # Secure WebSocket endpoint
class Endpoint(NamedTuple):
http: str # HTTP endpoint
https: str # HTTPS endpointHelper functions for validating instructions, parameters, and other Solana-specific data structures.
def validate_instruction_keys(instruction: Instruction, expected: int) -> None:
"""
Validate that an instruction has the expected number of keys.
Parameters:
- instruction: Instruction to validate
- expected: Expected number of keys
Raises:
ValueError: If instruction doesn't have expected number of keys
"""
def validate_instruction_type(parsed_data: Any, expected_type: Any) -> None:
"""
Validate that parsed instruction data matches expected type.
Parameters:
- parsed_data: Parsed instruction data
- expected_type: Expected data type or structure
Raises:
ValueError: If parsed data doesn't match expected type
"""Structured exception handling system for Solana operations with specific error types and decorator utilities.
class SolanaExceptionBase(Exception):
"""Base exception class for all Solana-related errors."""
pass
class SolanaRpcException(SolanaExceptionBase):
"""Exception class for RPC-specific errors."""
def __init__(self, message: str, error_code: Optional[int] = None, error_data: Optional[Any] = None):
"""
Initialize RPC exception.
Parameters:
- message: Error message
- error_code: RPC error code
- error_data: Additional error data
"""
super().__init__(message)
self.error_code = error_code
self.error_data = error_data
def handle_exceptions(func: Callable) -> Callable:
"""
Decorator for handling synchronous exceptions in Solana operations.
Parameters:
- func: Function to wrap with exception handling
Returns:
Callable: Wrapped function with exception handling
"""
def handle_async_exceptions(func: Callable) -> Callable:
"""
Decorator for handling asynchronous exceptions in Solana operations.
Parameters:
- func: Async function to wrap with exception handling
Returns:
Callable: Wrapped async function with exception handling
"""Utilities for parsing and validating security.txt metadata from on-chain programs.
def parse_security_txt(data: bytes) -> SecurityTxt:
"""
Parse security.txt data from program account.
Parameters:
- data: Raw security.txt data from program account
Returns:
SecurityTxt: Parsed security information
Raises:
NoSecurityTxtFoundError: If security.txt data is not found or invalid
"""
class SecurityTxt:
"""
Dataclass containing security.txt information.
Attributes:
- name: Program name
- project_url: Project website URL
- contacts: List of security contact methods
- policy: Security policy URL
- preferred_languages: Preferred languages for security reports
- source_code: Source code repository URL
- source_revision: Source code revision/commit
- source_release: Source code release version
- auditors: List of security auditors
- acknowledgments: Security acknowledgments URL
- expiry: Expiry date for security information
"""
class NoSecurityTxtFoundError(Exception):
"""Exception raised when security.txt is not found in program data."""
# Security.txt format constants
HEADER: str # Security.txt file header marker
FOOTER: str # Security.txt file footer markerUtilities for interacting with the Solana Vote Program for validator operations.
def withdraw_from_vote_account(params: WithdrawFromVoteAccountParams) -> Instruction:
"""
Create instruction to withdraw from a vote account.
Parameters:
- params: Withdrawal parameters
Returns:
Instruction: Withdraw instruction for transaction
"""
class WithdrawFromVoteAccountParams(NamedTuple):
vote_account_pubkey: Pubkey # Vote account to withdraw from
authorized_withdrawer_pubkey: Pubkey # Authorized withdrawer
to_pubkey: Pubkey # Destination for withdrawn funds
lamports: int # Amount to withdrawCommitment level constants for controlling transaction and query confirmation requirements.
# Commitment type and constants
Commitment = str # Type alias for commitment level strings
# Commitment levels (ordered from fastest to most secure)
Processed: Commitment = "processed" # Query the most recent block confirmed by cluster
Confirmed: Commitment = "confirmed" # Query the most recent block with at least 1 confirmation
Finalized: Commitment = "finalized" # Query the most recent block confirmed by supermajority
# Deprecated commitment levels (use modern equivalents above)
Max: Commitment = "max" # Deprecated, use "finalized"
Root: Commitment = "root" # Deprecated, use "finalized"
Single: Commitment = "single" # Deprecated, use "confirmed"
Recent: Commitment = "recent" # Deprecated, use "processed"Frequently used type definitions and parameter structures for Solana operations.
# RPC and networking types
URI = str # Type alias for endpoint URI strings
RPCMethod = str # Type alias for RPC method name strings
class RPCError(TypedDict):
code: int # Error code
message: str # Error message
data: Optional[Any] # Additional error data
# Query parameter types
class DataSliceOpts(NamedTuple):
offset: int # Starting byte offset
length: int # Number of bytes to return
class MemcmpOpts(NamedTuple):
offset: int # Byte offset for comparison
bytes_: str # Base58 encoded bytes to compare
class TokenAccountOpts(NamedTuple):
mint: Optional[Pubkey] = None # Filter by token mint
program_id: Optional[Pubkey] = None # Filter by token program
# Transaction options
class TxOpts(NamedTuple):
skip_preflight: bool = False # Skip transaction simulation
preflight_commitment: Optional[Commitment] = None # Commitment for simulation
encoding: str = "base64" # Transaction encoding
max_retries: Optional[int] = None # Maximum retry attempts
skip_confirmation: bool = False # Skip waiting for confirmationfrom solana.rpc.api import Client
from solana.utils.cluster import cluster_api_url
# Connect to different clusters
mainnet_client = Client(cluster_api_url("mainnet-beta"))
testnet_client = Client(cluster_api_url("testnet"))
devnet_client = Client(cluster_api_url("devnet"))
# Use custom endpoint
custom_client = Client("https://my-custom-rpc.com")from solana.exceptions import SolanaRpcException, handle_exceptions
from solana.rpc.api import Client
@handle_exceptions
def safe_get_balance(client: Client, pubkey: Pubkey):
try:
return client.get_balance(pubkey)
except SolanaRpcException as e:
print(f"RPC Error {e.error_code}: {e}")
return Nonefrom solana.utils.validate import validate_instruction_keys
from solders.instruction import Instruction
# Validate instruction has correct number of keys
def process_instruction(instruction: Instruction):
validate_instruction_keys(instruction, 3) # Expects exactly 3 keys
# Process instruction...from solana.constants import LAMPORTS_PER_SOL, SYSTEM_PROGRAM_ID
from spl.token.constants import TOKEN_PROGRAM_ID
# Convert SOL to lamports
sol_amount = 1.5
lamports = int(sol_amount * LAMPORTS_PER_SOL)
# Use program IDs in instructions
system_program_id = SYSTEM_PROGRAM_ID
token_program_id = TOKEN_PROGRAM_ID# Type aliases
Commitment = str
Cluster = Literal["mainnet-beta", "testnet", "devnet"]
URI = str
RPCMethod = str
# Structured types
class ClusterUrls(NamedTuple):
http: str
https: str
ws: str
wss: str
class Endpoint(NamedTuple):
http: str
https: str
class WithdrawFromVoteAccountParams(NamedTuple):
vote_account_pubkey: Pubkey
authorized_withdrawer_pubkey: Pubkey
to_pubkey: Pubkey
lamports: int
class SecurityTxt:
name: Optional[str]
project_url: Optional[str]
contacts: List[str]
policy: Optional[str]
preferred_languages: Optional[str]
source_code: Optional[str]
source_revision: Optional[str]
source_release: Optional[str]
auditors: List[str]
acknowledgments: Optional[str]
expiry: Optional[str]
class DataSliceOpts(NamedTuple):
offset: int
length: int
class MemcmpOpts(NamedTuple):
offset: int
bytes_: str
class TokenAccountOpts(NamedTuple):
mint: Optional[Pubkey] = None
program_id: Optional[Pubkey] = None
class TxOpts(NamedTuple):
skip_preflight: bool = False
preflight_commitment: Optional[Commitment] = None
encoding: str = "base64"
max_retries: Optional[int] = None
skip_confirmation: bool = False
class RPCError(TypedDict):
code: int
message: str
data: Optional[Any]Install with Tessl CLI
npx tessl i tessl/pypi-solana