> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# getTokenAccountsByOwnerの使用方法

> getTokenAccountsByOwnerのユースケース、コード例、リクエストパラメータ、応答構造、およびヒントを学ぶ。

[`getTokenAccountsByOwner`](https://www.helius.dev/docs/api-reference/rpc/http/gettokenaccountsbyowner) RPCメソッドは、特定の公開鍵が所有するすべてのSPL[トークンアカウント](https://www.helius.dev/blog/how-to-get-token-holders-on-solana)を取得するために使用されます。これは、ユーザーのトークン保有状況を表示する必要があるウォレットやアプリケーションにとって基本となるメソッドです。

クエリを特定のトークン`mint`または`programId`（例：SPLトークンプログラムやToken-2022プログラム）でフィルタリングする必要があります。

広範なトークンポートフォリオを持つウォレットの場合、[`getTokenAccountsByOwnerV2`](/ja/api-reference/rpc/http/gettokenaccountsbyownerv2)を使用することを検討してください。これは、リクエストごとに最大10,000アカウントのページサイズを設定できるカーソルベースのページネーションをサポートしています。

## 一般的なユースケース

* **ユーザーポートフォリオの表示**：特定のユーザーのウォレットアドレスに対してすべてのトークンアカウント（および残高）を取得し、完全なトークンポートフォリオを表示する。
* **アプリケーションロジック**：特定のミントのユーザーの特定のトークンアカウントを特定し、転送やその他のインタラクションを開始する前に特定する。
* **検証**：所有者が特定のタイプのトークンを持っているトークンアカウントを確認する。
* **トークンホルダーのインデックス化**：他の方法よりも効率的ではないが、既知の一連の所有者のためにアカウントを見つけるために使用できる。

## リクエストパラメータ

1. **`ownerPubkey`**（文字列、必須）：取得したいトークンアカウントの所有者のBase-58エンコードされた公開鍵。

2. **`filter`**（オブジェクト、必須）：`mint`または`programId`のいずれかを指定する必要があるJSONオブジェクト：
   * **`mint`**（文字列）：特定のトークンミントのBase-58エンコードされた公開鍵。指定された場合、このミントのトークンアカウントのみが`ownerPubkey`によって所有される。
   * **`programId`**（文字列）：アカウントを管理するトークンプログラムのBase-58エンコードされた公開鍵。一般的な値は次のとおりです：
     * SPLトークンプログラム：`TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA`
     * Token-2022プログラム：`TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb`

3. **`options`**（オブジェクト、オプション）：オプションの構成オブジェクトを含めることができます：
   * **`commitment`**（文字列、オプション）：[コミットメントレベル](https://www.helius.dev/blog/solana-commitment-levels)を指定します。
   * **`encoding`**（文字列、オプション）：アカウントデータのエンコード。`"jsonParsed"`が推奨されます。他のオプション：`"base64"`、`"base64+zstd"`。デフォルトは`"base64"`。
   * **`dataSlice`**（オブジェクト、オプション）：特定のアカウントデータのスライスを取得します（`offset`：usize、`length`：usize）。`base58`、`base64`、または`base64+zstd`エンコーディングのみで使用します。
   * **`minContextSlot`**（u64、オプション）：クエリの最小スロット。

## 応答構造

JSON-RPC応答の`result.value`フィールドは、オブジェクトの配列です。それぞれのオブジェクトは`ownerPubkey`に所有され、`filter`に一致するSPLトークンアカウントに対応します。

`value`配列の各オブジェクトには次のものが含まれます：

* **`pubkey`**（文字列）：トークンアカウント自体のBase-58エンコードされた公開鍵。
* **`account`**（オブジェクト）：トークンアカウントに関する詳細情報:
  * **`lamports`**（u64）：家賃の免除のためのLamportバランス。
  * **`owner`**（文字列）：所有プログラム（例：トークンプログラムの公開鍵）。
  * **`data`**：アカウントデータ。`"jsonParsed"`エンコーディングが使用されている場合、これには以下が含まれます：
    * **`program`**（文字列）：例：`"spl-token"`。
    * **`parsed`**：構造化情報を持つオブジェクト：
      * **`info`**：以下を含む詳細：
        * **`mint`**（文字列）：トークンのミントアドレス。
        * **`owner`**（文字列）：トークンアカウントの所有者（これはリクエストからの`ownerPubkey`と一致するはずです）。
        * **`tokenAmount`**（オブジェクト）：トークンバランス（`amount`、`decimals`、`uiAmount`、`uiAmountString`）。
        * **`state`**（文字列）：トークンアカウントの状態（例：`"initialized"`）。
        * **`isNative`**（ブール）：アカウントがラップされたSOLを保持している場合。
        * **`delegate`**（文字列、オプション）：デリゲートアドレスが設定されている場合。
        * **`delegatedAmount`**（オブジェクト、オプション）：デリゲートが設定されている場合の委任額。
      * **`type`**（文字列）：例：`"account"`。
  * **`executable`**（ブール）：アカウントが実行可能かどうか。
  * **`rentEpoch`**（u64）：次のエポックの家賃の期日。
  * **`space`**（u64、`jsonParsed`でない場合）：生のアカウントデータのバイト数。

**例としての応答（`jsonParsed`エンコーディング、`programId`でフィルタリングされた）:**

```json theme={"system"}
{
  "jsonrpc": "2.0",
  "result": {
    "context": {
      "slot": 183459000
    },
    "value": [
      {
        "pubkey": "AssociatedTokenAccountPubkey1...",
        "account": {
          "data": {
            "program": "spl-token",
            "parsed": {
              "info": {
                "isNative": false,
                "mint": "SomeTokenMintPubkey...",
                "owner": "OwnerPubkeyProvidedInRequest...",
                "state": "initialized",
                "tokenAmount": {
                  "amount": "1000000000", // 1 token if decimals is 9
                  "decimals": 9,
                  "uiAmount": 1.0,
                  "uiAmountString": "1.0"
                }
              },
              "type": "account"
            },
            "space": 165
          },
          "executable": false,
          "lamports": 2039280,
          "owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
          "rentEpoch": 380
        }
      },
      {
        "pubkey": "AnotherAssociatedTokenAccountPubkey...",
        "account": {
          // ... similar structure for another token owned by the same owner
        }
      }
    ]
  },
  "id": 1
}
```

## コード例

<CodeGroup>
  ```bash cURL theme={"system"}
  # Replace <OWNER_PUBKEY> and <TOKEN_MINT_PUBKEY> or <TOKEN_PROGRAM_ID>

  # Example filtering by programId (SPL Token Program)
  curl -X POST -H "Content-Type: application/json" -d \
    '{
      "jsonrpc": "2.0",
      "id": 1,
      "method": "getTokenAccountsByOwner",
      "params": [
        "<OWNER_PUBKEY>",
        { "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" },
        { "encoding": "jsonParsed" }
      ]
    }' \
    <YOUR_RPC_URL>

  # Example filtering by a specific mint
  curl -X POST -H "Content-Type: application/json" -d \
    '{
      "jsonrpc": "2.0",
      "id": 1,
      "method": "getTokenAccountsByOwner",
      "params": [
        "<OWNER_PUBKEY>",
        { "mint": "<SPECIFIC_TOKEN_MINT_PUBKEY>" },
        { "encoding": "jsonParsed", "commitment": "confirmed" }
      ]
    }' \
    <YOUR_RPC_URL>
  ```

  ```javascript JavaScript (using @solana/web3.js) theme={"system"}
  const { Connection, PublicKey } = require('@solana/web3.js');

  async function findOwnerTokenAccounts(ownerAddress, filter, encoding = 'jsonParsed') {
    // Replace with your RPC endpoint
    const connection = new Connection('https://mainnet.helius-rpc.com/?api-key=<api-key>');
    const ownerPubKey = new PublicKey(ownerAddress);

    try {
      let actualFilter;
      if (filter.mint) {
        actualFilter = { mint: new PublicKey(filter.mint) };
      } else if (filter.programId) {
        actualFilter = { programId: new PublicKey(filter.programId) };
      } else {
        console.error("Filter must contain either 'mint' or 'programId'");
        return;
      }

      const accounts = await connection.getTokenAccountsByOwner(
        ownerPubKey,
        actualFilter,
        { encoding }
      );

      console.log(`Found ${accounts.value.length} token accounts for owner ${ownerAddress}:`);
      accounts.value.forEach(accInfo => {
        console.log(`  Token Account: ${accInfo.pubkey.toBase58()}`);
        if (encoding === 'jsonParsed' && accInfo.account.data.parsed) {
          console.log(`    Mint: ${accInfo.account.data.parsed.info.mint}`);
          console.log(`    Balance: ${accInfo.account.data.parsed.info.tokenAmount.uiAmountString}`);
        }
        // console.log(JSON.stringify(accInfo, null, 2)); // For full details
      });

    } catch (error) {
      console.error(`Error fetching token accounts for owner ${ownerAddress}:`, error);
    }
  }

  // Replace with an actual owner's public key
  const exampleOwner = 'HXtBm8XZbxaTt41uqaKhwUAa6Z1aPyvJdsZVENiWsetg'; // Example wallet address

  // Example 1: Find all SPL Token Program accounts owned by `exampleOwner`
  findOwnerTokenAccounts(exampleOwner, { programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' });

  // Example 2: Find USDC token accounts owned by `exampleOwner`
  // const usdcMint = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
  // findOwnerTokenAccounts(exampleOwner, { mint: usdcMint });

  // Example 3: Find Token-2022 Program accounts owned by `exampleOwner`
  // findOwnerTokenAccounts(exampleOwner, { programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb' });
  ```
</CodeGroup>

## 開発者ヒント

* **フィルター要件**：フィルターには`mint`または`programId`を*必ず*指定してください。これらの主要なフィルターのいずれかなしに、すべてのトークン型にわたって所有者のすべてのトークンアカウントをクエリすることはできません。
* **関連するトークンアカウント**：このメソッドは、公開鍵が所有するすべてのトークンアカウントを返します。標準の関連トークンアカウント（ATA）や、古いウォレット実装またはカスタム設定からの他のSPLトークンアカウントも含まれます。
* **エンコーディング**：`encoding`オプションには`"jsonParsed"`を使用することを強くお勧めします。これにより、バイナリアカウントデータがより使いやすいJSON構造にデコードされます。
* **パフォーマンス**：所有者にトークンアカウントが非常に多い場合（特に`programId`によってのみフィルタリングする場合）、応答が大きくなる可能性があります。そのような場合は、[`getTokenAccountsByOwnerV2`](/ja/api-reference/rpc/http/gettokenaccountsbyownerv2)を使用して、組み込みのページネーションサポートを利用してください。
* **Token-2022（トークン拡張）**：Token-2022プログラムで作成されたトークン（転送手数料、利息などの拡張をサポートしています）を扱う場合、正しい`programId`を使用してください：`TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb`。

このガイドは、`getTokenAccountsByOwner` RPCメソッドについての理解を深め、任意のSolanaアドレスのトークンアカウント情報を効率的に取得できるようにします。

## 大規模なトークンポートフォリオのページネーション

広範なトークン保有を持つウォレットの場合、[`getTokenAccountsByOwnerV2`](/ja/api-reference/rpc/http/gettokenaccountsbyownerv2)を使用してください。これにより次のことが可能です：

* **カーソルベースのページネーション**：`limit`（1-10,000）を設定し、`paginationKey`を使用して結果をナビゲートします
* **インクリメンタルアップデート**：特定のスロット以降に変更されたトークンアカウントのみを取得するには`changedSinceSlot`を使用します
* **より良いパフォーマンス**：タイムアウトを防ぎ、リアルタイムのポートフォリオ追跡を可能にする
* **ページネーションの挙動**：トークンアカウントが返されないときのみページネーションの終了が示されます。フィルタリングのために制限よりも少ないアカウントが返される可能性があります－`paginationKey`がnullになるまでページネーションを続けてください

```typescript theme={"system"}
// Example: Paginated query for all token accounts
const response = await fetch("https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    jsonrpc: "2.0",
    id: "1",
    method: "getTokenAccountsByOwnerV2",
    params: [
      "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
      { "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" },
      {
        encoding: "jsonParsed",
        limit: 1000
      }
    ]
  })
});

const data = await response.json();
console.log(`Found ${data.result.value.length} token accounts`);
if (data.result.paginationKey) {
  console.log("More results available, use paginationKey for next page");
  // Continue pagination even if fewer than limit accounts were returned
} else {
  console.log("End of pagination - no more token accounts available");
}
```

## 関連メソッド

<CardGroup cols={2}>
  <Card title="getTokenAccountsByOwnerV2" href="/ja/api-reference/rpc/http/gettokenaccountsbyownerv2">
    大規模ポートフォリオ向けのカーソルベースのナビゲーションを備えたページネーションバージョン
  </Card>

  <Card title="getTokenAccountBalance" href="/ja/api-reference/rpc/http/gettokenaccountbalance">
    特定のトークンアカウントの残高を取得
  </Card>
</CardGroup>
