Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.pan.tech/llms.txt

Use this file to discover all available pages before exploring further.

pan agrega tasas de rendimiento (APY) de protocolos DeFi en múltiples chains, permitiendote encontrar las mejores oportunidades automaticamente.

Consulta Básica

const yields = await pan.yields.getAll();

console.log('Mejor APY:', yields.best);
console.log('Todos los yields:', yields.rates);

Estructura de Respuesta

{
  "rates": [
    {
      "chain": "base",
      "protocol": "aave",
      "asset": "USDC",
      "apy": 8.52
    },
    {
      "chain": "arbitrum",
      "protocol": "aave",
      "asset": "USDC",
      "apy": 7.23
    },
    {
      "chain": "ethereum",
      "protocol": "aave",
      "asset": "USDC",
      "apy": 5.15
    }
  ],
  "best": {
    "chain": "base",
    "asset": "USDC",
    "apy": 8.52,
    "reasoning": "Highest APY available"
  }
}

Campos de Rate

CampoTipoDescripción
chainstringNombre de la chain
protocolstringProtocolo DeFi
assetstringToken soportado
apynumberAPY actual (porcentaje)

Mostrar Yields al Usuario

async function mostrarOportunidades() {
  const { rates, best } = await pan.yields.getAll();

  console.log('\n=== Mejores Oportunidades de Rendimiento ===\n');

  // Ordenar por APY descendente
  const ordenados = [...rates].sort((a, b) => b.apy - a.apy);

  ordenados.forEach((y, i) => {
    const mejor = y.chain === best.chain ? ' (MEJOR)' : '';
    console.log(`${i + 1}. ${y.chain} - ${y.protocol}`);
    console.log(`   APY: ${y.apy.toFixed(2)}%${mejor}`);
    console.log('');
  });
}

Decidir Donde Depositar

async function analizarMejorOpcion(walletId, amount) {
  // 1. Obtener balances y yields
  const [balancesResponse, yieldsResponse] = await Promise.all([
    pan.wallet.getBalances(walletId),
    pan.yields.getAll()
  ]);

  const { rates, best } = yieldsResponse;

  // 2. Encontrar donde están los fondos
  const fuentes = [];
  for (const chainData of balancesResponse.chains) {
    const usdc = chainData.tokens.find(t => t.asset === 'USDC');
    if (usdc && parseFloat(usdc.balanceFormatted) > 0) {
      fuentes.push({
        chain: chainData.chain,
        balance: parseFloat(usdc.balanceFormatted)
      });
    }
  }

  // 3. Calcular escenarios
  console.log('\n=== Analisis de Opciones ===\n');

  // Opcion A: Depositar donde están los fondos (sin bridge)
  for (const fuente of fuentes) {
    const yieldLocal = rates.find(y => y.chain === fuente.chain);
    if (yieldLocal) {
      const gananciaAnual = fuente.balance * (yieldLocal.apy / 100);
      console.log(`Sin bridge (${fuente.chain}):`);
      console.log(`  APY: ${yieldLocal.apy}%`);
      console.log(`  Ganancia anual estimada: $${gananciaAnual.toFixed(2)}`);
      console.log('');
    }
  }

  // Opcion B: Bridge al mejor APY
  const gananciaOptima = amount * (best.apy / 100);
  console.log(`Con bridge a ${best.chain}:`);
  console.log(`  APY: ${best.apy}%`);
  console.log(`  Ganancia anual estimada: $${gananciaOptima.toFixed(2)}`);

  // 4. Calcular si vale la pena el bridge
  const apyLocal = rates.find(y => fuentes.some(f => f.chain === y.chain))?.apy || 0;
  const diferenciaApy = best.apy - apyLocal;
  const gananciaExtraAnual = amount * (diferenciaApy / 100);

  // Asumir costo de bridge ~$3
  const costoBridge = 3;
  const diasParaRecuperar = (costoBridge / gananciaExtraAnual) * 365;

  console.log(`\nAnalisis:`);
  console.log(`  Diferencia APY: ${diferenciaApy.toFixed(2)}%`);
  console.log(`  Ganancia extra anual: $${gananciaExtraAnual.toFixed(2)}`);
  console.log(`  Días para recuperar costo de bridge: ${diasParaRecuperar.toFixed(0)}`);

  if (diasParaRecuperar < 30) {
    console.log(`  Recomendacion: Bridge a ${best.chain}`);
    return { action: 'bridge', target: best.chain };
  } else {
    console.log(`  Recomendacion: Depositar localmente`);
    return { action: 'local', target: fuentes[0]?.chain };
  }
}

Componente React de Yields

import { useState, useEffect } from 'react';

