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

# getTokenAccountsByOwnerV2

> getTokenAccountsByOwner 的增强版本，具有附加功能，包括基于游标的分页和 changedSinceSlot 支持，以便高效检索由特定钱包地址拥有的 SPL 代币账户。

## 概述

`getTokenAccountsByOwnerV2` 是标准 `getTokenAccountsByOwner` 方法的增强版，专为高效查询代币投资组合和处理代币持有量庞大的钱包而设计。该方法引入了基于游标的分页和增量更新功能。

<Info>
  **V2的新特性：**

  * **基于游标的分页**：配置每个请求从1到10,000个token账户的限制
  * **增量更新**：使用`changedSinceSlot`仅获取最近修改的token账户
  * **投资组合可扩展性**：高效处理包含数千个token账户的钱包
  * **向后兼容性**：支持所有现有的`getTokenAccountsByOwner`参数和过滤器
  * **可选的`withContext`**：`true`在`result.context`下添加了`slot`和`apiVersion`；省略或`false`则不包含
</Info>

<Warning>
  **过滤器要求**：在查询中必须提供 `mint` （特定代币）或 `programId` （SPL代币或Token-2022程序）。不支持查询没有过滤器的所有代币类型。
</Warning>

## 主要优势

<CardGroup cols={2}>
  <Card title="大型投资组合" icon="wallet">
    处理具有数千个代币账户的钱包，不会出现超时或内存问题
  </Card>

  <Card title="实时跟踪" icon="chart-line">
    使用 `changedSinceSlot` 进行增量更新，实现投资组合的实时监控
  </Card>
</CardGroup>

## `withContext`（可选）

配置对象（`params[2]`）上的布尔值。只有`result`的形状会改变，不包括过滤器、限制或分页。省略或`false`：`result.value`是token账户的**数组**。`true`：`result.context`加上`result.value`作为一个**对象**（`accounts`，`paginationKey`）。如果你处理两个，请分支到`Array.isArray(result.value)`。

```json theme={"system"}
// Omitted or false
{ "jsonrpc": "2.0", "id": "1", "result": { "value": [], "paginationKey": null } }

// true
{ "jsonrpc": "2.0", "id": "1", "result": {
  "context": { "slot": 411895550, "apiVersion": "3.1.9" },
  "value": { "accounts": [], "paginationKey": null }
}}
```

## 分页最佳实践

<Warning>
  **重要的分页行为**：只有在**未返回任何token账户**时才会指示分页结束。由于过滤的原因，API可能会返回少于你限制的账户——始终继续分页直到`paginationKey`是`null`。
</Warning>

### 基本投资组合查询

```typescript theme={"system"}
// Get all SPL Token accounts for a wallet
let allTokenAccounts = [];
let paginationKey = null;

do {
  const response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${API_KEY}`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: '1',
      method: 'getTokenAccountsByOwnerV2',
      params: [
        "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM", // wallet address
        { "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" },
        {
          encoding: 'jsonParsed',
          limit: 1000,
          ...(paginationKey && { paginationKey })
        }
      ]
    })
  });
  
  const data = await response.json();
  allTokenAccounts.push(...data.result.value);
  paginationKey = data.result.paginationKey;
} while (paginationKey);

console.log(`Total token accounts: ${allTokenAccounts.length}`);
```

### 增量投资组合更新

```typescript theme={"system"}
// Get only token accounts modified since a specific slot
const portfolioUpdates = await fetch(`https://mainnet.helius-rpc.com/?api-key=${API_KEY}`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: '1',
    method: 'getTokenAccountsByOwnerV2',
    params: [
      walletAddress,
      { "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" },
      {
        encoding: 'jsonParsed',
        limit: 1000,
        changedSinceSlot: lastUpdateSlot // Only get recent changes
      }
    ]
  })
});
```

## Token程序支持

<Tip>
  **Token-2022支持**：使用`TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb`作为`programId`来查询带有扩展功能的Token-2022账户，如转账费用、计息token等。
</Tip>

```typescript theme={"system"}
// Query Token-2022 accounts (supports token extensions)
const token2022Response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${API_KEY}`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: '1',
    method: 'getTokenAccountsByOwnerV2',
    params: [
      walletAddress,
      { "programId": "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb" }, // Token-2022
      { encoding: 'jsonParsed', limit: 1000 }
    ]
  })
});
```

