Перейти к основному содержанию

Обзор

getTransactionsForAddress объединяет поиск сигнатур транзакций и полное получение транзакций в один эффективный вызов. Вместо отдельных запросов к getSignaturesForAddress и затем getTransaction для каждой сигнатуры вы получаете всё в одном запросе. Этот метод поддерживает:
  • Двунаправленную сортировку (от старых к новым или от новых к старым)
  • Фильтрацию по времени и слоту
  • Фильтрацию по статусу транзакций (успешные/неудачные)
  • Фильтрацию по токен-аккаунтам
  • Пагинацию на основе курсора

Зачем использовать этот метод

Проблема N+1

При использовании стандартных методов Solana RPC получение истории транзакций требует нескольких вызовов:
  1. Вызвать getSignaturesForAddress для получения списка сигнатур транзакций
  2. Вызвать getTransaction для каждой сигнатуры для получения полных данных транзакции
Для кошелька со 100 транзакциями это 101 вызов API. Для 1000 транзакций — 1001 вызов. Это создаёт задержку, сложность и более высокие расходы. getTransactionsForAddress решает эту проблему, возвращая полные данные транзакций в одном вызове — до 100 полных транзакций или 1000 сигнатур за запрос.

Дополнительные возможности

Помимо эффективности, этот метод предоставляет функции, недоступные в стандартном RPC:
  • Двунаправленная сортировка: Запрос от старых к новым (asc) для отслеживания адреса с первой транзакции
  • Фильтрация по времени: Получение транзакций в определённом диапазоне дат
  • Фильтрация по слоту: Запрос транзакций из конкретных диапазонов блоков
  • Фильтрация по статусу: Получение только успешных или только неудачных транзакций
  • Включение токен-аккаунтов: Захват транзакций из связанных токен-аккаунтов

Поддержка токен-аккаунтов

Стандартный getSignaturesForAddress возвращает только транзакции, непосредственно ссылающиеся на запрашиваемый адрес. Это упускает важную категорию: переводы токенов. При отправке токенов на кошелёк транзакция ссылается на Associated Token Account (ATA) кошелька, а не на сам адрес кошелька. Это означает, что стандартные методы дают неполную картину. getTransactionsForAddress с tokenAccounts: "all" автоматически включает транзакции из всех токен-аккаунтов, принадлежащих адресу, предоставляя полную историю транзакций.
curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getTransactionsForAddress",
  "params": [
    "WALLET_ADDRESS",
    {
      "filters": {
        "tokenAccounts": "all"
      }
    }
  ]
}'
Установите tokenAccounts: "none", если вам нужны только транзакции, непосредственно ссылающиеся на адрес.

Параметры

address
string
обязательно
Адрес Solana для запроса (публичный ключ в кодировке base-58)
options
object

Ответ

Формат ответа зависит от параметра transactionDetails.

С transactionDetails: "full"

result
array
Массив объектов полных транзакций, каждый содержит:

С transactionDetails: "signatures"

result
array
Массив объектов сигнатур, каждый содержит:

Примеры кода

Базовый запрос

Получить последние транзакции для адреса:
curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getTransactionsForAddress",
  "params": [
    "ADDRESS_HERE"
  ]
}'

Получить только сигнатуры

Получить до 1000 сигнатур без полных данных транзакций:
curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getTransactionsForAddress",
  "params": [
    "ADDRESS_HERE",
    {
      "transactionDetails": "signatures",
      "limit": 1000
    }
  ]
}'

От старых к новым с фильтром по времени

Получить транзакции в определённом временном диапазоне, отсортированные от старых к новым:
curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getTransactionsForAddress",
  "params": [
    "ADDRESS_HERE",
    {
      "sortOrder": "asc",
      "filters": {
        "afterTime": 1704067200,
        "beforeTime": 1706745600
      }
    }
  ]
}'

Только успешные транзакции

Фильтровать только успешные транзакции:
curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getTransactionsForAddress",
  "params": [
    "ADDRESS_HERE",
    {
      "filters": {
        "status": "success"
      }
    }
  ]
}'

Запрос с пагинацией

Использовать пагинацию на основе курсора для получения большего количества результатов:
curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getTransactionsForAddress",
  "params": [
    "ADDRESS_HERE",
    {
      "limit": 100,
      "before": "LAST_SIGNATURE_FROM_PREVIOUS_RESPONSE"
    }
  ]
}'

Пример на TypeScript

import { Connection } from '@solana/web3.js';

const connection = new Connection('https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY');

interface GetTransactionsOptions {
  transactionDetails?: 'full' | 'signatures';
  limit?: number;
  sortOrder?: 'asc' | 'desc';
  before?: string;
  after?: string;
  filters?: {
    tokenAccounts?: 'all' | 'none';
    beforeTime?: number;
    afterTime?: number;
    beforeSlot?: number;
    afterSlot?: number;
    status?: 'success' | 'failed';
  };
}

async function getTransactionsForAddress(
  address: string,
  options: GetTransactionsOptions = {}
) {
  const response = await fetch('https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: 1,
      method: 'getTransactionsForAddress',
      params: [address, options],
    }),
  });

  const data = await response.json();
  return data.result;
}

// Get recent transactions
const recent = await getTransactionsForAddress('ADDRESS_HERE');

// Get oldest transactions first with time filter
const historical = await getTransactionsForAddress('ADDRESS_HERE', {
  sortOrder: 'asc',
  filters: {
    afterTime: Math.floor(Date.now() / 1000) - 86400 * 30, // Last 30 days
  },
});

