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

Параметры

pubkeys
array
Массив публичных ключей аккаунтов (закодированных в base-58)
config
object

Ответ

result
object

Примеры кода

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

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"]
  ]
}'

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

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

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. Используйте подходящее кодирование в зависимости от ваших потребностей

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

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

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

  1. Пакетная обработка аккаунтов
    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. Анализ данных аккаунтов
    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. Мониторинг аккаунтов
    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;
      }
    }