> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Cómo obtener el historial de transacciones de una billetera de Solana

> Obtén el historial completo de transacciones de cualquier billetera de Solana, con los cambios de saldo de cada transacción. Diseñado para rastreadores de portafolios, contabilidad y análisis.

<Note>
  La Wallet API está en versión beta. Los endpoints y los formatos de respuesta pueden cambiar.
</Note>

## Descripción general

El endpoint Transaction History obtiene el historial completo de transacciones de una billetera de Solana mediante la Enhanced Transactions API. Devuelve transacciones analizadas y fáciles de leer, con los cambios de saldo de cada transacción, en orden cronológico inverso (las más recientes primero).

El endpoint devuelve hasta 100 transacciones por solicitud, por lo que la paginación es manual. Usa el parámetro `before` con `pagination.nextCursor` para obtener la página siguiente y consulta `pagination.hasMore` para saber si hay más resultados disponibles. Cada solicitud equivale a una sola llamada a la API y cuesta 100 créditos.

El parámetro `tokenAccounts` controla si se incluyen las transacciones que involucran cuentas de tokens propiedad de la billetera:

* `balanceChanged` (recomendado): incluye las transacciones que modificaron los saldos de cuentas de tokens y filtra el spam.
* `none`: solo interacciones directas con la billetera.
* `all`: todas las transacciones de cuentas de tokens, incluido el spam.