// Paginate through all transactions
async function getAllTransactions(address: string) {
  const allTransactions = [];
  let before: string | undefined;

  while (true) {
    const batch = await getTransactionsForAddress(address, {
      limit: 100,
      before,
    });

    if (!batch || batch.length === 0) break;

    allTransactions.push(...batch);
    before = batch[batch.length - 1].signature;
  }

  return allTransactions;
}

Сценарии использования

Анализ запуска токена

Найти самые ранние транзакции для минта токена, чтобы определить первых минтеров и ранних держателей. Используйте sortOrder: "asc" для начала с самого начала:
const earlyActivity = await getTransactionsForAddress(tokenMintAddress, {
  sortOrder: 'asc',
  limit: 100,
  filters: {
    tokenAccounts: 'all',
  },
});

История пополнения кошелька

Отследить источники средств кошелька, запросив его полную историю транзакций:
const fundingHistory = await getTransactionsForAddress(walletAddress, {
  sortOrder: 'asc',
  filters: {
    tokenAccounts: 'all',
  },
  transactionDetails: 'full',
});

// First transactions often reveal funding sources
const firstTransactions = fundingHistory.slice(0, 10);

Анализ неудачных транзакций

Отладка сбоев транзакций путём фильтрации только неудачных транзакций:
const failedTxs = await getTransactionsForAddress(walletAddress, {
  filters: {
    status: 'failed',
  },
  transactionDetails: 'full',
});

// Analyze error logs to understand failure reasons
failedTxs.forEach(tx => {
  console.log(tx.signature, tx.meta?.err, tx.meta?.logMessages);
});

Лента транзакций кошелька

Создать пагинированную историю транзакций для UI кошелька:
async function getWalletFeed(wallet: string, cursor?: string) {
  return getTransactionsForAddress(wallet, {
    limit: 20,
    before: cursor,
    transactionDetails: 'full',
    filters: {
      tokenAccounts: 'all',
    },
  });
}

Анализ торговых паттернов

Фильтровать успешные сделки в определённом временном окне:
const trades = await getTransactionsForAddress(traderWallet, {
  filters: {
    status: 'success',
    afterTime: startOfMonth,
    beforeTime: endOfMonth,
  },
  transactionDetails: 'full',
});

Аудит для комплаенса

Построить полную историю транзакций для регуляторного комплаенса:
async function auditAddress(address: string) {
  const allTxs = await getAllTransactions(address);

  return {
    totalTransactions: allTxs.length,
    successful: allTxs.filter(tx => !tx.err).length,
    failed: allTxs.filter(tx => tx.err).length,
    firstTransaction: allTxs[allTxs.length - 1],
    lastTransaction: allTxs[0],
  };
}

Пагинация

Для адресов с большим количеством транзакций необходимо использовать пагинацию. Метод поддерживает пагинацию на основе курсора с параметрами before и after.

Получение новых транзакций (по умолчанию)

С sortOrder: "desc" (по умолчанию) транзакции возвращаются от новых к старым. Используйте before для получения более старых транзакций:
// First request
const page1 = await getTransactionsForAddress(address, { limit: 100 });

// Get next page using last signature as cursor
const lastSignature = page1[page1.length - 1].signature;
const page2 = await getTransactionsForAddress(address, {
  limit: 100,
  before: lastSignature,
});

Получение старых транзакций первыми

С sortOrder: "asc" транзакции возвращаются от старых к новым. Используйте after для получения более новых транзакций:
// Get oldest transactions first
const page1 = await getTransactionsForAddress(address, {
  sortOrder: 'asc',
  limit: 100,
});

// Continue forward in time
const lastSignature = page1[page1.length - 1].signature;
const page2 = await getTransactionsForAddress(address, {
  sortOrder: 'asc',
  limit: 100,
  after: lastSignature,
});

Полный пример пагинации

Получить все транзакции для адреса:
async function getAllTransactions(address: string) {
  const allTransactions = [];
  let cursor: string | undefined;

  while (true) {
    const batch = await getTransactionsForAddress(address, {
      limit: 100,
      before: cursor,
      transactionDetails: 'full',
    });

    if (!batch || batch.length === 0) break;

    allTransactions.push(...batch);
    cursor = batch[batch.length - 1].signature;

    // Optional: Add delay to respect rate limits
    await new Promise(resolve => setTimeout(resolve, 100));
  }

  return allTransactions;
}

Лучшие практики

  1. Используйте режим signatures для подсчёта: Когда вам нужно только подсчитать или перечислить транзакции, используйте transactionDetails: "signatures" для лучшей производительности и более высоких лимитов.
  2. Фильтруйте заранее: Применяйте фильтры по времени, слоту или статусу для сокращения объёма возвращаемых данных и улучшения времени ответа.
  3. Реализуйте пагинацию: Для адресов с большим количеством транзакций всегда используйте пагинацию с курсором before.
  4. Кешируйте результаты: Данные транзакций неизменяемы после подтверждения. Кешируйте исторические результаты, чтобы избежать избыточных запросов.
  5. Обрабатывайте лимиты: Реализуйте экспоненциальную задержку при выполнении множества последовательных запросов.

Частые ошибки

КодСообщениеРешение
-32600Неверный запросПроверьте формат JSON-RPC и обязательные поля
-32602Неверные параметрыПроверьте формат адреса и значения параметров
-32005Превышен лимит запросовУменьшите лимит или реализуйте ограничение скорости

Сравнение со стандартными методами

ФункцияgetSignaturesForAddress + getTransactiongetTransactionsForAddress
Вызовы APIНесколько (1 + N)Один
СортировкаТолько от новых к старымДвунаправленная
Фильтрация по времениНе поддерживаетсяПоддерживается
Фильтрация по статусуНе поддерживаетсяПоддерживается
Макс. сигнатур1000 за вызов1000 за вызов
Макс. полных транзакцийОграничено вызовами100 за вызов