
Представляем ускоренные вызовы getProgramAccounts (gPA)
Вызовы getProgramAccounts (gPA) печально известны своими проблемами. Этот метод RPC выполняет ресурсоёмкую и неэффективную операцию: обращается к ноде, чтобы получить все аккаунты, принадлежащие указанному публичному ключу. Такие вызовы часто работают медленно и имеют жёсткие ограничения по частоте запросов. Иногда они полностью запрещены (например, вызов gPA для программы Serum), если результаты ещё не кэшированы. Из-за этих проблем разработчикам приходилось искать трудоёмкие и менее эффективные альтернативы.
Сегодня всё меняется.
Helius представляет ускоренные вызовы getProgramAccounts для всех разработчиков Solana.
Что изменилось:
- Мы значительно улучшили индексацию аккаунтов
- Вызовы gPA теперь выполняются в 2–10 раз быстрее, особенно при использовании фильтров для крупных программ
- Мы автоматически индексируем программу после одного вызова от любого разработчика, что повышает производительность для всех
Начало работы
Чтобы начать, зарегистрируйтесь в панели разработчика Helius и получите ключ API в разделе «API Keys».
Пример getProgramAccounts
Запросим в JavaScript все аккаунты, принадлежащие программе Ore V2:
const url = `https://mainnet.helius-rpc.com/?api-key=<API_KEY>`;
const getProgramAccounts = async () => {
try {
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
jsonrpc: "2.0",
id: "test",
method: "getProgramAccounts",
params: [
"oreV2ZymfyeXgNgBdqMkumTqqAprVqgBWQfoYkrtKWQ",
{
"encoding": "base64",
},
],
})
});
const data = await response.json();
console.log(`All Accounts Owned By The Ore v2 Program: ${JSON.stringify(data, null, 2)}`);
} catch (error) {
console.error(error);
}
};
getProgramAccounts();Разберём, как работает этот код:
- Настройка URL: мы создаём URL, указывающий на конечную точку Helius RPC, и передаём наш ключ API
- Структура запроса RPC
- method: «
getProgramAccounts» указывает, что мы хотим запросить аккаунты, принадлежащие программе params— это массив из двух элементов: ID программы, которую мы хотим запросить (в данном случае программа Ore V2), и объект конфигурации запроса
- method: «
- Кодирование: мы запрашиваем данные аккаунта в кодировке base64
- Обработка ошибок: мы обрабатываем возникающие ошибки с помощью блока try/catch
При выполнении этого кода в консоль будут выведены все аккаунты, принадлежащие программе Ore V2.
Однако это базовый пример. Обычно стоит использовать фильтры, чтобы сузить результаты и повысить производительность.
Пример getProgramAccounts с фильтрами
Рассмотрим более практичный пример, в котором с помощью фильтров запрашиваются все токен-аккаунты, принадлежащие определённому адресу:
const url = `https://mainnet.helius-rpc.com/?api-key=<API_KEY>`;
const getTokenAccounts = async () => {
try {
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
jsonrpc: "2.0",
id: "token-accounts",
method: "getProgramAccounts",
params: [
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", // Token Program address
{
"encoding": "jsonParsed", // Get parsed token data
"filters": [
{
"dataSize": 165, // Size of token account data
},
{
"memcmp": {
"offset": 32, // Location of owner address in the token account
"bytes": "YOUR_WALLET_ADDRESS"
}
}
]
}
]
})
});
const data = await response.json();
data.result.forEach((account, i) => {
const parsed = account.account.data.parsed.info;
console.log(`-- Token Account ${i + 1}: ${account.pubkey} --`);
console.log(`Mint: ${parsed.mint}`);
console.log(`Amount: ${parsed.tokenAmount.uiAmount}`);
});
} catch (error) {
console.error("Error fetching token accounts:", error);
}
};
getTokenAccounts();Этот пример развивает базовый и демонстрирует два важных способа фильтрации: фильтры dataSize и memcmp.
dataSize
Фильтр dataSize проверяет точный размер данных указанного аккаунта. Нас интересуют токен-аккаунты размером 165 байт. Фильтр сразу исключит все остальные аккаунты указанного кошелька, которые не являются токен-аккаунтами.
Фильтр memcmp (сравнение памяти)
Фильтр memcmp, или фильтр сравнения памяти, позволяет сравнивать данные, хранящиеся в определённой области памяти. Смещение задаёт позицию, с которой начинается сравнение данных.
В нашем примере используется смещение 32, чтобы пропустить адрес минта, который хранится в первых 32 байтах памяти, поскольку нас интересует только адрес владельца. Этот фильтр вернёт только аккаунты, принадлежащие указанному адресу кошелька.
При выполнении этого кода в консоль будет выведен список всех токен-аккаунтов и их балансов для указанного адреса кошелька. Благодаря улучшенной индексации Helius такие отфильтрованные запросы выполняются значительно быстрее, чем у других традиционных провайдеров RPC.
Дополнительная помощь
Готовы избавиться от лишних сложностей и ускорить вызовы getProgramAccounts?
Зарегистрируйтесь в панели разработчика Helius и начните создавать более производительные приложения уже сегодня. Нужна помощь? Задайте вопрос или получите поддержку в Discord-сообществе Helius!
Если вы дочитали до этого места, спасибо, anon! Укажите свой адрес электронной почты ниже, чтобы не пропускать новости Solana. Хотите продолжить обучение? Читайте свежие статьи в нашем блоге и ускорьте своё знакомство с Solana.
Похожие статьи
Подпишитесь на Helius
Следите за новостями разработки на Solana и получайте уведомления о наших публикациях