function YieldsTable() {
  const [yields, setYields] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function cargar() {
      const data = await pan.yields.getAll();
      setYields(data);
      setLoading(false);
    }
    cargar();
  }, []);

  if (loading) return <div>Cargando yields...</div>;

  return (
    <div className="yields-table">
      <h3>Oportunidades de Rendimiento</h3>

      <div className="best-yield">
        <span>Mejor APY:</span>
        <span className="apy">{yields.best.apy.toFixed(2)}%</span>
        <span className="chain">en {yields.best.chain}</span>
      </div>

      <table>
        <thead>
          <tr>
            <th>Chain</th>
            <th>Protocolo</th>
            <th>APY</th>
          </tr>
        </thead>
        <tbody>
          {yields.rates
            .sort((a, b) => b.apy - a.apy)
            .map((y) => (
              <tr
                key={`${y.chain}-${y.protocol}`}
                className={y.chain === yields.best.chain ? 'best' : ''}
              >
                <td>
                  <ChainIcon chain={y.chain} />
                  {y.chain}
                </td>
                <td>
                  <ProtocolIcon protocol={y.protocol} />
                  {y.protocol}
                </td>
                <td className="apy">
                  {y.apy.toFixed(2)}%
                </td>
              </tr>
            ))}
        </tbody>
      </table>
    </div>
  );
}

function RiskBadge({ level }) {
  const colors = {
    low: 'green',
    medium: 'yellow',
    high: 'red'
  };

  const labels = {
    low: 'Bajo',
    medium: 'Medio',
    high: 'Alto'
  };

  return (
    <span className={`risk-badge ${colors[level]}`}>
      {labels[level]}
    </span>
  );
}

Calcular Ganancias Estimadas

function calcularGanancias(monto, apy, periodos = [30, 90, 365]) {
  const tasaDiaria = apy / 365 / 100;

  return periodos.map(dias => {
    // Interes compuesto diario
    const montoFinal = monto * Math.pow(1 + tasaDiaria, dias);
    const ganancia = montoFinal - monto;

    return {
      dias,
      periodo: días === 30 ? '1 mes' : días === 90 ? '3 meses' : '1 año',
      montoFinal: montoFinal.toFixed(2),
      ganancia: ganancia.toFixed(2),
      porcentaje: ((ganancia / monto) * 100).toFixed(2)
    };
  });
}

// Uso
const ganancias = calcularGanancias(1000, 8.52);
console.log(ganancias);
// [
//   { dias: 30, periodo: '1 mes', montoFinal: '1006.97', ganancia: '6.97', porcentaje: '0.70' },
//   { dias: 90, periodo: '3 meses', montoFinal: '1021.12', ganancia: '21.12', porcentaje: '2.11' },
//   { dias: 365, periodo: '1 año', montoFinal: '1088.97', ganancia: '88.97', porcentaje: '8.90' }
// ]

Alertas de APY

class YieldMonitor {
  constructor(minApy) {
    this.minApy = minApy;
    this.lastBestApy = null;
  }

  async check() {
    const { best } = await pan.yields.getAll();

    const alerts = [];

    // Alerta si APY supera umbral
    if (best.apy >= this.minApy) {
      alerts.push({
        type: 'high_apy',
        message: `APY de ${best.apy}% disponible en ${best.chain}`,
        yield: best
      });
    }

    // Alerta si APY cambio significativamente
    if (this.lastBestApy) {
      const cambio = best.apy - this.lastBestApy;
      if (Math.abs(cambio) > 1) {
        alerts.push({
          type: 'apy_change',
          message: `APY ${cambio > 0 ? 'subio' : 'bajo'} ${Math.abs(cambio).toFixed(2)}%`,
          from: this.lastBestApy,
          to: best.apy
        });
      }
    }

    this.lastBestApy = best.apy;
    return alerts;
  }

  async startMonitoring(intervalMs = 300000, onAlert) {
    // Check inicial
    const alerts = await this.check();
    if (alerts.length) onAlert(alerts);

    // Monitoreo periodico
    setInterval(async () => {
      const alerts = await this.check();
      if (alerts.length) onAlert(alerts);
    }, intervalMs);
  }
}

// Uso
const monitor = new YieldMonitor(8.0);
monitor.startMonitoring(300000, (alerts) => {
  alerts.forEach(alert => {
    console.log(`[ALERTA] ${alert.message}`);
    // Enviar notificación, email, etc.
  });
});

Próximos Pasos

Ejecutar Intents

Depositar en los mejores yields

Monitorear Estado

Seguir tus depositos

API de Yields

Referencia del endpoint

Protocolos

Protocolos soportados