# Stellar Wallet Kit - Integración rápida

## **Construyendo un Sistema de Gestión de Carteras Stellar**

Esta guía te mostrará cómo crear un sistema integral de gestión de carteras para la integración con la blockchain Stellar en tu aplicación React/Next.js. El sistema ofrece conexión segura de carteras, desconexión y gestión de estado con persistencia.

### **Resumen**

El sistema consta de tres componentes principales:

1. **Proveedor de Carteras** - Gestión global del estado para la información de la cartera
2. **Hook de Cartera** - Lógica de negocio para las operaciones de la cartera
3. **Configuración del Kit de Carteras** - Configuración de integración con la blockchain Stellar

### **Paso 1: Instalar dependencias**

Primero, instala el paquete requerido del Stellar Wallet Kit:

```bash
npm install @creit.tech/stellar-wallets-kit
```

### **Paso 2: Configurar el Stellar Wallet Kit**

Crea un archivo de configuración que configure el Stellar Wallet Kit con soporte para múltiples tipos de cartera:

```tsx
import {
  StellarWalletsKit,
  WalletNetwork,
  FREIGHTER_ID,
  AlbedoModule,
  FreighterModule,
} from "@creit.tech/stellar-wallets-kit";

/**
 * Configuración principal para el Stellar Wallet Kit
 * Este kit admite múltiples tipos de carteras, incluyendo Freighter y Albedo
 * Configurar para TESTNET durante el desarrollo y MAINNET para producción
 */
export const kit: StellarWalletsKit = new StellarWalletsKit({
  network: WalletNetwork.TESTNET,
  selectedWalletId: FREIGHTER_ID,
  modules: [new FreighterModule(), new AlbedoModule()],
});

/**
 * Interfaz para los parámetros de firma de transacciones
 */
interface signTransactionProps {
  unsignedTransaction: string;
  address: string;
}

/**
 * Firmar una transacción Stellar usando la cartera conectada
 * Esta función maneja el proceso de firma y devuelve la transacción firmada
 * 
 * @param unsignedTransaction - La cadena XDR de la transacción sin firmar
 * @param address - La dirección de la cartera que firmará la transacción
 * @returns Promise<string> - El XDR de la transacción firmada
 */
export const signTransaction = async ({
  unsignedTransaction,
  address,
}: signTransactionProps): Promise<string> => {
  const { signedTxXdr } = await kit.signTransaction(unsignedTransaction, {
    address,
    networkPassphrase: WalletNetwork.TESTNET,
  });

  return signedTxXdr;
};
```

### **Paso 3: Crear el Proveedor de Contexto de la Cartera**

El Proveedor de Carteras gestiona el estado global de la cartera y persiste la información en localStorage para una mejor experiencia de usuario

```tsx
"use client";

import {
  createContext,
  useContext,
  useState,
  useEffect,
  ReactNode,
} from "react";

/**
 * Definición de tipos para el contexto de la cartera
 * Contiene la dirección de la cartera, el nombre y funciones para gestionar el estado de la cartera
 */
type WalletContextType = {
  walletAddress: string | null;
  walletName: string | null;
  setWalletInfo: (address: string, name: string) => void;
  clearWalletInfo: () => void;
};

/**
 * Crear el contexto de React para la gestión del estado de la cartera
 */
const WalletContext = createContext<WalletContextType | undefined>(undefined);

/**
 * Componente Wallet Provider que envuelve la aplicación
 * Gestiona el estado de la cartera y proporciona información de la cartera a los componentes hijos
 * Carga automáticamente la información de la cartera guardada desde localStorage en la inicialización
 */
export const WalletProvider = ({ children }: { children: ReactNode }) => {
  const [walletAddress, setWalletAddress] = useState<string | null>(null);
  const [walletName, setWalletName] = useState<string | null>(null);

  /**
   * Cargar la información de la cartera guardada desde localStorage cuando el componente se monta
   * Esto asegura que el estado de la cartera persista a través de las sesiones del navegador
   */
  useEffect(() => {
    const storedAddress = localStorage.getItem("walletAddress");
    const storedName = localStorage.getItem("walletName");

    if (storedAddress) setWalletAddress(storedAddress);
    if (storedName) setWalletName(storedName);
  }, []);

  /**
   * Establecer la información de la cartera y guardarla en localStorage
   * Esta función se llama cuando una cartera se conecta con éxito
   * 
   * @param address - La dirección pública de la cartera
   * @param name - El nombre/identificador de la cartera (por ejemplo, "Freighter", "Albedo")
   */
  const setWalletInfo = (address: string, name: string) => {
    setWalletAddress(address);
    setWalletName(name);
    localStorage.setItem("walletAddress", address);
    localStorage.setItem("walletName", name);
  };

  /**
   * Borrar la información de la cartera y eliminarla de localStorage
   * Esta función se llama al desconectar una cartera
   */
  const clearWalletInfo = () => {
    setWalletAddress(null);
    setWalletName(null);
    localStorage.removeItem("walletAddress");
    localStorage.removeItem("walletName");
  };

  return (
    <WalletContext.Provider
      value={{ walletAddress, walletName, setWalletInfo, clearWalletInfo }}
    >
      {children}
    </WalletContext.Provider>
  );
};

/**
 * Hook personalizado para acceder al contexto de la cartera
 * Proporciona el estado de la cartera y funciones a los componentes
 * Lanza un error si se usa fuera de WalletProvider
 */
export const useWalletContext = () => {
  const context = useContext(WalletContext);
  if (!context) {
    throw new Error("useWalletContext must be used within WalletProvider");
  }
  return context;
};
```

### **Paso 4: Crear el Hook de la Cartera**

El hook de la cartera encapsula toda la lógica de negocio para las operaciones de la cartera, proporcionando una interfaz limpia para los componentes:

