Conceptos básicos de Python para Solana
9 ejemplos para empezar con Python para Solana: 6 básicos y 3 intermedios. Cubre cuándo Python es adecuado, lecturas RPC, construcción de transacciones, AnchorPy y flujos de datos contra clústeres Agave 4.1.1.
Prerrequisitos
Crea un entorno virtual e instala la pila principal de Python:
python3 -m venv .venv
source .venv/bin/activate
pip install solders solana anchorpy httpx pandas polarsApuntar a devnet (coincide con los valores predeterminados de Solana CLI 3.0.10):
export SOLANA_RPC_URL=https://api.devnet.solana.comEjemplos básicos
1. Cuándo Python es adecuado
Python es la herramienta adecuada para la automatización off-chain, no para programas on-chain.
# Buenos casos de uso
USE_CASES = [
"bots de market-making y arbitraje",
"APIs de backend que construyen y retransmiten transacciones",
"indexación, ETL y análisis en pandas/Polars",
"notebooks de investigación y scripts de operaciones puntuales",
]
# Mal caso de uso
ON_CHAIN = "Usa Rust + Anchor 0.32.1 para programas desplegados vía cargo build-sbf"- El código on-chain debe compilar a sBPF; Python no puede ejecutarse en el runtime de Sealevel.
- Python brilla donde dominan las E/S, la programación y las herramientas de datos.
- Mantén las claves de firma fuera de los notebooks; usa variables de entorno o un gestor de secretos.
Relacionado: solders y solana-py - el par de SDK principal
2. Conectarse a RPC
solana-py expone un cliente HTTP asíncrono para JSON-RPC.
from solana.rpc.async_api import AsyncClient
RPC = "https://api.devnet.solana.com"
async def main():
async with AsyncClient(RPC) as client:
slot = (await client.get_slot()).value
print(f"Slot actual: {slot}")
# asyncio.run(main()) # descomentar en un script- Prefiere
AsyncClientpara bots que consultan suscripciones o distribuyen lecturas. - Fija la URL RPC por entorno; nunca codifiques en duro mainnet en scripts de desarrollo.
- Limita la tasa de los endpoints públicos; usa un proveedor de pago para bots de producción.
Relacionado: Lectura de datos de la cadena - cuentas y tokens
3. Leer un saldo con tipos solders
solders refleja los primitivos de Solana en Python con rendimiento de Rust.
from solders.pubkey import Pubkey
from solana.rpc.api import Client
SYSTEM_PROGRAM = Pubkey.from_string("11111111111111111111111111111111")
client = Client("https://api.devnet.solana.com")
resp = client.get_balance(SYSTEM_PROGRAM)
print(f"Lamports: {resp.value}")- Los saldos son lamports (enteros); nunca uses flotantes para matemáticas de tokens.
Pubkeyvalida base58 en la construcción, detectando errores tipográficos temprano.- Los tipos
soldersinteroperan con los constructores de solicitudes desolana-py.
4. Cargar un par de claves desde un archivo
Coincide con el formato de par de claves que escribe Solana CLI 3.0.10.
from solders.keypair import Keypair
kp = Keypair.from_bytes(bytes(open("/path/to/id.json", "rb").read()))
print(kp.pubkey())- Ruta predeterminada de la CLI:
~/.config/solana/id.json(JSON de array secreto de 64 bytes). - Nunca cometas archivos de par de claves; usa
.gitignorey secretos de CI. - Para bots, prefiere una billetera caliente dedicada de bajo saldo por estrategia.
Relacionado: Construcción de transacciones en Python - flujos de firma
5. Construir una instrucción de transferencia simple
Compón instrucciones con solders, luego envuélvelas en una transacción.
from solders.pubkey import Pubkey
from solders.system_program import TransferParams, transfer
from solders.hash import Hash
from solders.message import Message
from solders.transaction import Transaction
payer = Keypair() # reemplaza con tu par de claves
dest = Pubkey.from_string("Recipient1111111111111111111111111111111")
ix = transfer(TransferParams(from_pubkey=payer.pubkey(), to_pubkey=dest, lamports=1_000_000))
blockhash = Hash.from_string("11111111111111111111111111111111") # obtener fresco vía RPC
msg = Message.new_with_blockhash([ix], payer.pubkey(), blockhash)
tx = Transaction.new_unsigned(msg)
tx.sign([payer], blockhash)- Siempre obtén un blockhash reciente de RPC; el marcador de posición anterior es solo ilustrativo.
- Las transferencias del Programa del Sistema son la ruta de envío de extremo a extremo más simple.
- La simulación debe preceder a los envíos a mainnet (ver ejemplos intermedios).
6. Simular antes de enviar
Detecta errores de cuenta y de CU sin gastar tarifas.
from solana.rpc.types import TxOpts
sig = client.send_transaction(tx, opts=TxOpts(skip_preflight=False, preflight_commitment="confirmed"))
print(sig.value)skip_preflight=Falseejecuta la simulación dentro del nodo RPC.- Analiza los
logsen caso de error para depurar cuentas faltantes o errores del programa. - Los bots deben reintentar con un blockhash fresco cuando la simulación informe expiración.
Relacionado: Trading y Bots - patrones de automatización
Ejemplos intermedios
7. Llamar a un programa Anchor con AnchorPy
Carga una IDL e invoca instrucciones con clientes tipados.
from anchorpy import Program, Provider, Wallet
from solana.rpc.async_api import AsyncClient
async def call_anchor():
client = AsyncClient("https://api.devnet.solana.com")
wallet = Wallet.local() # usa ANCHOR_WALLET o la ruta predeterminada
provider = Provider(client, wallet)
program = await Program.at("<PROGRAM_ID>", provider)
# await program.rpc["initialize"](...)- AnchorPy se dirige a las formas de IDL de Anchor 0.32.x; regenera la IDL después de cambios en el programa.
Wallet.local()refleja el comportamiento de Anchor TS para desarrollo; usa rutas de clave explícitas en producción.- Mantén el ID del programa y la versión de la IDL fijados por despliegue.
Relacionado: AnchorPy - guía completa del cliente
8. Paginación de consultas de cuentas grandes
Evita respuestas gigantes de getProgramAccounts.
from solana.rpc.types import MemcmpOpts
filters = [MemcmpOpts(offset=0, bytes="...")] # discriminador específico del programa
resp = client.get_program_accounts(
Pubkey.from_string("<PROGRAM_ID>"),
encoding="base64",
filters=filters,
)- Añade filtros
memcmpen los discriminadores para reducir las cargas útiles. - Para análisis, prefiere un indexador o una exportación a BigTable sobre escaneos RPC brutos.
- Respeta los límites de paginación del proveedor; agrupa por rangos de slots cuando estén disponibles.
Relacionado: Análisis de datos - pipelines de pandas/Polars
9. Registro estructurado para bots
Haz que la respuesta a incidentes sea manejable cuando las transacciones no se confirman.
import logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
log = logging.getLogger("solana-bot")
def on_send_failure(signature: str, err: Exception):
log.error("send_failed sig=%s err=%s", signature, err)- Registra el slot, la antigüedad del blockhash, la tarifa de prioridad y los logs de simulación en caso de fallo.
- Correlaciona con
getSignatureStatusesde Agave 4.1.1 RPC para el seguimiento de confirmaciones. - Envía logs a tu pila de observabilidad; stdout por sí solo es frágil en producción.
Relacionado: Mejores prácticas de Python para Solana - lista de verificación de producción
Versiones de la pila: Esta página fue escrita para Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0 y LiteSVM 0.6.x.