## 从getTokenAccountsByOwner迁移

迁移很简单——只需将分页参数添加到你现有的查询中：

```diff theme={"system"}
{
  "jsonrpc": "2.0",
  "id": "1",
- "method": "getTokenAccountsByOwner",
+ "method": "getTokenAccountsByOwnerV2",
  "params": [
    "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
    { "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" },
    {
      "encoding": "jsonParsed",
+     "limit": 1000
    }
  ]
}
```

## 相关方法

<CardGroup cols={2}>
  <Card title="getTokenAccountsByOwner" icon="wallet" href="/docs/zh/api-reference/rpc/http/gettokenaccountsbyowner">
    无分页的原始方法
  </Card>

  <Card title="getProgramAccountsV2" icon="code" href="/docs/zh/api-reference/rpc/http/getprogramaccountsv2">
    用于程序账户查询的V2方法
  </Card>
</CardGroup>

## 请求参数

<ParamField body="address" type="string" required>
  要查询token持有的账户所有者的Solana钱包地址（pubkey），格式为base-58编码的字符串。
</ParamField>

<ParamField body="mint" type="string">
  特定 Solana 代币地址，仅检索特定代币或 NFT 的账户。
</ParamField>

<ParamField body="programId" type="string">
  创建代币账户的特定 Solana 代币程序 ID（通常是 SPL 代币程序）。
</ParamField>

<ParamField body="commitment" type="string">
  请求的承诺级别。

  * `confirmed`
  * `finalized`
  * `processed`
</ParamField>

<ParamField body="minContextSlot" type="number">
  请求可被评估的最小槽位。
</ParamField>

<ParamField body="withContext" type="boolean">
  当 `true` 时，返回 `result.context`（快照元数据：`slot`，`apiVersion`）并将 `accounts` 和 `paginationKey` 嵌套在 `result.value` 下作为对象。当 `false` 或省略时，`result.value` 是此页面的代币账户数组，`paginationKey` 在 `result` 上。应用相同的过滤器和限制。
</ParamField>

<ParamField body="dataSlice" type="object">
  请求账户数据的切片。
</ParamField>

<ParamField body="dataSlice.length" type="number">
  要返回的字节数。
</ParamField>

<ParamField body="dataSlice.offset" type="number">
  开始读取的字节偏移量。
</ParamField>

<ParamField body="encoding" type="string">
  账户数据的编码格式。

  * `base58`
  * `base64`
  * `base64+zstd`
  * `jsonParsed`
</ParamField>

<ParamField body="limit" type="number">
  每个请求返回的最大代币账户数量（1-10,000）。
</ParamField>

<ParamField body="paginationKey" type="string">
  用于获取后续页面的 Base-58 编码分页游标。使用之前响应中的 paginationKey。
</ParamField>

<ParamField body="changedSinceSlot" type="number">
  仅返回在此槽位号或之后修改的代币账户。对增量组合更新有用。
</ParamField>


## OpenAPI

````yaml zh/openapi/rpc-http/getTokenAccountsByOwnerV2.yaml POST /
openapi: 3.1.0
info:
  title: Solana RPC API
  version: 1.0.0
  description: >-
    增强的Solana代币账户发现API，具有附加功能，包括基于游标的分页和changedSinceSlot支持，以便高效检索与任何钱包地址相关的SPL代币余额、NFT和其他代币持有。支持通过基于slot的过滤进行增量更新。
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html
servers:
  - url: https://mainnet.helius-rpc.com
    description: 主网RPC端点
  - url: https://devnet.helius-rpc.com
    description: 开发网RPC端点
