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

# getMultipleAccounts

> Возвращает информацию об аккаунтах для нескольких аккаунтов

## Параметры

<ResponseField name="pubkeys" type="array">
  Массив публичных ключей аккаунтов (закодированных в base-58)
</ResponseField>

<ResponseField name="config" type="object" optional>
  <Expandable title="поля config">
    <ResponseField name="commitment" type="string" optional>
      Уровень commitment (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>
  </Expandable>
</ResponseField>

## Ответ

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

    <ResponseField name="value" type="array">
      Массив объектов информации об аккаунтах или null для несуществующих аккаунтов

      <ResponseField name="data" type="array">
        Данные аккаунта в указанном кодировании
      </ResponseField>

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

      <ResponseField name="lamports" type="number">
        Баланс аккаунта в lamports
      </ResponseField>

      <ResponseField name="owner" type="string">
        Владелец аккаунта (закодирован в base-58)
      </ResponseField>

      <ResponseField name="rentEpoch" type="number">
        Epoch, при котором аккаунт должен будет в следующий раз заплатить аренду
      </ResponseField>
    </ResponseField>
  </Expandable>
</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": "getMultipleAccounts",
  "params": [
    ["ACCOUNT1", "ACCOUNT2", "ACCOUNT3"]
  ]
}'
```

### Запрос с кодированием

```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": "getMultipleAccounts",
  "params": [
    ["ACCOUNT1", "ACCOUNT2"],
    {
      "encoding": "base64",
      "dataSlice": {
        "offset": 0,
        "length": 100
      }
    }
  ]
}'
```

### Использование 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 multiple accounts
const accounts = await connection.getMultipleAccounts([
  new PublicKey('ACCOUNT1'),
  new PublicKey('ACCOUNT2')
]);
console.log('Accounts:', accounts.value);

// Get account data slices
async function getAccountDataSlices(
  pubkeys: PublicKey[],
  offset: number,
  length: number
) {
  const accounts = await connection.getMultipleAccounts(pubkeys, {
    encoding: 'base64',
    dataSlice: { offset, length }
  });
  
  return accounts.value.map((account, index) => ({
    pubkey: pubkeys[index].toBase58(),
    exists: account !== null,
    data: account?.data[0],
    lamports: account?.lamports
  }));
}
```

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

1. Возвращает информацию о нескольких аккаунтах в одном запросе
2. Несуществующие аккаунты возвращаются как null
3. Данные аккаунта можно нарезать для уменьшения размера ответа
4. Ответ приходит немедленно, поскольку считывается из текущего состояния
5. Для данных аккаунта можно указывать различные кодировки

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

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

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

| Код    | Сообщение                       | Решение                                                   |
| ------ | ------------------------------- | --------------------------------------------------------- |
| -32601 | Method not found                | Убедитесь, что вы подключены к узлу Solana RPC            |
| -32602 | Invalid params                  | Проверьте параметры pubkeys и config                      |
| -32007 | Account information unavailable | Узел может выполнять начальную загрузку или синхронизацию |

## Примеры использования

1. **Пакетная обработка аккаунтов**
   ```typescript theme={null}
   interface AccountBatch {
     accounts: Array<{
       pubkey: string;
       exists: boolean;
       lamports: number;
       owner: string;
       executable: boolean;
     }>;
     totalLamports: number;
     metadata: {
       timestamp: number;
       slot: number;
     };
   }

   async function processAccountBatch(
     pubkeys: PublicKey[],
     chunkSize: number = 100
   ): Promise<AccountBatch> {
     const accounts: AccountBatch['accounts'] = [];
     let totalLamports = 0;
     
     for (let i = 0; i < pubkeys.length; i += chunkSize) {
       const chunk = pubkeys.slice(i, i + chunkSize);
       const result = await connection.getMultipleAccounts(chunk);
       
       chunk.forEach((pubkey, index) => {
         const account = result.value[index];
         const exists = account !== null;
         
         accounts.push({
           pubkey: pubkey.toBase58(),
           exists,
           lamports: account?.lamports || 0,
           owner: account?.owner.toBase58() || '',
           executable: account?.executable || false
         });
         
         if (exists) {
           totalLamports += account.lamports;
         }
       });
     }
     
     return {
       accounts,
       totalLamports,
       metadata: {
         timestamp: Date.now(),
         slot: accounts[0]?.slot || 0
       }
     };
   }
   ```

2. **Анализ данных аккаунтов**
   ```typescript theme={null}
   interface AccountDataAnalysis {
     pubkey: string;
     dataSize: number;
     dataHash: string;
     lamports: number;
     owner: string;
     metadata: {
       timestamp: number;
       slot: number;
     };
   }

   async function analyzeAccountData(
     pubkeys: PublicKey[],
     dataSlice?: { offset: number; length: number }
   ): Promise<AccountDataAnalysis[]> {
     const accounts = await connection.getMultipleAccounts(pubkeys, {
       encoding: 'base64',
       dataSlice
     });
     
     return accounts.value.map((account, index) => {
       const pubkey = pubkeys[index].toBase58();
       
       if (!account) {
         return {
           pubkey,
           dataSize: 0,
           dataHash: '',
           lamports: 0,
           owner: '',
           metadata: {
             timestamp: Date.now(),
             slot: accounts.context.slot
           }
         };
       }
       
       const data = account.data[0];
       const dataSize = Buffer.from(data, 'base64').length;
       
       return {
         pubkey,
         dataSize,
         dataHash: require('crypto')
           .createHash('sha256')
           .update(data)
           .digest('hex'),
         lamports: account.lamports,
         owner: account.owner.toBase58(),
         metadata: {
           timestamp: Date.now(),
           slot: accounts.context.slot
         }
       };
     });
   }
   ```

3. **Мониторинг аккаунтов**
   ```typescript theme={null}
   interface AccountChange {
     pubkey: string;
     type: 'created' | 'deleted' | 'modified';
     previous: any;
     current: any;
     difference: number;
   }

   class AccountMonitor {
     private previousAccounts: Map<string, any> = new Map();
     
     async monitorAccounts(
       pubkeys: PublicKey[],
       interval: number = 5000
     ): Promise<AccountChange[]> {
       const accounts = await connection.getMultipleAccounts(pubkeys);
       const changes: AccountChange[] = [];
       
       pubkeys.forEach((pubkey, index) => {
         const address = pubkey.toBase58();
         const current = accounts.value[index];
         const previous = this.previousAccounts.get(address);
         
         if (!previous && current) {
           changes.push({
             pubkey: address,
             type: 'created',
             previous: null,
             current,
             difference: current.lamports
           });
         } else if (previous && !current) {
           changes.push({
             pubkey: address,
             type: 'deleted',
             previous,
             current: null,
             difference: -previous.lamports
           });
         } else if (previous && current) {
           const difference = current.lamports - previous.lamports;
           if (difference !== 0 || current.data[0] !== previous.data[0]) {
             changes.push({
               pubkey: address,
               type: 'modified',
               previous,
               current,
               difference
             });
           }
         }
         
         this.previousAccounts.set(address, current);
       });
       
       return changes;
     }
   }
   ```
