> For the complete documentation index, see [llms.txt](https://docs.ston.fi/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ston.fi/es/seccion-para-desarrolladores/quickstart/swap.md).

# Guía de swap (React)

Esta guía te mostrará cómo crear una aplicación básica de intercambio de tokens usando el SDK y la API de STON.fi en una **React** proyecto. Integraremos la conectividad de la billetera con **TonConnect** (a través de `@tonconnect/ui-react`) para permitir que los usuarios conecten su billetera TON y realicen un intercambio. La guía está pensada para principiantes y asume una experiencia mínima con React.

> **Nota**: En esta demo, aprovecharemos **Tailwind CSS** para el estilo en lugar de usar CSS personalizado. La configuración de Tailwind CSS ya está incluida en las instrucciones de abajo, así que no necesitas configurarlo por separado.

> **Nota**: Puedes usar cualquier gestor de paquetes (npm, yarn, pnpm o bun) para configurar tu proyecto React. En este tutorial, lo mostraremos con **pnpm**.

***

## Índice

1. [Introducción](#id-1.-introduction)
2. [Configuración del proyecto](#id-2.-setting-up-the-project)
3. [Conectar la billetera](#id-3.-connecting-the-wallet)
4. [Obtener los activos disponibles](#id-4.-fetching-available-assets)
5. [Simulando un intercambio](#id-5.-simulating-a-swap)
6. [Ejecutando una transacción de intercambio](#id-6.-executing-a-swap-transaction)
7. [Probar tu intercambio](#id-7.-testing-your-swap)
8. [Conclusión](#id-8.-conclusion)
9. [Demo en vivo](#id-9.-live-demo)
10. [Aplicación de ejemplo avanzada](#id-10.-advanced-example-app)

***

## 1. Introducción

En este inicio rápido, construiremos una aplicación React mínima para:

* Conectarse a una billetera TON (a través de **TonConnect UI**).
* Obtener los tokens disponibles de STON.fi (a través de **`@ston-fi/api`**).
* Simula un intercambio (para ver la salida esperada).
* Ejecuta una transacción de intercambio en la cadena (vía **`@ston-fi/sdk`**).

Usaremos:

* **`@ston-fi/sdk`** – Ayuda a construir la carga útil para la transacción real de intercambio.
* **`@ston-fi/api`** – Nos permite obtener listas de activos, datos de pools y ejecutar simulaciones de intercambio.
* **`@tonconnect/ui-react`** – Proporciona un botón de conexión a billetera TON basado en React y utilidades.

***

## 2. Configuración del proyecto

### 2.1 Crear una aplicación React

Primero, comprobemos si pnpm está instalado en tu sistema:

```bash
pnpm --version
```

Si ves un número de versión (como `10.4.0`), pnpm está instalado. Si obtienes un error, primero tendrás que instalar pnpm:

```bash
npm install -g pnpm
```

Ahora crearemos un nuevo proyecto de React usando **Vite**. Sin embargo, puedes usar cualquier configuración de React que prefieras (Next.js, CRA, etc.).

Ejecuta el siguiente comando para crear un nuevo proyecto de React basado en Vite:

```bash
pnpm create vite --template react
```

Cuando se te solicite, escribe el nombre de proyecto que deseas (por ejemplo, stonfi-swap-app):

```
Nombre del proyecto: » stonfi-swap-app
```

Luego entra en la carpeta:

```bash
cd stonfi-swap-app
```

***

### 2.2 Instalación de los paquetes necesarios

Dentro del directorio de tu nuevo proyecto React, instala los paquetes de STON.fi y TonConnect UI:

```bash
pnpm add @ston-fi/sdk @ston-fi/api @tonconnect/ui-react
```

A continuación, instala Tailwind CSS y su plugin para Vite:

```bash
pnpm add tailwindcss @tailwindcss/vite
```

Además, instala el plugin de polyfills de Node.js para Vite, que es necesario para proporcionar Buffer y otras APIs de Node.js en el entorno del navegador (requerido por las bibliotecas de TON):

```bash
pnpm add vite-plugin-node-polyfills
```

Configura el plugin de Vite actualizando el archivo `vite.config.js` archivo. Solo hacemos polyfill del `buffer` módulo y exponemos la variable global `Buffer` para evitar incluir shims no utilizados en el bundle:

```javascript
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
import { nodePolyfills } from 'vite-plugin-node-polyfills'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    react(),
    tailwindcss(),
    nodePolyfills({
      include: ['buffer'],
      globals: {
        Buffer: true,
      },
    }),
  ],
})
```

Luego, importa Tailwind CSS en tu archivo CSS principal. Abre `src/index.css` y reemplaza todo el código por:

```css
@import "tailwindcss";
```

También puedes eliminar `src/App.css` ya no lo necesitamos y elimina la declaración de importación `import './App.css'` de `src/App.jsx`.

Después de hacer estos cambios, puedes verificar que tu aplicación sigue funcionando correctamente iniciando el servidor de desarrollo:

```bash
pnpm install
pnpm dev
```

Esto debería iniciar tu aplicación en modo desarrollo, normalmente en `http://localhost:5173`. Deberías ver el logotipo y el texto de Vite + React sobre un fondo blanco simple. Como hemos eliminado el estilo predeterminado (App.css), la página se verá más sencilla que la plantilla por defecto.

Si ves el logotipo y el texto, significa que tu configuración de Vite + React está funcionando correctamente. Asegúrate de que todo cargue sin errores antes de continuar con el siguiente paso.

***

## 3. Conectar la billetera

### 3.1 Agregar el proveedor TonConnect

Abre **src/main.jsx** (punto de entrada predeterminado de Vite) y envuelve tu aplicación con el `TonConnectUIProvider`. Este proveedor hace que el contexto de TonConnect esté disponible para tu app y permita la conexión con billeteras. Además, indícale un archivo manifest (que crearemos a continuación) que describa tu app a las billeteras.

```jsx
// src/main.jsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { TonConnectUIProvider } from '@tonconnect/ui-react';
import './index.css'
import App from './App.jsx'

createRoot(document.getElementById('root')).render(
  <StrictMode>
    <TonConnectUIProvider
          // Para fines de demostración, usamos una URL estática para el manifiesto
      // Reemplaza por la tuya: manifestUrl={`${window.location.origin}/tonconnect-manifest.json`}`
      manifestUrl="https://gist.githubusercontent.com/mrruby/243180339f492a052aefc7a666cb14ee/raw/"> 
      <App />
    </TonConnectUIProvider>
  </StrictMode>,
)
```

Esto envuelve el `<App />` componente con `TonConnectUIProvider`. El `manifestUrl` apunta a un `tonconnect-manifest.json` archivo que debe servirse en la raíz de tu app (lo crearemos abajo). Usar `window.location.origin` asegura que use el host correcto (por ejemplo, `http://localhost:5173/tonconnect-manifest.json` en desarrollo).

***

### 3.2 Crear el manifiesto de TonConnect

En la **public** carpeta de tu proyecto, crea un archivo llamado **tonconnect-manifest.json**. Este manifest proporciona a las apps de billetera información sobre tu aplicación (como el nombre y el icono). Debes personalizar este manifest para tu propia aplicación. Aquí tienes un ejemplo:

```json
{
    "url": "https://ton.vote",
    "name": "TON Vote",
    "iconUrl": "https://ton.vote/logo.png"
}
```

Asegúrate de actualizar estos campos para tu aplicación:

* **url**: La URL base desde la que se sirve tu aplicación
* **name**: El nombre visible de tu aplicación (esto es lo que las billeteras mostrarán a los usuarios)
* **iconUrl**: Un enlace al icono de tu aplicación (debe ser una imagen PNG de 180×180)

Asegúrate de que este archivo sea accesible. Cuando se ejecute el servidor de desarrollo, deberías poder obtenerlo en tu navegador en `http://localhost:5173/tonconnect-manifest.json`.

***

### 3.3 Agregar el botón de conectar billetera

En tu **App** principal, componente (por ejemplo, **src/App.jsx**), importa e incluye el `TonConnectButton`. Por ejemplo:

```jsx
// src/App.jsx
import { TonConnectButton } from '@tonconnect/ui-react';

function App() {
  return (
    <div className="flex flex-col items-center justify-center min-h-screen p-4">
      <h1 className="text-2xl font-bold mb-4">Demo de intercambio de STON.fi</h1>
      <TonConnectButton />
    </div>
  );
}

export default App;
```

Esto renderizará un botón "Connect Wallet". Al hacer clic, abrirá un modal con las billeteras TON disponibles. Después de que el usuario conecte, el botón mostrará automáticamente la dirección de la billetera o la información de la cuenta. TonConnect UI gestiona el estado de conexión por ti.

## 4. Obtener los activos disponibles

A continuación, recuperemos la lista de tokens (activos) que se pueden intercambiar en STON.fi. Usamos el cliente de la API de STON.fi (`@ston-fi/api`) para esto. Es importante señalar que, aunque muchos tokens en la blockchain de TON usan una precisión decimal de 9, algunos tokens, como jUSDT, tienen una precisión decimal de 6. Por lo tanto, nos basamos en los metadatos del token para determinar dinámicamente la precisión decimal, garantizando compatibilidad entre distintos tokens.

1. Inicializa el cliente de la API: En el componente donde manejarás el intercambio (podemos seguir trabajando en **App.jsx** por simplicidad), crea una instancia de cliente desde `StonApiClient`. Esta tiene métodos para obtener activos, pools, simular intercambios, etc.
2. Obtén los activos al cargar: Usando el hook de efecto de React, recupera la lista de activos cuando el componente se monte. Guarda los activos en el estado para poder mostrarlos.

```jsx
// src/App.jsx
import { useEffect, useState } from 'react';
import { TonConnectButton } from '@tonconnect/ui-react';
import { StonApiClient, AssetTag } from '@ston-fi/api';

function App() {
  const [assets, setAssets] = useState([]);
  const [fromAsset, setFromAsset] = useState(null);
  const [toAsset, setToAsset] = useState(null);
  const [amount, setAmount] = useState(0);

  // Función única para manejar cambios en "From", "To" y "Amount"
  // Limpia el resultado de la simulación cada vez que cambia cualquier entrada
  const handleChange = (setter) => (e) => {
    const value = e.target.value;
    
    if (setter === setFromAsset || setter === setToAsset) {
      const selectedAsset = assets.find(asset => asset.contractAddress === value);
      setter(selectedAsset);
    } else {
      setter(value);
    }
  };

  // Ayudante para encontrar un activo por dirección y devolver un objeto consistente
  const getAssetInfo = (asset) => {
    if (!asset) return { symbol: 'token', decimals: 10 ** 9 };

    // Determinar el símbolo de visualización
    const symbol = asset.meta?.symbol || asset.meta?.displayName || 'token';

    // Siempre toma la propiedad de decimales desde los metadatos; usa 9 como respaldo si falta
    const decimals = 10 ** (asset.meta?.decimals ?? 9);

    return { symbol, decimals };
  };

  useEffect(() => {
    const fetchAssets = async () => {
      try {
        const client = new StonApiClient();
        const condition = [
          AssetTag.LiquidityVeryHigh,
          AssetTag.LiquidityHigh,
          AssetTag.LiquidityMedium,
        ].join(' | ');
        const assetList = await client.queryAssets({ condition });

        setAssets(assetList);
        if (assetList[0]) setFromAsset(assetList[0]);
        if (assetList[1]) setToAsset(assetList[1]);
      } catch (err) {
        console.error('No se pudieron obtener los activos:', err);
      }
    };
    fetchAssets();
  }, []);

  // Atajo para mostrar el símbolo o "token"
  const displaySymbol = (asset) => getAssetInfo(asset).symbol;

  return (
    <div className="flex flex-col items-center justify-center min-h-screen bg-gradient-to-b from-blue-50 to-indigo-100 p-6">
      <div className="w-full max-w-md bg-white rounded-xl shadow-lg p-6 space-y-6">
        <div className="flex justify-between items-center">
          <h1 className="text-3xl font-bold text-indigo-700">Intercambio STON.fi</h1>
          <TonConnectButton />
        </div>

        <div className="h-px bg-gray-200 w-full my-4"></div>

        {assets.length > 0 ? (
          <div className="space-y-6">
            {/* From */}
            <div className="flex flex-col">
              <label className="text-sm font-medium text-gray-600 mb-1">
                Desde
              </label>
              <select
                value={fromAsset?.contractAddress || ''}
                onChange={handleChange(setFromAsset)}
                className="w-full p-3 bg-gray-50 border border-gray-200 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-all"
              >
                {assets.map((asset) => (
                  <option key={asset.contractAddress} value={asset.contractAddress}>
                    {asset.meta?.symbol || asset.meta?.displayName || 'token'}
                  </option>
                ))}
              </select>
            </div>

            {/* To */}
            <div className="flex flex-col">
              <label className="text-sm font-medium text-gray-600 mb-1">
                A
              </label>
              <select
                value={toAsset?.contractAddress || ''}
                onChange={handleChange(setToAsset)}
                className="w-full p-3 bg-gray-50 border border-gray-200 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-all"
              >
                {assets.map((asset) => (
                  <option key={asset.contractAddress} value={asset.contractAddress}>
                    {asset.meta?.symbol || asset.meta?.displayName || 'token'}
                  </option>
                ))}
              </select>
            </div>

            {/* Amount */}
            <div className="flex flex-col">
              <label className="text-sm font-medium text-gray-600 mb-1">
                Cantidad
              </label>
              <div className="relative">
                <input
                  type="number"
                  placeholder="0.0"
                  value={amount}
                  onChange={handleChange(setAmount)}
                  className="w-full p-3 bg-gray-50 border border-gray-200 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-all"
                />
                <div className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-500 text-sm">
                  {displaySymbol(fromAsset)}
                </div>
              </div>
            </div>

            {/* Botones */}
            <div className="flex space-x-3">
              <button
                className="flex-1 bg-indigo-100 hover:bg-indigo-200 text-indigo-700 font-medium py-3 px-4 rounded-lg transition-all"
              >
                Simular
              </button>
              <button className="flex-1 bg-indigo-600 hover:bg-indigo-700 text-white font-medium py-3 px-4 rounded-lg transition-all">
                Swap
              </button>
            </div>
          </div>
        ) : (
          <div className="flex justify-center items-center py-10">
            <div className="animate-pulse flex space-x-2">
              <div className="h-2 w-2 bg-indigo-500 rounded-full"></div>
              <div className="h-2 w-2 bg-indigo-500 rounded-full"></div>
              <div className="h-2 w-2 bg-indigo-500 rounded-full"></div>
            </div>
            <p className="ml-3 text-gray-600">Cargando activos...</p>
          </div>
        )}
      </div>

      <div className="mt-6 text-center text-xs text-gray-500">
        Impulsado por STON.fi
      </div>
    </div>
  );
}

export default App;
```

Ahora tu aplicación muestra:

* Un botón "Connect Wallet"
* Dos menús desplegables con tokens de STON.fi
* Un campo de entrada para la cantidad
* Botones "Simulate" e "Swap" (aún no funcionales).

***

## 5. Simulación de un intercambio

Antes de ejecutar una transacción de intercambio, es una buena práctica simularla. La simulación nos dice cuántos tokens de destino deberíamos recibir dada una cantidad de entrada, teniendo en cuenta la liquidez y el slippage. Usaremos la `simulateSwap` función de `StonApiClient`.

```jsx
// Cambios del paso #5 en App.jsx
// conserva todas las importaciones del paso #4

function App() {
  // conserva el estado existente del paso #4 y añade simulationResult al estado
  const [simulationResult, setSimulationResult] = useState(null);

  // actualiza handleChange del paso #4 para reiniciar simulationResult al cambiar las entradas
  const handleChange = (setter) => (e) => {
  // conserva el código existente del paso #4
    
    setSimulationResult(null);
  };

  // añade la función handleSimulate
  const handleSimulate = async () => {
    if (!fromAsset || !toAsset || !amount) return;
    try {
      const { decimals: fromDecimals } = getAssetInfo(fromAsset);
      const client = new StonApiClient();

      // Convierte la cantidad visible para el usuario (por ejemplo, 10.5) a unidades de blockchain (por ejemplo, 10500000000)
      // multiplicando por los decimales del token y convirtiendo a cadena para la API
      const offerUnits = (Number(amount) * fromDecimals).toString();
      
      const result = await client.simulateSwap({
        offerAddress: fromAsset.contractAddress,
        askAddress: toAsset.contractAddress,
        slippageTolerance: '0.01',
        offerUnits,
      });
      setSimulationResult(result);
    } catch (err) {
      console.error('La simulación falló:', err);
      setSimulationResult(null);
    }
  };

  // Convierte las unidades de blockchain (por ejemplo, 10500000000) de nuevo a un formato amigable para el usuario (por ejemplo, 10.5000)
  // Esto invierte el proceso realizado para la entrada, dividiendo por los decimales del token
  const formattedOutputAmount = simulationResult
    ? (Number(simulationResult.minAskUnits) / getAssetInfo(toAsset).decimals).toFixed(4)
    : '';

  return (
    // conserva el mismo contenedor JSX del paso #4
    <div className="flex flex-col items-center justify-center min-h-screen bg-gradient-to-b from-blue-50 to-indigo-100 p-6">
        {/* ... código existente del paso #4 ... */}

        {/* Actualiza el botón Simulate para adjuntar el manejador */}
        <button
          onClick={handleSimulate}
          className="flex-1 bg-indigo-100 hover:bg-indigo-200 text-indigo-700 font-medium py-3 px-4 rounded-lg transition-all"
        >
          Simular
        </button>
        {/* ... código existente del paso #4 ... */}
            
        {/* Muestra el resultado de la simulación si existe */}
        
        {/* añadir resultado de simulación */}
        {simulationResult && (
          <div className="mt-4 w-full max-w-md bg-white rounded-xl shadow-lg p-4">
            <div className="text-center">
              <p className="text-lg font-medium text-gray-800">Resumen del intercambio</p>
              <div className="flex justify-center items-center space-x-2 mt-2">
                <p className="text-md font-bold">
                  {amount} {displaySymbol(fromAsset)}
                </p>
                <span className="text-gray-500">→</span>
                <p className="text-md font-bold">
                  {formattedOutputAmount}{' '}
                  {displaySymbol(toAsset)}
                </p>
              </div>
            </div>
          </div>
        )}
      <div className="mt-6 text-center text-xs text-gray-500">
        Impulsado por STON.fi
      </div>
    </div>
  );
}

export default App;
```

Eso es todo para la simulación. Ahora, si:

* Seleccionas los tokens "From" y "To"
* Introduces una cantidad
* Haces clic en "Simulate"

…deberías ver una salida esperada.

***

## 6. Ejecución de una transacción de intercambio

Por último, hagamos que el botón Swap realmente envíe una transacción. Usaremos @ston-fi/sdk para construir los parámetros del intercambio y enviarlos a la billetera mediante TonConnect.

Solo añadimos un manejador más, handleSwap, y lo conectamos al botón Swap. También importaremos todo lo necesario desde @ston-fi/sdk, además del hook de TonConnect UI para enviar transacciones.

En App.jsx, cerca de la parte superior:

```jsx
// Cambios del paso #6

// añade importaciones extra:
import { dexFactory, Client } from "@ston-fi/sdk";
import { TonConnectButton, useTonConnectUI, useTonAddress } from '@tonconnect/ui-react';
```

Dentro del componente App, después de handleSimulate, añade:

```jsx
// continúa en App.jsx
const [tonConnectUI] = useTonConnectUI();
const userAddress = useTonAddress();

  const handleSwap = async () => {
    if (!fromAsset || !toAsset || !amount || !userAddress) {
      alert('Por favor, conecta la billetera e introduce los detalles del intercambio.');
      return;
    }

    if(!simulationResult) {
      alert('Por favor, simula primero el intercambio.');
      return;
    }
  
    try {
      // 1. Inicializa el cliente TON JSON-RPC
      const tonApiClient = new Client({
        endpoint: "https://toncenter.com/api/v2/jsonRPC",
      });
      
      // 2. Usa la información del router incrustada en el resultado de la simulación
      const routerInfo = simulationResult.router;
      const dexContracts = dexFactory(routerInfo);
      const router = tonApiClient.open(
        dexContracts.Router.create(routerInfo.address)
      );
      const proxyTon = dexContracts.pTON.create(routerInfo.ptonMasterAddress);
      
      // 3. Prepara los parámetros comunes de la transacción
      const sharedTxParams = {
        userWalletAddress: userAddress,
        offerAmount: simulationResult.offerUnits,
        minAskAmount: simulationResult.minAskUnits,
      };
      
      // 4. Determina el tipo de intercambio y obtén los parámetros de la transacción
      const getSwapParams = () => {
        // TON -> Jetton
        if (fromAsset.kind === 'Ton') {
          return router.getSwapTonToJettonTxParams({
            ...sharedTxParams,
            proxyTon,
            askJettonAddress: simulationResult.askAddress,
          });
        } 
        // Jetton -> TON
        if (toAsset.kind === 'Ton') {
          return router.getSwapJettonToTonTxParams({
            ...sharedTxParams,
            proxyTon,
            offerJettonAddress: simulationResult.offerAddress,
          });
        }
        // Jetton -> Jetton (no se necesita proxyTon)
        return router.getSwapJettonToJettonTxParams({
          ...sharedTxParams,
          offerJettonAddress: simulationResult.offerAddress,
          askJettonAddress: simulationResult.askAddress,
        });
      };
      
      const swapParams = await getSwapParams();
      
      // 5. Envía la transacción mediante TonConnect
      await tonConnectUI.sendTransaction({
        validUntil: Date.now() + 5 * 60 * 1000,
        messages: [
          {
            address: swapParams.to.toString(),
            amount: swapParams.value.toString(),
            payload: swapParams.body?.toBoc().toString("base64"),
          }
        ]
      });
    } catch (err) {
      console.error('El intercambio falló:', err);
      alert('La transacción de intercambio falló. Consulta la consola para más detalles.');
    }
  };
```

Por último, adjunta este nuevo manejador al botón Swap:

```jsx
// en el render, cerca del botón Simulate
<button
  className="flex-1 bg-indigo-600 hover:bg-indigo-700 text-white font-medium py-3 px-4 rounded-lg transition-all"
  onClick={handleSwap}
>
  Swap
</button>
```

Todo lo demás permanece igual que en el paso #5.

***

## 7. Prueba de tu intercambio

Ahora que tu app está en ejecución, puedes probar la funcionalidad de intercambio:

1. **Conecta tu billetera** haciendo clic en el botón "Connect Wallet" y seleccionando tu billetera TON en el modal.
2. **Selecciona tokens** en los menús desplegables:
   * Elige un token que poseas en el desplegable "From"
   * Selecciona un token que quieras recibir en el desplegable "To"
3. **Introduces una cantidad** que deseas intercambiar (asegúrate de que sea una cantidad que realmente tengas en tu billetera).
4. **Simula el intercambio** haciendo clic en el botón "Simulate" para ver la cantidad de salida esperada antes de confirmar la transacción.
5. **Ejecuta el intercambio** haciendo clic en el botón "Swap". Esto hará que tu billetera te pida aprobar la transacción.
6. **Confirma en tu billetera** cuando aparezca la solicitud de aprobación.

Una vez completado con éxito, la transacción se procesará en la cadena y los saldos de tu billetera se actualizarán en consecuencia. Todo el proceso suele tardar solo unos segundos en completarse.

***

## 8. Conclusión

Ahora tienes una app con React + Vite y Tailwind CSS que:

* Se conecta a una billetera TON usando TonConnect.
* Obtiene los tokens disponibles de STON.fi.
* Simula intercambios (mediante simulateSwap).
* Construye y envía transacciones de intercambio (mediante @ston-fi/sdk).

Más información: [DeFi fácil para proyectos TON: integración de STON.fi](https://blog.ston.fi/easy-defi-for-ton-projects-stonfi-integration/)

Siéntete libre de ampliar esta demo con:

* Mejor manejo de decimales para cada token.
* Configuración personalizada de tolerancia al slippage.
* Mensajes de error/éxito más robustos.

¡Feliz desarrollo en TON y STON.fi!

***

## 9. Demo en vivo

Con esta demo de Replit, puedes:

* Abrir el proyecto directamente en tu navegador
* Hacer un fork del Replit para crear tu propia copia
* Ejecutar la aplicación para verla en acción
* Explorar y modificar el código para aprender cómo funciona
* Experimentar con diferentes funciones y cambios en la interfaz

{% embed url="<https://replit.com/@stonfi/stonfi-swap-app?embed=true>" %}

## 10. Aplicación de ejemplo avanzada

Para quienes buscan un enfoque más avanzado y con más funciones, también tenemos una Demo App en Next.js que:

* Usa Next.js para un framework escalable
* Utiliza hooks y providers para una arquitectura elegante
* Demuestra un mejor manejo de errores, una gestión de estado robusta y funciones adicionales de STON.fi

Puedes explorar el código en nuestro repositorio:

[Aplicación demo de Next.js del SDK de STON.fi](https://github.com/ston-fi/sdk/tree/main/examples/next-js-app)

O verla en acción en nuestra demo en vivo:

[Aplicación demo del SDK](https://sdk-demo-app.ston.fi/swap)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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.ston.fi/es/seccion-para-desarrolladores/quickstart/swap.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.