security: []
paths:
  /:
    post:
      tags:
        - RPC
      summary: getTokenAccountsByOwnerV2
      description: >
        增强版 getTokenAccountsByOwner，具有附加功能，包括基于游标的分页和 changedSinceSlot
        支持，能够高效检索由特定钱包地址拥有的大量 SPL 代币账户。支持配置每个请求最多 10,000
        个账户的可扩展投资组合查询。changedSinceSlot
        参数允许仅检索自特定区块链槽位以来修改的代币账户，非常适合实时投资组合跟踪和钱包余额同步。对于钱包、投资组合追踪器、DeFi
        应用程序以及任何需要全面代币持有数据的服务（用于管理大量代币组合的用户）至关重要。


        注意：只有在没有返回任何代币账户时才指示分页结束。由于过滤，API 可能返回的账户少于限制——继续分页直到 paginationKey 为
        null。


        **withContext**：可选布尔值，可在配置对象中使用（与编码、限制等一起）。当 `withContext` 为 `true`
        时，RPC 返回标准 Solana 包装形状：`result.context`（快照元数据，包括 `slot` 和通常的
        `apiVersion`）和 `result.value` 作为包含 `accounts` 和 `paginationKey` 的对象。当
        `withContext` 为 `false` 或省略时，账户列表为 `result.value` 的数组（与经典
        `getTokenAccountsByOwner` 相同），`paginationKey` 在 `result`
        上。过滤器、限制和分页行为没有变化；只有 `result` 的 JSON 形状不同。
      operationId: getTokenAccountsByOwnerV2
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                jsonrpc:
                  type: string
                  enum:
                    - '2.0'
                  description: JSON-RPC 协议版本。
                  example: '2.0'
                  default: '2.0'
                id:
                  type: string
                  description: 请求的唯一标识符。
                  example: '1'
                  default: '1'
                method:
                  type: string
                  enum:
                    - getTokenAccountsByOwnerV2
                  description: 要调用的 RPC 方法名称。
                  example: getTokenAccountsByOwnerV2
                  default: getTokenAccountsByOwnerV2
                params:
                  type: array
                  description: 用于查询由特定公钥拥有的分页代币账户的参数。
                  default:
                    - A1TMhSGzQxMr1TboBKtgixKz1sS6REASMxPo1qsyTSJd
                    - programId: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
                    - encoding: jsonParsed
                      limit: 1000
                  items:
                    oneOf:
                      - type: string
                        description: 要查询代币持有的账户所有者的 Solana 钱包地址（公钥），以 base-58 编码字符串表示。
                        example: A1TMhSGzQxMr1TboBKtgixKz1sS6REASMxPo1qsyTSJd
                      - type: object
                        description: 通过铸币地址或程序 ID 缩小代币账户范围的过滤配置。
                        properties:
                          mint:
                            type: string
                            description: 特定的 Solana 代币铸造地址，用于仅检索特定代币或 NFT 的账户。
                            example: 2cHr7QS3xfuSV8wdxo3ztuF4xbiarF6Nrgx3qpx3HzXR
                          programId:
                            type: string
                            description: 创建代币账户的特定 Solana 代币程序 ID（通常是 SPL 代币程序）。
                            example: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
                      - type: object
                        description: 具有分页支持和可选字段的增强配置对象。
                        properties:
                          commitment:
                            type: string
                            description: 请求的承诺级别。
                            enum:
                              - confirmed
                              - finalized
                              - processed
                            example: finalized
                          minContextSlot:
                            type: integer
                            description: 请求可以评估的最小槽位。
                            example: 1000
                          withContext:
                            type: boolean
                            description: >
                              When `true`, returns `result.context` (snapshot
                              metadata: `slot`, `apiVersion`) and nests

                              `accounts` and `paginationKey` under
                              `result.value` as an object. When `false`

                              or omitted, `result.value` is the token account
                              array for this page, with `paginationKey`

                              on `result`. Same filters and limits apply.
                            example: true
                          dataSlice:
                            type: object
                            description: 请求账户数据的一个切片。
                            properties:
                              length:
                                type: integer
                                description: 要返回的字节数。
                                example: 10
                              offset:
                                type: integer
                                description: 开始读取的字节偏移量。
                                example: 0
                          encoding:
                            type: string
                            description: 账户数据的编码格式。
                            enum:
                              - base58
                              - base64
                              - base64+zstd
                              - jsonParsed
                            example: jsonParsed
                          limit:
                            type: integer
                            description: 每个请求返回的最大代币账户数量（1-10,000）。
                            minimum: 1
                            maximum: 10000
                            example: 1000
                          paginationKey:
                            type: string
                            description: 用于获取后续页面的Base-58编码分页游标。使用上一个响应中的paginationKey。
                            example: 9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM
                          changedSinceSlot:
                            type: integer
                            description: 仅返回在此槽号或之后修改的代币账户。用于增量投资组合更新。
                            example: 12345678
      responses:
        '200':
          description: 成功检索到按所有者分页的代币账户。
          content:
            application/json:
              schema:
                type: object
                properties:
                  jsonrpc:
                    type: string
                    description: JSON-RPC协议版本。
                    enum:
                      - '2.0'
                    example: '2.0'
                  id:
                    type: string
                    description: 与请求匹配的标识符。
                    example: '1'
                  result:
                    oneOf:
                      - $ref: >-
                          #/components/schemas/TokenAccountsByOwnerV2ResultDirect
                        title: without withContext
                      - type: object
                        title: with withContext
                        description: >-
                          Wrapped result when `withContext` is `true` in the
                          request options.
                        required:
                          - context
                          - value
                        properties:
                          context:
                            type: object
                            description: >-
                              Snapshot metadata for the node response (slot
                              consistency, debugging).
                            properties:
                              slot:
                                type: integer
                                description: Slot at which the node built this response.
                                example: 341197933
                              apiVersion:
                                type: string
                                description: RPC API version when available.
                                example: 2.0.15
                          value:
                            $ref: '#/components/schemas/TokenAccountsByOwnerV2Page'
              example:
                jsonrpc: '2.0'
                id: '1'
                result:
                  value:
                    - pubkey: BGocb4GEpbTFm8UFV2VsDSaBXHELPfAXrvd4vtt8QWrA
                      account:
                        lamports: 2039280
                        owner: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
                        data:
                          program: spl-token
                          parsed:
                            info:
                              isNative: false
                              mint: 2cHr7QS3xfuSV8wdxo3ztuF4xbiarF6Nrgx3qpx3HzXR
                              owner: A1TMhSGzQxMr1TboBKtgixKz1sS6REASMxPo1qsyTSJd
                              state: initialized
                              tokenAmount:
                                amount: '420000000000000'
                                decimals: 6
                                uiAmount: 420000000
                                uiAmountString: '420000000'
                          space: 165
                        executable: false
                        rentEpoch: 18446744073709552000
                        space: 165
                  paginationKey: 8WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM
        '400':
          description: 错误请求 - 请求参数无效或请求格式错误。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                jsonrpc: '2.0'
                error:
                  code: -32602
                  message: 参数无效
                id: '1'
        '401':
          description: 未授权 - API 密钥无效或缺失。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                jsonrpc: '2.0'
                error:
                  code: -32001
                  message: 未授权
                id: '1'
        '429':
          description: 请求过多 - 超出速率限制。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                jsonrpc: '2.0'
                error:
                  code: -32005
                  message: 请求过多
                id: '1'
        '500':
          description: 内部服务器错误 - 服务器发生错误。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                jsonrpc: '2.0'
                error:
                  code: -32603
                  message: 内部错误
                id: '1'
        '503':
          description: 服务不可用 - 服务暂时不可用。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                jsonrpc: '2.0'
                error:
                  code: -32002
                  message: 服务不可用
                id: '1'
        '504':
          description: 网关超时 - 请求超时。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                jsonrpc: '2.0'
                error:
                  code: -32003
                  message: 网关超时
                id: '1'
      security:
        - ApiKeyQuery: []
