Puntos Clave de Integración de Wallet
En Solana, los usuarios guardan sus claves en una wallet (extensión de navegador, aplicación móvil o dispositivo de hardware). Tu dApp nunca recibe una clave privada. Descubre wallets, solicita conexión, construye mensajes de transacción sin firmar y pide a la wallet que firme. La wallet muestra una interfaz de aprobación legible por humanos; después de que el usuario confirma, tu aplicación envía el payload firmado a RPC y rastrea la confirmación.
Esta página es el mapa conceptual para la Integración de Wallet - capas de adaptador, conexión y desconexión, firma de transacciones y mensajes, UX de autoconexión y sesión, rutas de hardware y móviles, y los límites de seguridad que mantienen las claves fuera de tu proceso en pilas alineadas con Agave 4.1.1.
Resumen
- La integración de wallet es un puente de capacidades: descubre una wallet estándar, establece una sesión con ámbito de origen, firma solo lo que el usuario aprueba, y luego transmite con tu propio RPC y UX. Los secretos permanecen dentro de la wallet.
- Por Qué Importa: Cada acción pagada por el usuario (intercambio, mint, transferencia, movimiento de juego) y la mayoría de la autenticación fuera de cadena (SIWS) dependen del estado de conexión correcto, la identidad del pagador de tarifas, la alineación del clúster y las previsualizaciones honestas. Los errores producen transacciones fallidas, datos de cuenta incorrectos o UX de nivel de phishing.
- Conceptos Clave: Wallet Standard, adaptador de wallet / wallet-ui, conectar / desconectar / seleccionar, sesión de publicKey, signTransaction / signAllTransactions / signMessage, puente TransactionSendingSigner, autoConnect, SIWS, coincidencia de clúster, tiempos de espera de MWA / hardware.
- Cuándo Usar Este Modelo: Publicar una dApp de React o Next.js, conectar pipelines de mensajes de
@solana/kit7.0.0 a firmadores de navegador, diseñar UX de sesión, soportar Ledger o móvil, o auditar dónde pueden vivir las claves y las firmas. - Limitaciones / Compensaciones: La conexión no es un cheque en blanco para gastos futuros; cada acción sensible requiere aprobación. Los adaptadores difieren por producto; móvil y hardware añaden latencia y modos de fallo. La autenticación del servidor requiere verificación de firma separada, no solo "conectado en React".
- Temas Relacionados: Fundamentos de Wallet, Adaptador de Wallet, Conexión y Desconexión, Firma de Transacciones y Mensajes, Autoconexión y UX de Sesión, Wallets de Hardware y Móviles.
Fundamentos
Una wallet de Solana es software o hardware que contiene pares de claves (o cuentas derivadas de semillas), rastrea el contexto del clúster (mainnet, devnet, testnet) y expone una API limitada: conectar, desconectar, firmar transacciones y, opcionalmente, firmar mensajes arbitrarios.
La dApp posee la UX del producto, la construcción de instrucciones, las lecturas de RPC, la simulación, el envío y la confirmación. No debe tomar frases semilla ni claves privadas si afirma ser una firma no custodial.
Material de clave del usuario
|
v
Wallet (extensión / móvil / hardware)
| conectar, signTransaction, signMessage
v
Adaptador / Puente Wallet Standard
| contexto de React: publicKey, connected, signers
v
dApp (@solana/kit build + RPC send + UI)Wallet Standard (y el ecosistema multi-adaptador a su alrededor) es cómo los navegadores descubren las wallets instaladas sin codificar una marca específica. Las extensiones se registran; tu aplicación las lista para la selección del usuario. En móvil, Mobile Wallet Adapter (MWA) y los deep links juegan un papel similar con una infraestructura diferente.
En React, @solana/wallet-adapter-react (ConnectionProvider, WalletProvider, useWallet, modal opcional) sigue siendo común. Los scaffolds más nuevos pueden usar @wallet-ui/react. Ambos comparten el mismo contrato: proveedores solo para el cliente, adaptadores registrados y hooks para publicKey, connected, connecting, select, connect, disconnect y firma.
Conexión significa que este origen puede solicitar firmas para una cuenta elegida. No es una transacción en cadena ni un inicio de sesión en servidor. publicKey es la identidad de sesión del cliente para el estado indexado por dirección.
La alineación de clúster es obligatoria: la red de la wallet, la URL de RPC y los IDs de programa deben coincidir. Una wallet de mainnet contra un RPC de devnet produce fallos opacos de simulación y envío. Muestra una insignia de clúster y bloquea el envío ante una discrepancia cuando puedas detectarla.
El trabajo de solo lectura (saldos, exploradores, marketing) utiliza RPC sin conexión. Limita solo las acciones que requieren un pagador de tarifas o una firma del usuario.
Mecánicas e Interacciones
Configuración y descubrimiento del adaptador
Monta los proveedores solo en el cliente ("use client" en Next.js App Router). Registra wallets populares para que el modal no esté vacío. Empareja la firma del adaptador con @solana/kit 7.0.0 para la construcción de mensajes y RPC.
"use client";
// Forma conceptual - array de wallets + autoConnect + modal
<ConnectionProvider endpoint={rpcUrl}>
<WalletProvider wallets={wallets} autoConnect>
<WalletModalProvider>{children}</WalletModalProvider>
</WalletProvider>
</ConnectionProvider>Los adaptadores mapean los eventos de Wallet Standard a contexto de React. useWallet() es la superficie de la aplicación. Registra wallet?.adapter.name en herramientas de soporte para errores específicos de la wallet.
Conectar, seleccionar y desconectar
UX típica: Conectar, elegir una wallet en un modal, aprobar en la extensión o aplicación, luego mostrar una dirección truncada y desconectar.
| Estado | Significado | Deber de la UI |
|---|---|---|
| disconnected | Sin sesión | Conectar / seleccionar wallet |
| connecting | Solicitud o autoConnect en curso | Deshabilitar doble clic; mostrar restaurando o conectando |
| connected | publicKey disponible | Chip de cuenta, desconectar, habilitar acciones de firma |
| disconnecting / error | Limpieza o fallo | Reintento amigable; borrar UI optimista |
const { connected, connecting, publicKey, disconnect, select } = useWallet();- Prefiere un selector modal cuando puede haber múltiples wallets instaladas;
connect()sin un adaptador seleccionado es ambiguo. - Desconectar debe borrar las tiendas y cachés de la aplicación indexadas por pubkey para que la siguiente cuenta no herede el estado de cartera o autenticación.
- La conexión no aprueba transacciones futuras. Cada envío todavía necesita una aprobación fresca de la wallet.
Firmar transacciones y mensajes
Tu aplicación construye un mensaje sin firmar: pagador de tarifas = pubkey conectada, blockhash reciente, instrucciones (y presupuesto de cómputo según sea necesario). Opcionalmente simula antes del modal de la wallet. Llama a la API de firma de la wallet. Después de que se devuelvan las firmas, tú aún serializas, envías vía RPC y confirmas.
1. publicKey conectada
2. getLatestBlockhash (kit RPC)
3. createTransactionMessage + pagador de tarifas + instrucciones
4. simulación opcional
5. wallet.signTransaction / helpers de firma de kit
6. enviar + confirmarsignMessage cubre bytes fuera de cadena (por ejemplo, Sign-In with Solana). La wallet devuelve una firma ed25519. Los servidores deben verificar la firma, la vinculación de dominio y el nonce o la caducidad; nunca trates "el cliente dice conectado" como autenticación.
Modos de fallo comunes: pagador de tarifas ≠ cuenta conectada; blockhash obsoleto después de una aprobación lenta de hardware o móvil (reconstruir); transacciones sobredimensionadas sin ALTs; asumir que signTransaction también confirma en cadena (firmar es local; enviar es tuyo).
Integra la wallet en TransactionSendingSigner de kit (o equivalente) para que la ruta de mensaje tipificada y el adaptador permanezcan en un solo pipeline.
Autoconexión y UX de sesión
autoConnect restaura la última wallet elegida al montar (a menudo una preferencia de localStorage, nunca claves secretas). Eso reduce la fricción para las visitas de retorno.
| Patrón | Cuándo encaja | Riesgo si se usa mal |
|---|---|---|
| autoConnect + puerta de carga | dApps de consumo, transacciones frecuentes | Flash de UI "desconectada" si ignoras connecting |
| Conexión manual solamente | Administración de alta seguridad, operaciones raras | Fricción adicional para usuarios diarios |
| Conexión perezosa | Sitios de marketing; conectar a la primera intención de firma | Mayor conversión que los modales de página de destino |
| SIWS + cookie/JWT de servidor | Backends personalizados, APIs restringidas | Sesiones falsificadas si la verificación es solo del cliente |
Muestra restaurando sesión mientras connecting es verdadero. No abras el modal de conexión completo en cada carga. Expón siempre la desconexión. Trata SIWS como una capa separada: la reconexión del adaptador no vuelve a probar la identidad a tu API hasta que vuelvas a verificar una firma o una sesión de servidor aún válida.
Hardware y móvil
En escritorio, los usuarios de Ledger a menudo se conectan a través de una wallet intermediaria que reenvía previsualizaciones al dispositivo. El código de la aplicación sigue siendo controlado por el adaptador; la latencia y la confirmación en varios pasos aumentan. En móvil, la inyección de extensiones difiere: usa MWA, deep links o navegadores integrados en la aplicación. Extiende los tiempos de espera. Prueba en dispositivos reales. Seeker y Seed Vault mantienen la misma regla: la dApp solicita firmas; el dispositivo guarda las semillas. Agrupa las instrucciones para que una acción del producto no signifique muchas indicaciones del dispositivo.
Consideraciones Avanzadas y Aplicaciones
Trata la integración de wallets como un límite de seguridad, no solo como un adorno de UI.
| Límite | Permitido en dApp | Debe permanecer en wallet / dispositivo |
|---|---|---|
| Claves privadas / semillas | Nunca | Siempre |
| Preferencia de conexión | localStorage OK | N/A |
| Bytes de transacción a firmar | Construir y mostrar intención | Firmar después de la revisión del usuario |
| Mensaje de autenticación fuera de cadena | Componer con dominio + caducidad | Firmar; el servidor verifica |
| Cookies de sesión | Después de verificar SIWS | No es un sustituto de las claves |
- Aislamiento de origen: La conexión es por sitio. No enseñes a los usuarios a exportar semillas para "arreglar" una mala conexión.
- Honestidad en la previsualización: Simula y resume las deltas de tokens y el pagador de tarifas antes de la solicitud de la wallet cuando puedas.
- Sin almacenamiento de secretos: Solo claves públicas, preferencia de clúster y flags de UI en el almacenamiento del navegador.
- Confianza del servidor: Verifica SIWS (ed25519, vinculación de dominio, protección contra repetición) en el lado del servidor para APIs autenticadas.
- IDs de clúster y programa: La configuración no debe apuntar silenciosamente una wallet de mainnet a un clúster o programa incorrecto.
Mantén las versiones de wallet-adapter o wallet-ui alineadas con kit y tu scaffold. Doble pila (lecturas de kit + firmas de adaptador) está bien si está documentado; rutas de envío dobles no. Registra el nombre del adaptador, el clúster y la pubkey truncada para soporte. Haz QA con dos wallets de software más hardware y móvil para aplicaciones de consumo. Los modales de conexión necesitan captura de foco, navegación por teclado y copia amigable para rechazos.
En una pila alineada con Agave 4.1.1 (CLI 3.0.10, Anchor 0.32.1, Rust 1.91.1, @solana/kit 7.0.0), ejercita la conexión, el rechazo, la desconexión, la firma retrasada (blockhash obsoleto) y la discrepancia de clúster antes de mainnet.
Conceptos Erróneos Comunes
- "Conectar significa que el sitio puede gastar libremente." Conectar solo abre una sesión para solicitudes posteriores. Cada transacción todavía necesita la aprobación del usuario.
- "Puedo almacenar la clave privada en localStorage por conveniencia." Eso convierte un producto no custodial en una colmena de malware. Nunca.
- "signTransaction también envía la transacción." Firmar devuelve firmas; tu código debe enviar y confirmar.
- "Una marca de wallet es suficiente." Los usuarios llegan con Phantom, Solflare, configuraciones intermediadas por Ledger y wallets móviles. Descubre múltiples opciones.
- "autoConnect es una característica de seguridad." Es una característica de UX. Las UIs de administración de alta seguridad pueden preferir la conexión manual cada vez.
- "Conectado en React equivale a iniciar sesión en el servidor." Las sesiones del servidor requieren verificación SIWS. La
publicKeydel cliente por sí sola es falsificable en las solicitudes. - "Móvil tiene la misma API que la extensión." Los deep links y MWA cambian el comportamiento de la sesión y los tiempos de espera.
- "Las wallets de hardware necesitan bytes de instrucción especiales de la dApp." Generalmente se firma el mismo mensaje; los temporizadores y las previsualizaciones deben adaptarse, no un segundo protocolo.
- "La red RPC y la red de la wallet pueden discrepar si intento lo suficiente." Alinea primero la insignia del clúster, el RPC y la red de la wallet.
- "Desconectar solo oculta el chip de dirección." Desconectar debe soltar la sesión del adaptador y borrar el estado de la aplicación indexado por pubkey.
Preguntas Frecuentes
¿Qué hace una wallet de Solana para una dApp?
Guarda claves, muestra una UI de aprobación y devuelve firmas. La dApp descubre la wallet, construye mensajes, solicita firmas y maneja el envío y la confirmación de RPC.
¿Qué es Wallet Standard?
Una convención de descubrimiento de navegador para que múltiples wallets puedan registrarse y las dApps puedan listarlas sin codificar una API de extensión específica.
¿wallet-adapter vs wallet-ui?
@solana/wallet-adapter-react sigue siendo ampliamente utilizado. @wallet-ui/react aparece en scaffolds más nuevos. Ambos se sitúan por encima del descubrimiento estilo Wallet Standard; elige una pila y mantén las versiones alineadas con kit.
¿Cuándo debo solicitar al usuario que se conecte?
Prefiere la conexión perezosa: solicita cuando el usuario inicia una acción que requiere firma o una vista específica de su pubkey. No bloquees contenido de solo lectura. Ver Conexión y Desconexión.
¿Qué debe borrar desconectar?
La sesión del adaptador más las cachés y almacenes de la aplicación indexados por la publicKey anterior. Deja intactos los datos públicos de marketing.
¿Cómo firmo con @solana/kit 7.0.0 y una wallet de navegador?
Construye el mensaje con kit (pagador de tarifas, blockhash, instrucciones), integra la wallet en un firmador compatible con kit, firma y luego envía a través del RPC de kit. Ver Firma de Transacciones y Mensajes.
¿signTransaction vs signMessage?
signTransaction (o sign-all) autoriza bytes de transacciones en cadena. signMessage firma bytes fuera de cadena para autenticación o atestaciones. Solo las firmas regresan a la página.
¿Debería habilitar autoConnect?
Sí, para la mayoría de las aplicaciones de consumo, con una puerta de carga mientras connecting es verdadero y una desconexión visible. Prefiere la conexión manual para administración de alta seguridad. Ver Autoconexión y UX de Sesión.
¿Cómo se relaciona SIWS con la conexión de wallet?
La conexión proporciona al cliente una publicKey. SIWS prueba el control de esa clave a tu backend a través de un mensaje vinculado al dominio y verificación ed25519 en el lado del servidor. No son la misma capa.
¿Por qué los usuarios de wallets de hardware fallan más a menudo?
Las aprobaciones largas caducan los blockhashes; los tiempos de espera cortos abortan prematuramente; los flujos de múltiples indicaciones causan abandono. Extiende los temporizadores, reconstruye los mensajes y agrupa las instrucciones. Ver Wallets de Hardware y Móviles.
¿Cómo deberían integrarse las wallets móviles?
Usa MWA y rutas de retorno de deep link para tu pila (web vs React Native). Prueba en dispositivos. No asumas la inyección de extensiones de escritorio.
¿Necesito una wallet para leer saldos?
No. Las lecturas de RPC públicas funcionan con cualquier dirección. Requiere conexión solo cuando el usuario necesita firmar o cuando personalizas la UI en torno a su pubkey.
¿Cuál es el límite de seguridad principal?
El material de clave secreta nunca entra en la memoria o almacenamiento de la dApp. La dApp puede contener claves públicas, preferencias, mensajes sin firmar que construyó y firmas devueltas después de la aprobación del usuario.
¿Cómo manejo el rechazo del usuario?
Trata la cancelación como normal: copia amigable, habilita reintentos, sin banners de rastreo de pila. No reenvíes automáticamente en un bucle.
Relacionados
- Fundamentos de Wallet - Wallet Standard, conexión perezosa, conocimiento del clúster
- Adaptador de Wallet - configuración del proveedor y hooks
useWallet - Conexión y Desconexión - estado de sesión y selección de múltiples wallets
- Firma de Transacciones y Mensajes - pipeline de mensajes de kit y firma de wallet
- Autoconexión y UX de Sesión - restaura la sesión sin modales sorpresa
- Wallets de Hardware y Móviles - Ledger, MWA, tiempos de espera
- Mejores Prácticas de Integración de Wallet - checklist 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.