<Warning>
  El filtro `tokenAccounts` depende del campo `owner` de los metadatos del saldo de tokens, que no estaba disponible antes del slot 111,491,819 (\~diciembre de 2022). Es posible que falten transacciones que involucren cuentas de tokens activas antes de este slot. Consulta el [tutorial de getTransactionsForAddress](/docs/es/rpc/gettransactionsforaddress#limitaciones-y-casos-extremos) para ver una solución alternativa.
</Warning>

## Cuándo usarlo

Usa la Transaction History API cuando necesites:

* **Mostrar un feed de transacciones**: muestra a los usuarios su historial completo de transacciones.
* **Calcular las ganancias y pérdidas**: registra las ganancias y pérdidas de todas las transacciones.
* **Impuestos y contabilidad**: genera informes completos de transacciones para declaraciones fiscales.
* **Análisis de portafolios**: analiza los patrones y la actividad de trading.
* **Registros de auditoría**: conserva registros completos de la actividad de la billetera.
* **Reconstrucción de saldos**: reconstruye los saldos actuales a partir de datos históricos.

## Inicio rápido

### Consulta básica del historial

Obtén las transacciones más recientes con cambios de saldo:

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={"system"}
    const getTransactionHistory = async (address) => {
      const url = `https://api.helius.xyz/v1/wallet/${address}/history?api-key=YOUR_API_KEY`;

      const response = await fetch(url);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      const data = await response.json();

      console.log(`Found ${data.data.length} transactions`);

      // Display recent transactions
      data.data.forEach(tx => {
        const date = new Date(tx.timestamp * 1000).toLocaleString();
        const status = tx.error ? 'Failed' : 'Success';

        console.log(`\n${status} - ${date}`);
        console.log(`Signature: ${tx.signature.slice(0, 20)}...`);
        console.log(`Fee: ${tx.fee} SOL`);

        // Show balance changes
        tx.balanceChanges.forEach(change => {
          const sign = change.amount > 0 ? '+' : '';
          console.log(`  ${sign}${change.amount} ${change.mint === 'SOL' ? 'SOL' : change.mint.slice(0, 8)}...`);
        });
      });

      return data;
    };

    getTransactionHistory("86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY");
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={"system"}
    import requests
    from datetime import datetime

    def get_transaction_history(address: str):
        url = f"https://api.helius.xyz/v1/wallet/{address}/history"
        headers = {"X-Api-Key": "YOUR_API_KEY"}

        response = requests.get(url, headers=headers)
        response.raise_for_status()

        data = response.json()

        print(f"Found {len(data['data'])} transactions")

        # Display recent transactions
        for tx in data['data']:
            date = datetime.fromtimestamp(tx['timestamp']).strftime('%Y-%m-%d %H:%M:%S')
            status = 'Failed' if tx.get('error') else 'Success'

            print(f"\n{status} - {date}")
            print(f"Signature: {tx['signature'][:20]}...")
            print(f"Fee: {tx['fee']} SOL")

            # Show balance changes
            for change in tx['balanceChanges']:
                sign = '+' if change['amount'] > 0 else ''
                mint_display = 'SOL' if change['mint'] == 'SOL' else change['mint'][:8] + '...'
                print(f"  {sign}{change['amount']} {mint_display}")

        return data

    get_transaction_history("86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY")
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={"system"}
    curl "https://api.helius.xyz/v1/wallet/86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY/history?api-key=YOUR_API_KEY"
    ```
  </Tab>
</Tabs>

### Paginación para obtener el historial completo

Obtén todas las transacciones mediante paginación con el parámetro `before`:

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={"system"}
    const getAllTransactionHistory = async (address) => {
      let allTransactions = [];
      let before = null;

      do {
        const url = before
          ? `https://api.helius.xyz/v1/wallet/${address}/history?api-key=YOUR_API_KEY&before=${before}`
          : `https://api.helius.xyz/v1/wallet/${address}/history?api-key=YOUR_API_KEY`;

        const response = await fetch(url);
        const data = await response.json();

        allTransactions = allTransactions.concat(data.data);
        before = data.pagination.hasMore ? data.pagination.nextCursor : null;

        console.log(`Fetched ${allTransactions.length} transactions so far...`);

      } while (before);

      console.log(`\nTotal transactions: ${allTransactions.length}`);
      return allTransactions;
    };

    getAllTransactionHistory("86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY");
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={"system"}
    def get_all_transaction_history(address: str):
        all_transactions = []
        before = None

        while True:
            url = f"https://api.helius.xyz/v1/wallet/{address}/history"
            params = {"api-key": "YOUR_API_KEY"}

            if before:
                params["before"] = before

            response = requests.get(url, params=params, headers={"X-Api-Key": "YOUR_API_KEY"})
            response.raise_for_status()

            data = response.json()
            all_transactions.extend(data['data'])

            print(f"Fetched {len(all_transactions)} transactions so far...")

            if not data['pagination']['hasMore']:
                break

            before = data['pagination']['nextCursor']

        print(f"\nTotal transactions: {len(all_transactions)}")
        return all_transactions

    get_all_transaction_history("86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY")
    ```
  </Tab>
</Tabs>

## Parámetros de consulta

| Parámetro       | Tipo   | Valor predeterminado | Descripción                                                                                               |
| --------------- | ------ | -------------------- | --------------------------------------------------------------------------------------------------------- |
| `limit`         | entero | 100                  | Número máximo de transacciones por solicitud (1-100)                                                      |
| `before`        | cadena | -                    | Obtiene transacciones anteriores a esta firma (usa `pagination.nextCursor` de la respuesta anterior)      |
| `after`         | cadena | -                    | Obtiene transacciones posteriores a esta firma (para paginación en orden ascendente)                      |
| `type`          | cadena | -                    | Filtra por tipo de transacción (por ejemplo, SWAP, TRANSFER, NFT\_SALE, TOKEN\_MINT)                      |
| `tokenAccounts` | cadena | balanceChanged       | Filtra las transacciones que involucran cuentas de tokens: `none`, `balanceChanged` (recomendado) o `all` |

### Tipos de transacciones disponibles

El parámetro `type` permite filtrar por estos tipos de transacciones:

`SWAP`, `TRANSFER`, `NFT_SALE`, `NFT_BID`, `NFT_LISTING`, `NFT_MINT`, `NFT_CANCEL_LISTING`, `TOKEN_MINT`, `BURN`, `COMPRESSED_NFT_MINT`, `COMPRESSED_NFT_TRANSFER`, `COMPRESSED_NFT_BURN`, `CREATE_STORE`, `WHITELIST_CREATOR`, `ADD_TO_WHITELIST`, `REMOVE_FROM_WHITELIST`, `AUCTION_MANAGER_CLAIM_BID`, `EMPTY_PAYMENT_ACCOUNT`, `UPDATE_PRIMARY_SALE_METADATA`, `ADD_TOKEN_TO_VAULT`, `ACTIVATE_VAULT`, `INIT_VAULT`, `INIT_BANK`, `INIT_STAKE`, `MERGE_STAKE`, `SPLIT_STAKE`, `CREATE_AUCTION_MANAGER`, `START_AUCTION`, `CREATE_AUCTION_MANAGER_V2`, `UPDATE_EXTERNAL_PRICE_ACCOUNT`, `EXECUTE_TRANSACTION`

### Ejemplos de filtros

<Tabs>
  <Tab title="Filter by Type">
    ```javascript theme={"system"}
    // Get only SWAP transactions
    const url = `https://api.helius.xyz/v1/wallet/${address}/history?api-key=YOUR_API_KEY&type=SWAP`;
    ```
  </Tab>

  <Tab title="Token Accounts Filter">
    ```javascript theme={"system"}
    // Exclude spam by only including transactions that changed token balances
    const url = `https://api.helius.xyz/v1/wallet/${address}/history?api-key=YOUR_API_KEY&tokenAccounts=balanceChanged`;

    // Only show direct wallet interactions
    const url = `https://api.helius.xyz/v1/wallet/${address}/history?api-key=YOUR_API_KEY&tokenAccounts=none`;
    ```
  </Tab>

  <Tab title="Combined Filters">
    ```javascript theme={"system"}
    // Get only NFT sales that changed balances
    const url = `https://api.helius.xyz/v1/wallet/${address}/history?api-key=YOUR_API_KEY&type=NFT_SALE&tokenAccounts=balanceChanged`;
    ```
  </Tab>
</Tabs>

## Formato de respuesta

```json theme={"system"}
{
  "data": [
    {
      "signature": "5wHu1qwD7Jsj3xqWjdSEJmYr3Q5f5RjXqjqQJ7jqEj7jqEj7jqEj7jqEj7jqEj7jqE",
      "timestamp": 1704067200,
      "slot": 250000000,
      "fee": 0.000005,
      "feePayer": "86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY",
      "error": null,
      "balanceChanges": [
        {
          "mint": "So11111111111111111111111111111111111111111",
          "amount": -0.05,
          "decimals": 9
        },
        {
          "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
          "amount": 50.0,
          "decimals": 6
        }
      ]
    }
  ],
  "pagination": {
    "hasMore": true,
    "nextCursor": "5wHu1qwD7Jsj3xqWjdSEJmYr3Q5f5RjXqjqQJ7jqEj7jqEj7jqEj7jqEj7jqEj7jqE"
  }
}
```

### Notas sobre los campos

* **`timestamp`**: segundos Unix. Puede ser `null` para transacciones muy recientes que aún no se hayan procesado por completo.
* **`error`**: `null` para transacciones exitosas; un valor de error para las que fallaron. Las transacciones fallidas también generan comisiones.
* **`balanceChanges`**: indica cómo cambiaron los activos de la billetera en la transacción. Un valor `amount` positivo representa tokens recibidos y uno negativo representa tokens enviados o gastados.
* **`mint`** (dentro de `balanceChanges`): dirección de acuñación del token, o `"SOL"` para SOL nativo.
* **`amount`** (dentro de `balanceChanges`): **fácil de leer**, ya dividido entre `decimals`. `-0.05` significa −0.05 SOL, no −0.05 lamports. Este endpoint no incluye un campo `amountRaw` sin procesar.

#### Ejemplo de cambios de saldo

```javascript theme={"system"}
// Swap: Sold 0.05 SOL, received 5 USDC
{
  "balanceChanges": [
    { "mint": "SOL", "amount": -0.05, "decimals": 9 },
    { "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "amount": 5.0, "decimals": 6 }
  ]
}

// Simple transfer: Sent 10 USDC
{
  "balanceChanges": [
    { "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "amount": -10.0, "decimals": 6 }
  ]
}
```

## Casos de uso

### Calcular el volumen total de trading

Suma todas las transferencias para obtener el volumen de trading:

```javascript theme={"system"}
const calculateTradingVolume = async (address, tokenMint) => {
  const transactions = await getAllTransactionHistory(address);

  let totalVolume = 0;

  transactions.forEach(tx => {
    tx.balanceChanges.forEach(change => {
      if (change.mint === tokenMint) {
        totalVolume += Math.abs(change.amount);
      }
    });
  });

  console.log(`Total ${tokenMint} volume: ${totalVolume}`);
  return totalVolume;
};

// Example: Calculate total USDC volume
calculateTradingVolume(
  "86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY",
  "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" // USDC
);
```

### Generar un informe fiscal

Crea un informe de transacciones para una declaración fiscal:

```javascript theme={"system"}
const generateTaxReport = async (address, year) => {
  const transactions = await getAllTransactionHistory(address);

  const startDate = new Date(`${year}-01-01`).getTime() / 1000;
  // Set to end of December 31st (23:59:59.999) to include all transactions from that day
  const endDate = new Date(`${year}-12-31T23:59:59.999Z`).getTime() / 1000;

  const taxableTransactions = transactions
    .filter(tx => tx.timestamp >= startDate && tx.timestamp <= endDate)
    .map(tx => ({
      date: new Date(tx.timestamp * 1000).toISOString(),
      signature: tx.signature,
      fee: tx.fee,
      balanceChanges: tx.balanceChanges,
      explorerUrl: `https://orbmarkets.io/tx/${tx.signature}`
    }));

  console.log(`Found ${taxableTransactions.length} transactions in ${year}`);

  // Export as JSON
  const report = {
    address,
    year,
    transactionCount: taxableTransactions.length,
    transactions: taxableTransactions
  };

  console.log(JSON.stringify(report, null, 2));
  return report;
};

generateTaxReport("86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY", 2024);
```

### Rastrear transacciones fallidas

Busca todas las transacciones fallidas para comprender los errores:

```javascript theme={"system"}
const getFailedTransactions = async (address) => {
  const data = await getTransactionHistory(address);

  const failed = data.data.filter(tx => tx.error !== null);

  console.log(`Found ${failed.length} failed transactions`);

  failed.forEach(tx => {
    const date = new Date(tx.timestamp * 1000).toLocaleString();
    console.log(`\n${date}`);
    console.log(`Signature: ${tx.signature}`);
    console.log(`Error: ${tx.error}`);
    console.log(`Fee Paid: ${tx.fee} SOL`);
  });

  return failed;
};
```

### Reconstruir un saldo histórico

Calcula cuál era el saldo en un momento específico:

```javascript theme={"system"}
const getHistoricalBalance = async (address, targetTimestamp) => {
  const transactions = await getAllTransactionHistory(address);

  // Filter to transactions before target date
  const relevantTxs = transactions.filter(tx => tx.timestamp <= targetTimestamp);

  // Sum all balance changes
  const balances = {};

  relevantTxs.forEach(tx => {
    tx.balanceChanges.forEach(change => {
      if (!balances[change.mint]) {
        balances[change.mint] = 0;
      }
      balances[change.mint] += change.amount;
    });
  });

  console.log(`Historical balances as of ${new Date(targetTimestamp * 1000).toLocaleString()}:`);
  Object.entries(balances).forEach(([mint, balance]) => {
    console.log(`${mint}: ${balance}`);
  });

  return balances;
};

// Example: Get balances on Jan 1, 2024
getHistoricalBalance(
  "86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY",
  new Date("2024-01-01").getTime() / 1000
);
```

Para obtener el saldo exacto de un solo token en un momento determinado, el endpoint [Historical Balance](/docs/es/wallet-api/balance-at) lo lee directamente de los saldos posteriores registrados on-chain, en lugar de sumar los cambios en el cliente.

### Analizar las comisiones de las transacciones

Calcula el total de comisiones pagadas:

```javascript theme={"system"}
const analyzeFees = async (address) => {
  const transactions = await getAllTransactionHistory(address);

  const totalFees = transactions.reduce((sum, tx) => sum + tx.fee, 0);
  const avgFee = totalFees / transactions.length;

  const successfulTxs = transactions.filter(tx => !tx.error);
  const failedTxs = transactions.filter(tx => tx.error);

  const wastedFees = failedTxs.reduce((sum, tx) => sum + tx.fee, 0);

  console.log(`Total Transactions: ${transactions.length}`);
  console.log(`Successful: ${successfulTxs.length}`);
  console.log(`Failed: ${failedTxs.length}`);
  console.log(`Total Fees Paid: ${totalFees.toFixed(6)} SOL`);
  console.log(`Average Fee: ${avgFee.toFixed(6)} SOL`);
  console.log(`Wasted on Failed Txs: ${wastedFees.toFixed(6)} SOL`);

  return {
    totalFees,
    avgFee,
    wastedFees,
    successRate: (successfulTxs.length / transactions.length) * 100
  };
};
```

## Prácticas recomendadas

* **Usa la paginación para obtener el historial completo.** Algunas billeteras tienen cientos de miles de transacciones. Siempre usa la paginación cuando las obtengas todas.
* **Almacena en caché los datos históricos.** Las transacciones históricas nunca cambian. Almacénalas localmente en caché y obtén solo las transacciones nuevas.
* **Gestiona las transacciones fallidas.** Consulta el campo `error` para distinguir las transacciones exitosas de las fallidas. Las transacciones fallidas también generan comisiones.
* **Usa marcas de tiempo para filtrar por fecha.** Las marcas de tiempo se expresan en segundos Unix. Conviértelas a fechas locales para mostrarlas y filtrarlas.

## Errores comunes

| Código de error | Descripción                                 | Solución                                                               |
| --------------- | ------------------------------------------- | ---------------------------------------------------------------------- |
| 400             | Formato de dirección de billetera no válido | Verifica que la dirección sea una dirección de Solana válida en base58 |
| 401             | Falta la clave de API o no es válida        | Comprueba que la clave de API esté incluida en la solicitud            |
| 429             | Se superó el límite de solicitudes          | Reduce la frecuencia de las solicitudes o mejora tu plan               |

## Próximos pasos

<CardGroup cols={3}>
  <Card title="Token Transfers" icon="arrow-right-arrow-left" href="/docs/es/wallet-api/transfers">
    Una vista exclusiva de transferencias con información del remitente y el destinatario, más sencilla que el historial completo.
  </Card>

  <Card title="Wallet API Overview" icon="wallet" href="/docs/es/wallet-api/overview">
    Todos los endpoints de la Wallet API y las convenciones compartidas.
  </Card>

  <Card title="API Reference" icon="code" href="/docs/es/api-reference/wallet-api/history">
    Esquemas de solicitud y respuesta para el historial de transacciones.
  </Card>
</CardGroup>
