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

# getTokenAccountsByOwner

> Returns all token accounts for a given owner

## Parameters

<ResponseField name="owner" type="string" required>
  Public key of the owner (base-58 encoded)
</ResponseField>

<ResponseField name="config" type="object" required>
  Configuration object containing:

  <ResponseField name="programId" type="string" required>
    Public key of the token program (base-58 encoded)
  </ResponseField>

  <ResponseField name="commitment" type="string" optional>
    Commitment level (processed, confirmed, finalized)
  </ResponseField>

  <ResponseField name="encoding" type="string" optional>
    Encoding for account data (base58, base64, jsonParsed)
  </ResponseField>

  <ResponseField name="dataSlice" type="object" optional>
    <ResponseField name="offset" type="number">
      Offset into account data
    </ResponseField>

    <ResponseField name="length" type="number">
      Length of data to return
    </ResponseField>
  </ResponseField>
</ResponseField>

## Response

<ResponseField name="result" type="object">
  Object containing:

  <ResponseField name="context" type="object">
    <ResponseField name="slot" type="number">
      The slot the request was processed at
    </ResponseField>
  </ResponseField>

  <ResponseField name="value" type="array">
    Array of token account objects containing:

    <ResponseField name="pubkey" type="string">
      Public key of the token account (base-58 encoded)
    </ResponseField>

    <ResponseField name="account" type="object">
      <ResponseField name="lamports" type="number">
        Number of lamports in the account
      </ResponseField>

      <ResponseField name="owner" type="string">
        Public key of the account owner (base-58 encoded)
      </ResponseField>

      <ResponseField name="executable" type="boolean">
        Whether the account is executable
      </ResponseField>

      <ResponseField name="rentEpoch" type="number">
        Epoch at which the account will next owe rent
      </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">
                Raw amount of tokens as a string
              </ResponseField>

              <ResponseField name="decimals" type="number">
                Number of decimals configured for token's mint
              </ResponseField>

              <ResponseField name="uiAmount" type="number" optional>
                Token amount as a float, accounting for decimals
              </ResponseField>

              <ResponseField name="uiAmountString" type="string" optional>
                Token amount as a string, accounting for decimals
              </ResponseField>
            </ResponseField>

            <ResponseField name="mint" type="string">
              Public key of the token's mint (base-58 encoded)
            </ResponseField>

            <ResponseField name="owner" type="string">
              Public key of the token account owner (base-58 encoded)
            </ResponseField>

            <ResponseField name="delegate" type="string" optional>
              Public key of the delegate (base-58 encoded)
            </ResponseField>
          </ResponseField>

          <ResponseField name="type" type="string">
            Type of account (account)
          </ResponseField>
        </ResponseField>

        <ResponseField name="program" type="string">
          Program that owns the account (spl-token)
        </ResponseField>

        <ResponseField name="space" type="number">
          Number of bytes allocated to the account
        </ResponseField>
      </ResponseField>
    </ResponseField>
  </ResponseField>
</ResponseField>

## Code Examples

### Basic Request

```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": "getTokenAccountsByOwner",
  "params": [
    "4vJ9JU1bJJE96FWSJKvHsmmFADCg4gpZQff4P3bkLZj",
    {
      "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
    }
  ]
}'
```

### Using 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 owner
const owner = new PublicKey('4vJ9JU1bJJE96FWSJKvHsmmFADCg4gpZQff4P3bkLZj');
const programId = new PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA');
const accounts = await connection.getTokenAccountsByOwner(owner, { programId });
console.log('Token accounts:', accounts);

// Get token accounts by owner with analysis
async function getTokenAccountsByOwnerWithAnalysis(
  owner: PublicKey,
  config: { programId: PublicKey; commitment?: string }
) {
  const accounts = await connection.getTokenAccountsByOwner(owner, 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
      }
    }
  };
}
```

## Notes

1. Returns all token accounts owned by the given public key
2. The owner has full control over these accounts
3. The response is immediate as it reads from the current state
4. The accounts can change with token transfers and other operations
5. The owner must be a valid public key

## Best Practices

1. Use appropriate commitment level based on your needs
2. Cache results when appropriate to reduce RPC load
3. Monitor for changes in owned accounts
4. Consider using websocket subscription for real-time updates
5. Handle network errors and retry when appropriate

## Common Errors

| Code   | Message            | Solution                                     |
| ------ | ------------------ | -------------------------------------------- |
| -32601 | Method not found   | Verify you're connected to a Solana RPC node |
| -32602 | Invalid params     | Check owner public key and configuration     |
| -32007 | Owner not found    | Verify the owner exists                      |
| -32008 | Invalid program ID | Verify the program ID is correct             |

## Use Cases

1. **Owner Account Analysis**
   ```typescript theme={null}
   interface OwnerAccountAnalysis {
     owner: string;
     accounts: Array<{
       pubkey: string;
       mint: string;
       balance: string;
       delegate?: string;
     }>;
     metrics: {
       totalAccounts: number;
       totalBalance: string;
       byMint: Record<string, string>;
       delegatedAccounts: number;
     };
     metadata: {
       timestamp: number;
       commitment?: string;
     };
   }

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

2. **Owner Account Monitoring**
   ```typescript theme={null}
   interface OwnerAccountChange {
     owner: string;
     changes: Array<{
       type: 'added' | 'removed' | 'modified';
       account: string;
       previousBalance?: string;
       currentBalance?: string;
       previousDelegate?: string;
       currentDelegate?: string;
     }>;
     metadata: {
       timestamp: number;
     };
   }

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

3. **Owner Account Planning**
   ```typescript theme={null}
   interface OwnerAccountPlan {
     owner: string;
     currentAccounts: Array<{
       pubkey: string;
       mint: string;
       balance: string;
       delegate?: string;
     }>;
     recommendations: Array<{
       type: 'consolidate' | 'diversify' | 'rebalance' | 'delegate';
       accounts: string[];
       reason: string;
     }>;
     metadata: {
       timestamp: number;
     };
   }

   class OwnerAccountPlanner {
     private readonly minBalancePerAccount = BigInt(1000000); // 1 token
     private readonly maxAccountsPerMint = 5;
     
     async planOwnerAccounts(
       owner: PublicKey,
       config: { programId: PublicKey; commitment?: string }
     ): Promise<OwnerAccountPlan> {
       const accounts = await connection.getTokenAccountsByOwner(owner, 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' | 'delegate';
         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}`
           });
         }
         
         // Check for accounts without delegates
         const accountsWithoutDelegates = mintAccounts.filter(
           account => !account.account.data.parsed.info.delegate
         );
         
         if (accountsWithoutDelegates.length > 0) {
           recommendations.push({
             type: 'delegate',
             accounts: accountsWithoutDelegates.map(account => account.pubkey),
             reason: `Accounts without delegates for mint ${mint}`
           });
         }
       });
       
       return {
         owner: owner.toBase58(),
         currentAccounts: accounts.value.map(account => ({
           pubkey: account.pubkey,
           mint: account.account.data.parsed.info.mint,
           balance: account.account.data.parsed.info.tokenAmount.amount,
           delegate: account.account.data.parsed.info.delegate
         })),
         recommendations,
         metadata: {
           timestamp: Date.now()
         }
       };
     }
   }
   ```