```tsx
import { kit } from "@/config/wallet-kit";
import { useWalletContext } from "@/providers/wallet.provider";
import { ISupportedWallet } from "@creit.tech/stellar-wallets-kit";

/**
 * Hook personalizado que proporciona funcionalidad de conexión y desconexión de carteras
 * Se integra con el Stellar Wallet Kit y gestiona el estado de la cartera a través del contexto
 */
export const useWallet = () => {
  // Obtener funciones de gestión de cartera desde el contexto
  const { setWalletInfo, clearWalletInfo } = useWalletContext();

  /**
   * Conectar a una cartera Stellar usando el Wallet Kit
   * Abre un modal para la selección de cartera y maneja el proceso de conexión
   * Establece automáticamente la información de la cartera en el contexto tras una conexión exitosa
   */
  const connectWallet = async () => {
    await kit.openModal({
      modalTitle: "Conéctate a tu cartera favorita",
      onWalletSelected: async (option: ISupportedWallet) => {
        // Establecer la cartera seleccionada como la cartera activa
        kit.setWallet(option.id);

        // Obtener la dirección y el nombre de la cartera
        const { address } = await kit.getAddress();
        const { name } = option;

        // Almacenar la información de la cartera en el contexto y en localStorage
        setWalletInfo(address, name);
      },
    });
  };

  /**
   * Desconectarse de la cartera actual
   * Borra la información de la cartera del contexto y de localStorage
   * Desconecta la cartera del Stellar Wallet Kit
   */
  const disconnectWallet = async () => {
    await kit.disconnect();
    clearWalletInfo();
  };

  /**
   * Manejar la conexión de la cartera con manejo de errores
   * Envuelve la función connectWallet en un bloque try-catch para un mejor manejo de errores
   */
  const handleConnect = async () => {
    try {
      await connectWallet();
    } catch (error) {
      console.error("Error connecting wallet:", error);
      // Aquí puedes añadir manejo adicional de errores, como mostrar notificaciones al usuario
    }
  };

  /**
   * Manejar la desconexión de la cartera con manejo de errores
   * Envuelve la función disconnectWallet en un bloque try-catch para un mejor manejo de errores
   */
  const handleDisconnect = async () => {
    try {
      await disconnectWallet();
    } catch (error) {
      console.error("Error disconnecting wallet:", error);
      // Aquí puedes añadir manejo adicional de errores, como mostrar notificaciones al usuario
    }
  };

  return {
    connectWallet,
    disconnectWallet,
    handleConnect,
    handleDisconnect,
  };
};
```

### **Paso 5: Integrar el Proveedor en tu App**

Envuelve tu aplicación con WalletProvider para habilitar la gestión del estado de la cartera en toda tu app:

```tsx
import { WalletProvider } from "@/providers/wallet.provider";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <WalletProvider>
          {children}
        </WalletProvider>
      </body>
    </html>
  );
}
```

### **Paso 6: Usar el Hook de Cartera en Componentes**

Ahora puedes usar la funcionalidad de la cartera en cualquier componente. Aquí hay un ejemplo de un botón de conexión de cartera:

```tsx
import { useWallet } from "@/hooks/wallet.hook";
import { useWalletContext } from "@/providers/wallet.provider";

/**
 * Componente de botón para conectar/desconectar la cartera
 * Muestra diferentes estados según el estado de conexión de la cartera
 */
export const WalletButton = () => {
  const { handleConnect, handleDisconnect } = useWallet();
  const { walletAddress, walletName } = useWalletContext();

  // Si la cartera está conectada, mostrar la opción de desconexión
  if (walletAddress) {
    return (
      <div className="flex items-center gap-4">
        <div className="text-sm">
          <p className="font-medium">Conectado: {walletName}</p>
          <p className="text-gray-500">{walletAddress}</p>
        </div>
        <button 
          onClick={handleDisconnect}
          className="px-4 py-2 bg-red-500 text-white rounded hover:bg-red-600"
        >
          Desconectar
        </button>
      </div>
    );
  }

  // Si la cartera no está conectada, mostrar la opción de conexión
  return (
    <button 
      onClick={handleConnect}
      className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
    >
      Conectar Billetera
    </button>
  );
};
```

### **Características clave y beneficios**

#### **Persistencia de estado**

* La información de la cartera se guarda automáticamente en localStorage
* Los usuarios no necesitan reconectar su cartera cada vez que visitan tu app
* Experiencia de usuario fluida a través de las sesiones del navegador

#### **Soporte multi-cartera**

* Admite múltiples tipos de carteras Stellar (Freighter, Albedo, etc.)
* Fácil de agregar nuevos módulos de cartera a medida que estén disponibles
* Los usuarios pueden elegir su cartera preferida

#### **Manejo de errores**

* Manejo de errores integral para las operaciones de cartera
* Recuperaciones elegantes cuando las operaciones de cartera fallan
* Fácil de extender con notificaciones de error personalizadas

#### **Seguridad de tipos**

* Soporte completo de TypeScript con definiciones de tipos adecuadas
* Soporte de IntelliSense para una mejor experiencia de desarrollo
* Verificación de errores en tiempo de compilación para las operaciones de cartera

#### **Arquitectura basada en contexto**

* Separación clara de responsabilidades entre la gestión del estado y la lógica de negocio
* Fácil acceso al estado de la cartera desde cualquier componente
* Gestión centralizada del estado de la cartera

### **Opciones de configuración**

#### **Selección de red**

* **TESTNET**: Usar durante el desarrollo y las pruebas
* **MAINNET**: Usar para aplicaciones en producción


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.trustlesswork.com/trustless-work/v1-es/introduccion/developer-resources/stellar-wallet-kit-integracion-rapida.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
