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

# getVoteAccounts

> Возвращает текущие голосующие счета

## Параметры

<ResponseField name="config" type="object" optional>
  Объект конфигурации, содержащий:

  <ResponseField name="commitment" type="string" optional>
    Уровень подтверждения (processed, confirmed, finalized)
  </ResponseField>

  <ResponseField name="votePubkey" type="string" optional>
    Открытый ключ конкретного голосующего счёта для запроса (в кодировке base-58)
  </ResponseField>

  <ResponseField name="keepUnstakedDelinquents" type="boolean" optional>
    Включать ли нестейкинговые просроченные голосующие счета
  </ResponseField>

  <ResponseField name="delinquentSlotDistance" type="number" optional>
    Максимальное расстояние слота для признания голосующего счёта просроченным
  </ResponseField>
</ResponseField>

## Ответ

<ResponseField name="result" type="object">
  Объект, содержащий:

  <ResponseField name="current" type="array">
    Массив текущих объектов голосующих счетов, содержащих:

    <ResponseField name="votePubkey" type="string">
      Открытый ключ голосующего счёта (в кодировке base-58)
    </ResponseField>

    <ResponseField name="nodePubkey" type="string">
      Открытый ключ валидатора (в кодировке base-58)
    </ResponseField>

    <ResponseField name="activatedStake" type="number">
      Размер активированного стейка в lamports
    </ResponseField>

    <ResponseField name="epochVoteAccount" type="boolean">
      Голосовал ли счёт в текущей эпохе
    </ResponseField>

    <ResponseField name="epochCredits" type="array">
      Массив объектов кредитов эпохи, содержащих:

      <ResponseField name="epoch" type="number">
        Номер эпохи
      </ResponseField>

      <ResponseField name="credits" type="number">
        Количество заработанных кредитов
      </ResponseField>

      <ResponseField name="previousCredits" type="number">
        Количество кредитов в предыдущей эпохе
      </ResponseField>
    </ResponseField>

    <ResponseField name="lastVote" type="number">
      Слот последнего голосования
    </ResponseField>

    <ResponseField name="rootSlot" type="number" optional>
      Корневой слот
    </ResponseField>
  </ResponseField>

  <ResponseField name="delinquent" type="array">
    Массив просроченных голосующих счетов с такой же структурой, как и current
  </ResponseField>
</ResponseField>

## Примеры кода

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

```bash theme={null}
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": "getVoteAccounts"
}'
```

### Использование web3.js

```typescript theme={null}
import { Connection } from '@solana/web3.js';

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

// Get vote accounts
const voteAccounts = await connection.getVoteAccounts();
console.log('Vote accounts:', voteAccounts);

// Get vote accounts with analysis
async function getVoteAccountsWithAnalysis(
  config: { 
    commitment?: string;
    votePubkey?: string;
    keepUnstakedDelinquents?: boolean;
    delinquentSlotDistance?: number;
  }
) {
  const voteAccounts = await connection.getVoteAccounts(config);
  
  return {
    voteAccounts,
    analysis: {
      current: {
        count: voteAccounts.current.length,
        totalStake: voteAccounts.current.reduce((sum, acc) => sum + acc.activatedStake, 0),
        averageStake: voteAccounts.current.reduce((sum, acc) => sum + acc.activatedStake, 0) / voteAccounts.current.length,
        activeVoters: voteAccounts.current.filter(acc => acc.epochVoteAccount).length
      },
      delinquent: {
        count: voteAccounts.delinquent.length,
        totalStake: voteAccounts.delinquent.reduce((sum, acc) => sum + acc.activatedStake, 0),
        averageStake: voteAccounts.delinquent.reduce((sum, acc) => sum + acc.activatedStake, 0) / voteAccounts.delinquent.length,
        activeVoters: voteAccounts.delinquent.filter(acc => acc.epochVoteAccount).length
      },
      metadata: {
        timestamp: Date.now(),
        commitment: config.commitment
      }
    }
  };
}
```

## Примечания

1. Возвращает текущие голосующие счета
2. Ответ включает как текущие, так и просроченные голосующие счета
3. Ответ приходит немедленно, так как читается из текущего состояния
4. Счета могут изменяться при изменении стейка и голосовании
5. Голосующие счета должны быть действительными

## Рекомендации

1. Используйте подходящий уровень подтверждения в зависимости от ваших потребностей
2. Кэшируйте результаты там, где это уместно, для снижения нагрузки на RPC
3. Отслеживайте изменения в голосующих счетах
4. Рассмотрите использование подписки на websocket для обновлений в реальном времени
5. Обрабатывайте сетевые ошибки и выполняйте повторные попытки при необходимости

## Распространённые ошибки

| Код    | Сообщение              | Решение                                        |
| ------ | ---------------------- | ---------------------------------------------- |
| -32601 | Method not found       | Убедитесь, что вы подключены к узлу Solana RPC |
| -32602 | Invalid params         | Проверьте параметры конфигурации               |
| -32007 | Vote account not found | Убедитесь, что голосующий счёт существует      |

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

