> ## 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.

# getTokenAccountsByDelegate

> Возвращает все токеновые счета для заданного делегата

## Параметры

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

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

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

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

  <ResponseField name="encoding" type="string" optional>
    Кодирование данных счёта (base58, base64, jsonParsed)
  </ResponseField>

  <ResponseField name="dataSlice" type="object" optional>
    <ResponseField name="offset" type="number">
      Смещение в данных счёта
    </ResponseField>

    <ResponseField name="length" type="number">
      Длина возвращаемых данных
    </ResponseField>
  </ResponseField>
</ResponseField>

## Ответ

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

  <ResponseField name="context" type="object">
    <ResponseField name="slot" type="number">
      Слот, в котором был обработан запрос
    </ResponseField>
  </ResponseField>

  <ResponseField name="value" type="array">
    Массив объектов токеновых счетов, содержащих:

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

    <ResponseField name="account" type="object">
      <ResponseField name="lamports" type="number">
        Количество lamports на счёте
      </ResponseField>

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

      <ResponseField name="executable" type="boolean">
        Является ли счёт исполняемым
      </ResponseField>

      <ResponseField name="rentEpoch" type="number">
        Эпоха, в которую счёт должен будет оплатить аренду следующий раз
      </ResponseField>

      <ResponseField name="data" type="object">
        <ResponseField name="parsed" type="object">
          <ResponseField name="info" type="object">
            <ResponseField name="tokenAmount" type="object">
              <ResponseField name="amount" type="string">
                Необработанное количество токенов в виде строки
              </ResponseField>

              <ResponseField name="decimals" type="number">
                Количество десятичных знаков, настроенных для монетного двора токена
              </ResponseField>

              <ResponseField name="uiAmount" type="number" optional>
                Количество токенов в виде числа с плавающей точкой с учётом десятичных знаков
              </ResponseField>

              <ResponseField name="uiAmountString" type="string" optional>
                Количество токенов в виде строки с учётом десятичных знаков
              </ResponseField>
            </ResponseField>

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

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

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

          <ResponseField name="type" type="string">
            Тип счёта (account)
          </ResponseField>
        </ResponseField>

        <ResponseField name="program" type="string">
          Программа, владеющая счётом (spl-token)
        </ResponseField>

        <ResponseField name="space" type="number">
          Количество байтов, выделенных для счёта
        </ResponseField>
      </ResponseField>
    </ResponseField>
  </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": "getTokenAccountsByDelegate",
  "params": [
    "4vJ9JU1bJJE96FWSJKvHsmmFADCg4gpZQff4P3bkLZj",
    {
      "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
    }
  ]
}'
```

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

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

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

// Get token accounts by delegate
const delegate = new PublicKey('4vJ9JU1bJJE96FWSJKvHsmmFADCg4gpZQff4P3bkLZj');
const programId = new PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA');
const accounts = await connection.getTokenAccountsByDelegate(delegate, { programId });
console.log('Token accounts:', accounts);

// Get token accounts by delegate with analysis
async function getTokenAccountsByDelegateWithAnalysis(
  delegate: PublicKey,
  config: { programId: PublicKey; commitment?: string }
) {
  const accounts = await connection.getTokenAccountsByDelegate(delegate, config);
  
  return {
    accounts,
    analysis: {
      totalAccounts: accounts.value.length,
      totalBalance: accounts.value.reduce((sum, acc) => {
        const amount = BigInt(acc.account.data.parsed.info.tokenAmount.amount);
        return sum + amount;
      }, BigInt(0)),
      byMint: accounts.value.reduce((acc, account) => {
        const mint = account.account.data.parsed.info.mint;
        const amount = BigInt(account.account.data.parsed.info.tokenAmount.amount);
        acc[mint] = (acc[mint] || BigInt(0)) + amount;
        return acc;
      }, {} as Record<string, bigint>),
      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 | Delegate not found | Убедитесь, что делегат существует               |
| -32008 | Invalid program ID | Проверьте корректность ID программы             |

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

1. **Анализ счетов делегата**
   ```typescript theme={null}
   interface DelegateAccountAnalysis {
     delegate: string;
     accounts: Array<{
       pubkey: string;
       mint: string;
       balance: string;
       owner: string;
     }>;
     metrics: {
       totalAccounts: number;
       totalBalance: string;
       byMint: Record<string, string>;
       byOwner: Record<string, number>;
     };
     metadata: {
       timestamp: number;
       commitment?: string;
     };
   }

   class DelegateAccountAnalyzer {
     async analyzeDelegateAccounts(
       delegate: PublicKey,
       config: { programId: PublicKey; commitment?: string }
     ): Promise<DelegateAccountAnalysis> {
       const accounts = await connection.getTokenAccountsByDelegate(delegate, config);
       
       const byMint: Record<string, bigint> = {};
       const byOwner: Record<string, number> = {};
       let totalBalance = BigInt(0);
       
       accounts.value.forEach(account => {
         const mint = account.account.data.parsed.info.mint;
         const owner = account.account.data.parsed.info.owner;
         const amount = BigInt(account.account.data.parsed.info.tokenAmount.amount);
         
         byMint[mint] = (byMint[mint] || BigInt(0)) + amount;
         byOwner[owner] = (byOwner[owner] || 0) + 1;
         totalBalance += amount;
       });
       
       return {
         delegate: delegate.toBase58(),
         accounts: accounts.value.map(account => ({
           pubkey: account.pubkey,
           mint: account.account.data.parsed.info.mint,
           balance: account.account.data.parsed.info.tokenAmount.amount,
           owner: account.account.data.parsed.info.owner
         })),
         metrics: {
           totalAccounts: accounts.value.length,
           totalBalance: totalBalance.toString(),
           byMint: Object.fromEntries(
             Object.entries(byMint).map(([mint, amount]) => [mint, amount.toString()])
           ),
           byOwner
         },
         metadata: {
           timestamp: Date.now(),
           commitment: config.commitment
         }
       };
     }
   }
   ```

2. **Мониторинг счетов делегата**
   ```typescript theme={null}
   interface DelegateAccountChange {
     delegate: string;
     changes: Array<{
       type: 'added' | 'removed' | 'modified';
       account: string;
       previousBalance?: string;
       currentBalance?: string;
     }>;
     metadata: {
       timestamp: number;
     };
   }

   class DelegateAccountMonitor {
     private previousAccounts: Map<string, string> = new Map();
     
     async monitorDelegateAccounts(
       delegate: PublicKey,
       config: { programId: PublicKey; commitment?: string }
     ): Promise<DelegateAccountChange | null> {
       const accounts = await connection.getTokenAccountsByDelegate(delegate, config);
       const currentAccounts = new Map(
         accounts.value.map(account => [
           account.pubkey,
           account.account.data.parsed.info.tokenAmount.amount
         ])
       );
       
       const changes: Array<{
         type: 'added' | 'removed' | 'modified';
         account: string;
         previousBalance?: string;
         currentBalance?: string;
       }> = [];
       
       // Check for removed or modified accounts
       this.previousAccounts.forEach((balance, account) => {
         if (!currentAccounts.has(account)) {
           changes.push({
             type: 'removed',
             account,
             previousBalance: balance
           });
         } else if (currentAccounts.get(account) !== balance) {
           changes.push({
             type: 'modified',
             account,
             previousBalance: balance,
             currentBalance: currentAccounts.get(account)
           });
         }
       });
       
       // Check for added accounts
       currentAccounts.forEach((balance, account) => {
         if (!this.previousAccounts.has(account)) {
           changes.push({
             type: 'added',
             account,
             currentBalance: balance
           });
         }
       });
       
       this.previousAccounts = currentAccounts;
       
       if (changes.length > 0) {
         return {
           delegate: delegate.toBase58(),
           changes,
           metadata: {
             timestamp: Date.now()
           }
         };
       }
       
       return null;
     }
   }
   ```

3. **Планирование счетов делегата**
   ```typescript theme={null}
   interface DelegateAccountPlan {
     delegate: string;
     currentAccounts: Array<{
       pubkey: string;
       mint: string;
       balance: string;
     }>;
     recommendations: Array<{
       type: 'consolidate' | 'diversify' | 'rebalance';
       accounts: string[];
       reason: string;
     }>;
     metadata: {
       timestamp: number;
     };
   }

   class DelegateAccountPlanner {
     private readonly minBalancePerAccount = BigInt(1000000); // 1 token
     private readonly maxAccountsPerMint = 5;
     
     async planDelegateAccounts(
       delegate: PublicKey,
       config: { programId: PublicKey; commitment?: string }
     ): Promise<DelegateAccountPlan> {
       const accounts = await connection.getTokenAccountsByDelegate(delegate, config);
       
       const byMint = accounts.value.reduce((acc, account) => {
         const mint = account.account.data.parsed.info.mint;
         if (!acc[mint]) {
           acc[mint] = [];
         }
         acc[mint].push(account);
         return acc;
       }, {} as Record<string, typeof accounts.value>);
       
       const recommendations: Array<{
         type: 'consolidate' | 'diversify' | 'rebalance';
         accounts: string[];
         reason: string;
       }> = [];
       
       Object.entries(byMint).forEach(([mint, mintAccounts]) => {
         // Check for accounts with low balances
         const lowBalanceAccounts = mintAccounts.filter(account => 
           BigInt(account.account.data.parsed.info.tokenAmount.amount) < this.minBalancePerAccount
         );
         
         if (lowBalanceAccounts.length > 0) {
           recommendations.push({
             type: 'consolidate',
             accounts: lowBalanceAccounts.map(account => account.pubkey),
             reason: `Accounts with balances below minimum threshold for mint ${mint}`
           });
         }
         
         // Check for too many accounts per mint
         if (mintAccounts.length > this.maxAccountsPerMint) {
           recommendations.push({
             type: 'consolidate',
             accounts: mintAccounts.map(account => account.pubkey),
             reason: `Too many accounts (${mintAccounts.length}) for mint ${mint}`
           });
         }
       });
       
       return {
         delegate: delegate.toBase58(),
         currentAccounts: accounts.value.map(account => ({
           pubkey: account.pubkey,
           mint: account.account.data.parsed.info.mint,
           balance: account.account.data.parsed.info.tokenAmount.amount
         })),
         recommendations,
         metadata: {
           timestamp: Date.now()
         }
       };
     }
   }
   ```
