跳转到主要内容

参数

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检查公钥和配置参数
-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;
      }
    }