Experiencia de Usuario de Transacciones
Notificaciones, confirmaciones, reintentos y decodificación de errores para envíos dirigidos al usuario.
Receta
type TxState = "idle" | "building" | "signing" | "sending" | "confirmed" | "failed";Cuándo usar esto:
- Cualquier botón que active la aprobación de la billetera.
- Reducción de tickets de soporte por fallos opacos.
- Pulido profesional en lanzamientos en mainnet.
Ejemplo Funcional
"use client";
import { useState } from "react";
export function useTxToast() {
const [state, setState] = useState<TxState>("idle");
const [signature, setSignature] = useState<string | null>(null);
const [error, setError] = useState<string | null>(null);
async function run(sendFn: () => Promise<string>) {
try {
setError(null);
setState("signing");
const sig = await sendFn();
setSignature(sig);
setState("confirmed");
return sig;
} catch (e) {
setError(e instanceof Error ? e.message : "Transaction failed");
setState("failed");
throw e;
}
}
return { state, signature, error, run };
}Lo que esto demuestra:
- Máquina de estados explícita para spinners de UI.
- Captura de la firma para enlace al explorador.
- Diferenciación entre rechazo de billetera y error de programa en la capa de UI.
Análisis Profundo
Cómo Funciona
- Simular antes de firmar para mapear logs del programa a texto.
- Mostrar enlace al explorador al confirmar.
- Reintentar con un
blockhashnuevo en caso de errores de expiración. - Deshabilitar envíos duplicados mientras están en curso.
Errores Comunes
- Notificación genérica de "fallido": los usuarios reintentan ciegamente. Solución: decodificar logs de simulación.
- Sin estado pendiente: clics dobles. Solución: deshabilitar el botón.
- Asumir finalización instantánea: éxito prematuro. Solución: indicar el nivel de compromiso.
- Falta de enlace al explorador: fricción de soporte. Solución: plantilla de URL consciente del clúster.
- Bucle de reintento infinito: mismo error de programa. Solución: limitar reintentos; mostrar guía de solución.
Alternativas
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| Email al confirmar | Operaciones de alto valor | Transacciones de juegos para consumidores |
| Envío silencioso en segundo plano | Analítica | Transferencias iniciadas por el usuario |
Preguntas Frecuentes
App Router?
Proveedores en layout.tsx del cliente; las páginas mezclan componentes de servidor y cliente.
Secretos?
Solo variables de entorno del servidor para keypairs; NEXT_PUBLIC_ para URLs RPC.
kit 7.0.0?
Todos los ejemplos usan @solana/kit, no web3.js v1.
Billetera?
Firma solo en componentes del cliente.
Caché?
Revalidar lecturas on-chain cuidadosamente: la cadena es la fuente de verdad.
Acciones?
Endpoints HTTPS que devuelven JSON de Acciones de Solana.
Móvil?
Aplicación React Native separada con MWA.
Pruebas?
Surfpool para integración; mock RPC en pruebas unitarias.
Mainnet?
Archivos de entorno y program IDs separados.
Errores?
Decodificar logs de simulación para mensajes dirigidos al usuario.
Relacionado
- Firma del Lado del Cliente - pipeline de envío
- Firma y Envío - confirmación con kit
- Depuración de Transacciones Fallidas - operaciones
Versiones de Stack: 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.