Python bindings for Solana Rust tools providing high-performance blockchain development primitives, RPC functionality, and testing infrastructure.
—
Core blockchain cryptography implementations providing Ed25519 keypairs, signatures, public keys, and SHA-256 hashing. These primitives form the foundation for all Solana operations including account identification, transaction signing, and data integrity verification.
Solana addresses and program identifiers represented as 32-byte Ed25519 public keys with derivation and validation capabilities.
class Pubkey:
"""
Represents a 32-byte Solana public key used for addresses and program IDs.
"""
def __init__(self, value: bytes):
"""
Create a Pubkey from 32 bytes.
Parameters:
- value: bytes, exactly 32 bytes representing the public key
Raises:
- ValueError: if value is not exactly 32 bytes
"""
@classmethod
def from_string(cls, s: str) -> 'Pubkey':
"""
Parse a base58-encoded string into a Pubkey.
Parameters:
- s: str, base58-encoded public key string
Returns:
Pubkey object
Raises:
- ValueError: if string is not valid base58 or wrong length
"""
@classmethod
def from_bytes(cls, data: bytes) -> 'Pubkey':
"""
Create Pubkey from byte array.
Parameters:
- data: bytes, public key data
Returns:
Pubkey object
"""
@staticmethod
def find_program_address(seeds: List[bytes], program_id: 'Pubkey') -> Tuple['Pubkey', int]:
"""
Find a program derived address (PDA) with bump seed.
Parameters:
- seeds: List[bytes], seed components for derivation
- program_id: Pubkey, program that owns the derived address
Returns:
Tuple of (derived_pubkey, bump_seed)
"""
@staticmethod
def create_program_address(seeds: List[bytes], program_id: 'Pubkey') -> 'Pubkey':
"""
Create program address from seeds (must not be on Ed25519 curve).
Parameters:
- seeds: List[bytes], seed components including bump
- program_id: Pubkey, program that owns the derived address
Returns:
Pubkey object
Raises:
- ValueError: if derived address is on Ed25519 curve
"""
def __str__(self) -> str:
"""Return base58 string representation."""
def __bytes__(self) -> bytes:
"""Return 32-byte representation."""
def __eq__(self, other) -> bool:
"""Compare equality with another Pubkey."""Ed25519 keypair generation and management for transaction signing and account ownership.
class Keypair:
"""
Ed25519 key pair for signing transactions and proving account ownership.
"""
def __init__(self):
"""Generate a new random keypair."""
@classmethod
def from_seed(cls, seed: bytes) -> 'Keypair':
"""
Create keypair from a 32-byte seed for deterministic generation.
Parameters:
- seed: bytes, exactly 32 bytes for deterministic key generation
Returns:
Keypair object
Raises:
- ValueError: if seed is not exactly 32 bytes
"""
@classmethod
def from_secret_key_bytes(cls, secret_key: bytes) -> 'Keypair':
"""
Create keypair from 64-byte secret key.
Parameters:
- secret_key: bytes, 64-byte Ed25519 secret key
Returns:
Keypair object
"""
@classmethod
def from_base58_string(cls, s: str) -> 'Keypair':
"""
Create keypair from base58-encoded secret key string.
Parameters:
- s: str, base58-encoded secret key
Returns:
Keypair object
"""
def pubkey(self) -> Pubkey:
"""
Get the public key component.
Returns:
Pubkey object representing the public key
"""
def secret(self) -> bytes:
"""
Get the secret key bytes.
Returns:
bytes, 64-byte secret key (private key + public key)
"""
def sign_message(self, message: bytes) -> 'Signature':
"""
Sign a message with this keypair.
Parameters:
- message: bytes, message to sign
Returns:
Signature object
"""
def to_base58_string(self) -> str:
"""
Export secret key as base58 string.
Returns:
str, base58-encoded secret key
"""Ed25519 signature creation and verification for transaction authentication.
class Signature:
"""
Represents a 64-byte Ed25519 signature for transaction authentication.
"""
def __init__(self, signature_bytes: bytes):
"""
Create signature from 64 bytes.
Parameters:
- signature_bytes: bytes, exactly 64 bytes representing the signature
Raises:
- ValueError: if signature_bytes is not exactly 64 bytes
"""
@classmethod
def from_string(cls, s: str) -> 'Signature':
"""
Parse a base58-encoded signature string.
Parameters:
- s: str, base58-encoded signature string
Returns:
Signature object
Raises:
- ValueError: if string is not valid base58 or wrong length
"""
@classmethod
def default() -> 'Signature':
"""
Create a default (all zeros) signature.
Returns:
Signature object with all zero bytes
"""
def __str__(self) -> str:
"""Return base58 string representation."""
def __bytes__(self) -> bytes:
"""Return 64-byte signature."""
def __eq__(self, other) -> bool:
"""Compare equality with another Signature."""
def verify(self, pubkey: Pubkey, message: bytes) -> bool:
"""
Verify signature against public key and message.
Parameters:
- pubkey: Pubkey, public key to verify against
- message: bytes, original message that was signed
Returns:
bool, True if signature is valid
"""SHA-256 hashing for blockhashes, transaction IDs, and data integrity verification.
class Hash:
"""
Represents a 32-byte SHA-256 hash used for blockhashes and transaction IDs.
"""
def __init__(self, value: bytes):
"""
Create hash from 32 bytes.
Parameters:
- value: bytes, exactly 32 bytes representing the hash
Raises:
- ValueError: if value is not exactly 32 bytes
"""
@classmethod
def from_string(cls, s: str) -> 'Hash':
"""
Parse a base58-encoded hash string.
Parameters:
- s: str, base58-encoded hash string
Returns:
Hash object
Raises:
- ParseHashError: if string is not valid base58 or wrong length
"""
@classmethod
def default() -> 'Hash':
"""
Create a default (all zeros) hash.
Returns:
Hash object with all zero bytes
"""
@staticmethod
def hash(data: bytes) -> 'Hash':
"""
Compute SHA-256 hash of data.
Parameters:
- data: bytes, data to hash
Returns:
Hash object containing the SHA-256 digest
"""
@staticmethod
def hashv(data: List[bytes]) -> 'Hash':
"""
Compute SHA-256 hash of multiple byte arrays.
Parameters:
- data: List[bytes], list of byte arrays to hash together
Returns:
Hash object containing the SHA-256 digest
"""
def __str__(self) -> str:
"""Return base58 string representation."""
def __bytes__(self) -> bytes:
"""Return 32-byte hash."""
def __eq__(self, other) -> bool:
"""Compare equality with another Hash."""Non-standard signer implementations for specialized use cases.
class NullSigner:
"""
No-op signer for read-only operations and simulation.
"""
def __init__(self, pubkey: Pubkey):
"""
Create null signer with specified public key.
Parameters:
- pubkey: Pubkey, public key this signer represents
"""
def pubkey(self) -> Pubkey:
"""
Get the public key.
Returns:
Pubkey object
"""
class Presigner:
"""
Container for pre-computed signatures.
"""
def __init__(self, pubkey: Pubkey, signature: Signature):
"""
Create presigner with public key and signature.
Parameters:
- pubkey: Pubkey, public key that created the signature
- signature: Signature, pre-computed signature
"""
def pubkey(self) -> Pubkey:
"""
Get the public key.
Returns:
Pubkey object
"""
def signature(self) -> Signature:
"""
Get the pre-computed signature.
Returns:
Signature object
"""from solders.keypair import Keypair
from solders.pubkey import Pubkey
# Generate new keypair
keypair = Keypair()
pubkey = keypair.pubkey()
print(f"Public key: {pubkey}")
print(f"Secret key: {keypair.to_base58_string()}")
# Create from seed for deterministic generation
seed = b'my_deterministic_seed_32_bytes!'
deterministic_keypair = Keypair.from_seed(seed)
# Sign and verify a message
message = b"Hello, Solana!"
signature = keypair.sign_message(message)
is_valid = signature.verify(keypair.pubkey(), message)
print(f"Signature valid: {is_valid}")from solders.pubkey import Pubkey
# Find PDA for token metadata
mint_pubkey = Pubkey.from_string("So11111111111111111111111111111111111111112")
metadata_program_id = Pubkey.from_string("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s")
seeds = [
b"metadata",
bytes(metadata_program_id),
bytes(mint_pubkey)
]
pda, bump = Pubkey.find_program_address(seeds, metadata_program_id)
print(f"Metadata PDA: {pda}, bump: {bump}")
# Create the actual address with bump
seeds_with_bump = seeds + [bytes([bump])]
actual_pda = Pubkey.create_program_address(seeds_with_bump, metadata_program_id)
assert pda == actual_pdafrom solders.hash import Hash
# Hash single data
data = b"transaction_data"
hash_result = Hash.hash(data)
print(f"SHA-256 hash: {hash_result}")
# Hash multiple pieces of data
hash_multiple = Hash.hashv([b"part1", b"part2", b"part3"])
print(f"Multi-part hash: {hash_multiple}")
# Parse from string
hash_from_string = Hash.from_string("11111111111111111111111111111112")# System Program ID
SYSTEM_PROGRAM_ID: Final[Pubkey] = Pubkey.from_string("11111111111111111111111111111112")
# Native SOL Token Mint
NATIVE_MINT: Final[Pubkey] = Pubkey.from_string("So11111111111111111111111111111111111111112")
# SPL Token Program ID
TOKEN_PROGRAM_ID: Final[Pubkey] = Pubkey.from_string("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")# Default signature (all zeros)
DEFAULT_SIGNATURE: Final[Signature] = Signature.default()
# Default hash (all zeros)
DEFAULT_HASH: Final[Hash] = Hash.default()class ParseHashError(Exception):
"""
Exception raised when hash string parsing fails.
Raised by:
- Hash.from_string() with invalid base58 or wrong length
"""Common error scenarios:
from solders.hash import Hash, ParseHashError
from solders.pubkey import Pubkey
try:
# Invalid base58 string
invalid_hash = Hash.from_string("invalid_base58_string!!!")
except ParseHashError as e:
print(f"Hash parse error: {e}")
try:
# Wrong length bytes
invalid_pubkey = Pubkey(b"too_short")
except ValueError as e:
print(f"Pubkey creation error: {e}")
try:
# Invalid seed length
invalid_keypair = Keypair.from_seed(b"wrong_length")
except ValueError as e:
print(f"Keypair creation error: {e}")