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

# Wallet Activity

> Query deposit and withdrawal history for any wallet address.

<Note>
  All requests require an API key via the `X-API-Key` header.
  See [Authentication](/sdk/authentication/api-keys) for details.
</Note>

## Overview

The Wallet Activity endpoint returns on-chain earn interactions (deposits and withdrawals) for one or more wallet addresses across all opportunities and distributors. Results are ordered by date descending.

This is a **wallet-scoped** endpoint. For distributor-scoped activity, see [Distributor Activity](/sdk/earn-api/deposits).

## Endpoint

### Get Wallet Activity

<CodeGroup>
  ```bash curl theme={null}
  curl "https://earn.turtle.xyz/v1/wallets/activity?addresses=0x3191F53d4d652F9cF37F74c554070d95e710c07f&page=1&limit=20" \
    -H "X-API-Key: pk_live_xxxxx"
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch(
    'https://earn.turtle.xyz/v1/wallets/activity?addresses=0x3191F53d4d652F9cF37F74c554070d95e710c07f&page=1&limit=20',
    { headers: { 'X-API-Key': 'pk_live_xxxxx' } }
  );
  const data = await response.json();
  ```
</CodeGroup>

**Query Parameters**

<ParamField query="addresses" type="string" required>
  Comma-separated list of EVM wallet addresses. Maximum 1000 addresses per request. Addresses are case-insensitive.
</ParamField>

<ParamField query="page" type="integer" default="1">
  Page number for pagination.
</ParamField>

<ParamField query="limit" type="integer" default="20">
  Results per page (max: 100).
</ParamField>

<Warning>
  This is a GET endpoint. Do not send a request body — it will return an error.
</Warning>

**Response**

```json theme={null}
{
  "activity": [
    {
      "id": "uuid",
      "opportunityId": "uuid",
      "interaction": "deposit",
      "txHash": "0xabc...",
      "chainId": 1,
      "blockTimestamp": "2024-11-01T12:00:00Z",
      "walletAddress": "0xabc...",
      "amountToken": "100.00",
      "amountInUsd": "99.50",
      "tokenSymbol": "USDC",
      "tokenIconUrl": "https://...",
      "isSwap": false
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 42,
    "totalPages": 3,
    "hasNext": true,
    "hasPrevious": false
  }
}
```

**Activity Object**

<ParamField body="id" type="string">
  Unique identifier for the interaction.
</ParamField>

<ParamField body="opportunityId" type="string">
  The opportunity this interaction belongs to.
</ParamField>

<ParamField body="interaction" type="string">
  Type of interaction: `deposit` or `withdraw`.
</ParamField>

<ParamField body="txHash" type="string">
  On-chain transaction hash.
</ParamField>

<ParamField body="chainId" type="integer">
  Chain ID where the transaction occurred.
</ParamField>

<ParamField body="blockTimestamp" type="string">
  ISO 8601 timestamp of the on-chain transaction.
</ParamField>

<ParamField body="walletAddress" type="string">
  The wallet address that performed the interaction.
</ParamField>

<ParamField body="amountToken" type="string">
  Human-readable token amount (already adjusted for decimals). Present when available.
</ParamField>

<ParamField body="amountInUsd" type="string">
  USD value of the interaction at time of transaction. Present when available.
</ParamField>

<ParamField body="tokenSymbol" type="string">
  Symbol of the deposited or withdrawn token. Present when available.
</ParamField>

<ParamField body="tokenIconUrl" type="string">
  URL to the token icon. Present when available.
</ParamField>

<ParamField body="isSwap" type="boolean">
  Whether the deposit used swap mode.
</ParamField>

## Use Cases

### Display Wallet Transaction History

Build a transaction history view for a user's portfolio page.

```typescript theme={null}
const getWalletHistory = async (walletAddress: string) => {
  const response = await fetch(
    `https://earn.turtle.xyz/v1/wallets/activity?addresses=${walletAddress}&limit=50`,
    { headers: { 'X-API-Key': 'pk_live_xxxxx' } }
  );
  const { activity, pagination } = await response.json();

  return { activity, pagination };
};
```

### Query Multiple Wallets

Fetch activity across multiple wallets in a single request — useful for users with multiple addresses or for building aggregate views.

```typescript theme={null}
const addresses = [
  '0x3191F53d4d652F9cF37F74c554070d95e710c07f',
  '0xa1E7Db8d88BEd2bA0bEFb9bda654b98631c4b305'
].join(',');

const response = await fetch(
  `https://earn.turtle.xyz/v1/wallets/activity?addresses=${addresses}&page=1&limit=100`,
  { headers: { 'X-API-Key': 'pk_live_xxxxx' } }
);
const { activity } = await response.json();
```

### Paginate Through All Results

```typescript theme={null}
const getAllActivity = async (walletAddress: string) => {
  let page = 1;
  let allActivity = [];

  while (true) {
    const response = await fetch(
      `https://earn.turtle.xyz/v1/wallets/activity?addresses=${walletAddress}&page=${page}&limit=100`,
      { headers: { 'X-API-Key': 'pk_live_xxxxx' } }
    );
    const { activity, pagination } = await response.json();
    allActivity.push(...activity);

    if (!pagination.hasNext) break;
    page++;
  }

  return allActivity;
};
```

## Wallet Activity vs Distributor Activity

|                  | Wallet Activity                | [Distributor Activity](/sdk/earn-api/deposits) |
| ---------------- | ------------------------------ | ---------------------------------------------- |
| **Endpoint**     | `GET /v1/wallets/activity`     | `GET /v1/deposit/{distributor_id}`             |
| **Scoped by**    | Wallet address(es)             | Distributor ID                                 |
| **Interactions** | Deposits + withdrawals         | Deposits only                                  |
| **Best for**     | Portfolio UIs, user dashboards | Distributor attribution tracking               |
| **Pagination**   | Page-based (`page`, `hasNext`) | Offset-based (`offset`, `limit`)               |

## Error Handling

<AccordionGroup>
  <Accordion title="Missing Addresses">
    **Status Code:** 400 Bad Request

    ```json theme={null}
    {
      "error": {
        "status": "INVALID_ARGUMENT",
        "error": "addresses parameter is required"
      }
    }
    ```

    **Solution:** Include at least one valid EVM address in the `addresses` query parameter.
  </Accordion>

  <Accordion title="Too Many Addresses">
    **Status Code:** 400 Bad Request

    ```json theme={null}
    {
      "error": {
        "status": "INVALID_ARGUMENT",
        "error": "maximum 1000 addresses per request"
      }
    }
    ```

    **Solution:** Split your request into batches of 1000 addresses or fewer.
  </Accordion>

  <Accordion title="Request Body Sent">
    **Status Code:** 400 Bad Request

    **Solution:** This is a GET endpoint. Remove any request body and pass parameters via the query string only.
  </Accordion>
</AccordionGroup>