1. **Анализ голосующих счетов**
   ```typescript theme={null}
   interface VoteAccountAnalysis {
     accounts: {
       current: Array<{
         votePubkey: string;
         nodePubkey: string;
         activatedStake: number;
         epochVoteAccount: boolean;
         lastVote: number;
         rootSlot?: number;
       }>;
       delinquent: Array<{
         votePubkey: string;
         nodePubkey: string;
         activatedStake: number;
         epochVoteAccount: boolean;
         lastVote: number;
         rootSlot?: number;
       }>;
     };
     metrics: {
       current: {
         count: number;
         totalStake: number;
         averageStake: number;
         activeVoters: number;
         participationRate: number;
       };
       delinquent: {
         count: number;
         totalStake: number;
         averageStake: number;
         activeVoters: number;
         participationRate: number;
       };
     };
     metadata: {
       timestamp: number;
       commitment?: string;
     };
   }

   class VoteAccountAnalyzer {
     async analyzeVoteAccounts(
       config: { 
         commitment?: string;
         votePubkey?: string;
         keepUnstakedDelinquents?: boolean;
         delinquentSlotDistance?: number;
       }
     ): Promise<VoteAccountAnalysis> {
       const voteAccounts = await connection.getVoteAccounts(config);
       
       return {
         accounts: {
           current: voteAccounts.current.map(acc => ({
             votePubkey: acc.votePubkey,
             nodePubkey: acc.nodePubkey,
             activatedStake: acc.activatedStake,
             epochVoteAccount: acc.epochVoteAccount,
             lastVote: acc.lastVote,
             rootSlot: acc.rootSlot
           })),
           delinquent: voteAccounts.delinquent.map(acc => ({
             votePubkey: acc.votePubkey,
             nodePubkey: acc.nodePubkey,
             activatedStake: acc.activatedStake,
             epochVoteAccount: acc.epochVoteAccount,
             lastVote: acc.lastVote,
             rootSlot: acc.rootSlot
           }))
         },
         metrics: {
           current: {
             count: voteAccounts.current.length,
             totalStake: voteAccounts.current.reduce((sum, acc) => sum + acc.activatedStake, 0),
             averageStake: voteAccounts.current.reduce((sum, acc) => sum + acc.activatedStake, 0) / voteAccounts.current.length,
             activeVoters: voteAccounts.current.filter(acc => acc.epochVoteAccount).length,
             participationRate: voteAccounts.current.filter(acc => acc.epochVoteAccount).length / voteAccounts.current.length
           },
           delinquent: {
             count: voteAccounts.delinquent.length,
             totalStake: voteAccounts.delinquent.reduce((sum, acc) => sum + acc.activatedStake, 0),
             averageStake: voteAccounts.delinquent.reduce((sum, acc) => sum + acc.activatedStake, 0) / voteAccounts.delinquent.length,
             activeVoters: voteAccounts.delinquent.filter(acc => acc.epochVoteAccount).length,
             participationRate: voteAccounts.delinquent.filter(acc => acc.epochVoteAccount).length / voteAccounts.delinquent.length
           }
         },
         metadata: {
           timestamp: Date.now(),
           commitment: config.commitment
         }
       };
     }
   }
   ```

