> ## 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>
    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>
</ResponseField>

## 响应

<ResponseField name="result" type="object">
  包含以下内容的对象：

  <ResponseField name="context" type="object">
    <ResponseField name="slot" type="number">
      处理请求时的 slot
    </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">
        账户下次需要支付租金的 epoch
      </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. 根据需求使用适当的 commitment 级别
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;
       }> = [];
       
       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)
           });
         }
       });
       
       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]) => {
         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}`
           });
         }
         
         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()
         }
       };
     }
   }
   ```