components:
  schemas:
    TokenAccountsByOwnerV2ResultDirect:
      type: object
      description: >-
        当 `withContext` 为 false 或省略时的分页代币账户。匹配熟悉的形状，其中账户列表是一个数组的
        `result.value`（不嵌套在 `accounts` 下）。
      properties:
        value:
          type: array
          description: 当前页的代币账户。
          items:
            $ref: '#/components/schemas/TokenAccountByOwnerV2Entry'
        paginationKey:
          type: string
          description: 用于下一页的分页游标。只有当没有返回任何代币账户时为 null（分页结束）。注意，由于过滤，返回的账户可能少于限制，但这不表示分页结束。
          example: 8WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM
          nullable: true
    TokenAccountsByOwnerV2Page:
      type: object
      description: >-
        当 `withContext` 为 true 时的分页代币账户。`result.value` 中包含 `accounts` 和
        `paginationKey`，同时有 `result.context`。
      properties:
        accounts:
          type: array
          description: 当前页的代币账户。
          items:
            $ref: '#/components/schemas/TokenAccountByOwnerV2Entry'
        paginationKey:
          type: string
          description: 用于下一页的分页游标。只有当没有返回任何代币账户时为 null（分页结束）。注意，由于过滤，返回的账户可能少于限制，但这不表示分页结束。
          example: 8WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM
          nullable: true
    ErrorResponse:
      type: object
      properties:
        jsonrpc:
          type: string
          description: JSON-RPC协议版本。
          enum:
            - '2.0'
          example: '2.0'
        error:
          type: object
          properties:
            code:
              type: integer
              description: 错误代码。
              example: -32602
            message:
              type: string
              description: 错误信息。
            data:
              type: object
              description: 关于错误的附加数据。
        id:
          type: string
          description: 与请求匹配的标识符。
          example: '1'
    TokenAccountByOwnerV2Entry:
      type: object
      properties:
        pubkey:
          type: string
          description: 账户公共密钥，base-58编码字符串。
          example: BGocb4GEpbTFm8UFV2VsDSaBXHELPfAXrvd4vtt8QWrA
        account:
          type: object
          description: 代币账户详情。
          properties:
            lamports:
              type: integer
              description: 分配给账户的 lamports 数量。
              example: 2039280
            owner:
              type: string
              description: 账户被分配的程序的公共密钥。
              example: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
            data:
              type: object
              description: 与账户关联的代币状态数据。
              properties:
                program:
                  type: string
                  description: 程序名称。
                  example: spl-token
                parsed:
                  type: object
                  description: 已解析的代币数据。
                  properties:
                    info:
                      type: object
                      description: 代币账户信息。
                      properties:
                        isNative:
                          type: boolean
                          description: 指示账户是否持有本地SOL。
                          example: false
                        mint:
                          type: string
                          description: 代币铸造的公共密钥。
                          example: 2cHr7QS3xfuSV8wdxo3ztuF4xbiarF6Nrgx3qpx3HzXR
                        owner:
                          type: string
                          description: 账户所有者的公钥。
                          example: A1TMhSGzQxMr1TboBKtgixKz1sS6REASMxPo1qsyTSJd
                        state:
                          type: string
                          description: Token账户状态。
                          example: initialized
                        tokenAmount:
                          type: object
                          description: Token数量详情。
                          properties:
                            amount:
                              type: string
                              description: 未带小数的原始余额。
                              example: '420000000000000'
                            decimals:
                              type: integer
                              description: 小数位数。
                              example: 6
                            uiAmount:
                              type: number
                              description: 用户友好格式的余额。
                              example: 420000000
                            uiAmountString:
                              type: string
                              description: 字符串格式的余额。
                              example: '420000000'
                space:
                  type: integer
                  description: 为账户分配的空间。
                  example: 165
            executable:
              type: boolean
              description: 指示账户是否包含程序。
              example: false
            rentEpoch:
              type: integer
              description: 下次应付租金的纪元。
              example: 18446744073709552000
            space:
              type: integer
              description: 账户的数据大小。
              example: 165
  securitySchemes:
    ApiKeyQuery:
      type: apiKey
      in: query
      name: api-key
      description: 您的Helius API密钥。您可以在[仪表板](https://dashboard.helius.dev/api-keys)中免费获取一个。

````