2. **Мониторинг голосующих счетов**
   ```typescript theme={null}
   interface VoteAccountChange {
     changes: {
       current: Array<{
         type: 'added' | 'removed' | 'modified';
         votePubkey: string;
         previousStake?: number;
         currentStake?: number;
         previousVote?: boolean;
         currentVote?: boolean;
       }>;
       delinquent: Array<{
         type: 'added' | 'removed' | 'modified';
         votePubkey: string;
         previousStake?: number;
         currentStake?: number;
         previousVote?: boolean;
         currentVote?: boolean;
       }>;
     };
     metadata: {
       timestamp: number;
     };
   }

   class VoteAccountMonitor {
     private previousAccounts: {
       current: Map<string, {
         stake: number;
         vote: boolean;
       }>;
       delinquent: Map<string, {
         stake: number;
         vote: boolean;
       }>;
     } = {
       current: new Map(),
       delinquent: new Map()
     };
     
     async monitorVoteAccounts(
       config: { 
         commitment?: string;
         votePubkey?: string;
         keepUnstakedDelinquents?: boolean;
         delinquentSlotDistance?: number;
       }
     ): Promise<VoteAccountChange | null> {
       const voteAccounts = await connection.getVoteAccounts(config);
       
       const changes: {
         current: Array<{
           type: 'added' | 'removed' | 'modified';
           votePubkey: string;
           previousStake?: number;
           currentStake?: number;
           previousVote?: boolean;
           currentVote?: boolean;
         }>;
         delinquent: Array<{
           type: 'added' | 'removed' | 'modified';
           votePubkey: string;
           previousStake?: number;
           currentStake?: number;
           previousVote?: boolean;
           currentVote?: boolean;
         }>;
       } = {
         current: [],
         delinquent: []
       };
       
       // Check current accounts
       this.checkAccountChanges(
         voteAccounts.current,
         this.previousAccounts.current,
         changes.current
       );
       
       // Check delinquent accounts
       this.checkAccountChanges(
         voteAccounts.delinquent,
         this.previousAccounts.delinquent,
         changes.delinquent
       );
       
       // Update previous accounts
       this.previousAccounts.current = new Map(
         voteAccounts.current.map(acc => [
           acc.votePubkey,
           {
             stake: acc.activatedStake,
             vote: acc.epochVoteAccount
           }
         ])
       );
       
       this.previousAccounts.delinquent = new Map(
         voteAccounts.delinquent.map(acc => [
           acc.votePubkey,
           {
             stake: acc.activatedStake,
             vote: acc.epochVoteAccount
           }
         ])
       );
       
       if (changes.current.length > 0 || changes.delinquent.length > 0) {
         return {
           changes,
           metadata: {
             timestamp: Date.now()
           }
         };
       }
       
       return null;
     }
     
     private checkAccountChanges(
       currentAccounts: Array<{
         votePubkey: string;
         activatedStake: number;
         epochVoteAccount: boolean;
       }>,
       previousAccounts: Map<string, {
         stake: number;
         vote: boolean;
       }>,
       changes: Array<{
         type: 'added' | 'removed' | 'modified';
         votePubkey: string;
         previousStake?: number;
         currentStake?: number;
         previousVote?: boolean;
         currentVote?: boolean;
       }>
     ) {
       // Check for removed or modified accounts
       previousAccounts.forEach((data, votePubkey) => {
         const current = currentAccounts.find(acc => acc.votePubkey === votePubkey);
         
         if (!current) {
           changes.push({
             type: 'removed',
             votePubkey,
             previousStake: data.stake,
             previousVote: data.vote
           });
         } else if (
           current.activatedStake !== data.stake ||
           current.epochVoteAccount !== data.vote
         ) {
           changes.push({
             type: 'modified',
             votePubkey,
             previousStake: data.stake,
             currentStake: current.activatedStake,
             previousVote: data.vote,
             currentVote: current.epochVoteAccount
           });
         }
       });
       
       // Check for added accounts
       currentAccounts.forEach(account => {
         if (!previousAccounts.has(account.votePubkey)) {
           changes.push({
             type: 'added',
             votePubkey: account.votePubkey,
             currentStake: account.activatedStake,
             currentVote: account.epochVoteAccount
           });
         }
       });
     }
   }
   ```

3. **Планирование голосующих счетов**
   ```typescript theme={null}
   interface VoteAccountPlan {
     accounts: {
       current: Array<{
         votePubkey: string;
         nodePubkey: string;
         activatedStake: number;
         epochVoteAccount: boolean;
       }>;
       delinquent: Array<{
         votePubkey: string;
         nodePubkey: string;
         activatedStake: number;
         epochVoteAccount: boolean;
       }>;
     };
     recommendations: Array<{
       type: 'stake' | 'unstake' | 'monitor';
       votePubkey: string;
       reason: string;
     }>;
     metadata: {
       timestamp: number;
     };
   }

   class VoteAccountPlanner {
     private readonly minStake = 1000000000; // 1 SOL
     private readonly maxDelinquentVotes = 3;
     
     async planVoteAccounts(
       config: { 
         commitment?: string;
         votePubkey?: string;
         keepUnstakedDelinquents?: boolean;
         delinquentSlotDistance?: number;
       }
     ): Promise<VoteAccountPlan> {
       const voteAccounts = await connection.getVoteAccounts(config);
       
       const recommendations: Array<{
         type: 'stake' | 'unstake' | 'monitor';
         votePubkey: string;
         reason: string;
       }> = [];
       
       // Check current accounts
       voteAccounts.current.forEach(account => {
         if (account.activatedStake < this.minStake) {
           recommendations.push({
             type: 'stake',
             votePubkey: account.votePubkey,
             reason: `Account has low stake (${account.activatedStake})`
           });
         }
         
         if (!account.epochVoteAccount) {
           recommendations.push({
             type: 'monitor',
             votePubkey: account.votePubkey,
             reason: 'Account not voting in current epoch'
           });
         }
       });
       
       // Check delinquent accounts
       voteAccounts.delinquent.forEach(account => {
         if (account.activatedStake > 0) {
           recommendations.push({
             type: 'unstake',
             votePubkey: account.votePubkey,
             reason: 'Account is delinquent with stake'
           });
         }
       });
       
       return {
         accounts: {
           current: voteAccounts.current.map(acc => ({
             votePubkey: acc.votePubkey,
             nodePubkey: acc.nodePubkey,
             activatedStake: acc.activatedStake,
             epochVoteAccount: acc.epochVoteAccount
           })),
           delinquent: voteAccounts.delinquent.map(acc => ({
             votePubkey: acc.votePubkey,
             nodePubkey: acc.nodePubkey,
             activatedStake: acc.activatedStake,
             epochVoteAccount: acc.epochVoteAccount
           }))
         },
         recommendations,
         metadata: {
           timestamp: Date.now()
         }
       };
     }
   }
   ```
