From 8c7e912f75b151415a4abb095446a04462737d3b Mon Sep 17 00:00:00 2001 From: alchemy-bot <80712764+alchemy-bot@users.noreply.github.com> Date: Fri, 21 Aug 2026 12:56:23 +0000 Subject: [PATCH] [docs-agent] Document Solana getBalanceByOwnerAtSlot method Adds an OpenRPC definition for the new Solana JSON-RPC method `getBalanceByOwnerAtSlot`, the aggregate counterpart to `getTokenAccountsByOwnerAtSlot`. It returns a wallet's summed balance of one SPL Token or Token-2022 mint at a specific slot, with an optional `scope` parameter (all | ata) selecting between the wallet-wide sum and its canonical Associated Token Account. - Method definition in `src/openrpc/chains/_components/solana/methods.yaml` - `GetBalanceByOwnerAtSlotScope` and `GetBalanceByOwnerAtSlotResult` schemas in `src/openrpc/chains/_components/solana/account.yaml` - `$ref` registration and `x-bot-ignore` entry in `src/openrpc/chains/solana/solana.yaml` - Table link in `content/api-reference/solana/solana-api-overview.mdx` Refs DOCS-199 Requested-by: @andreidg31 --- .../solana/solana-api-overview.mdx | 56 ++++----- .../chains/_components/solana/account.yaml | 44 +++++++ .../chains/_components/solana/methods.yaml | 118 ++++++++++++++++++ src/openrpc/chains/solana/solana.yaml | 3 + 4 files changed, 193 insertions(+), 28 deletions(-) diff --git a/content/api-reference/solana/solana-api-overview.mdx b/content/api-reference/solana/solana-api-overview.mdx index 4cbf2f123..4ae3f5bd6 100644 --- a/content/api-reference/solana/solana-api-overview.mdx +++ b/content/api-reference/solana/solana-api-overview.mdx @@ -12,34 +12,34 @@ slug: docs/solana/solana-api-overview | | | | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | | [`getAccountInfo`](/docs/chains/solana/solana-api-endpoints/get-account-info) | [`getBalance`](/docs/chains/solana/solana-api-endpoints/get-balance) | -| [`getBlock`](/docs/chains/solana/solana-api-endpoints/get-block) | [`getBlockCommitment`](/docs/chains/solana/solana-api-endpoints/get-block-commitment) | -| [`getBlockHeight`](/docs/chains/solana/solana-api-endpoints/get-block-height) | [`getBlockProduction`](/docs/chains/solana/solana-api-endpoints/get-block-production) | -| [`getBlocks`](/docs/chains/solana/solana-api-endpoints/get-blocks) | [`getBlocksWithLimit`](/docs/chains/solana/solana-api-endpoints/get-blocks-with-limit) | -| [`getBlockTime`](/docs/chains/solana/solana-api-endpoints/get-block-time) | [`getClusterNodes`](/docs/chains/solana/solana-api-endpoints/get-cluster-nodes) | -| [`getEpochInfo`](/docs/chains/solana/solana-api-endpoints/get-epoch-info) | [`getEpochSchedule`](/docs/chains/solana/solana-api-endpoints/get-epoch-schedule) | -| [`getFeeForMessage`](/docs/chains/solana/solana-api-endpoints/get-fee-for-message) | [`getFirstAvailableBlock`](/docs/chains/solana/solana-api-endpoints/get-first-available-block) | -| [`getGenesisHash`](/docs/chains/solana/solana-api-endpoints/get-genesis-hash) | [`getHealth`](/docs/chains/solana/solana-api-endpoints/get-health) | -| [`getHighestSnapshotSlot`](/docs/chains/solana/solana-api-endpoints/get-highest-snapshot-slot) | [`getIdentity`](/docs/chains/solana/solana-api-endpoints/get-identity) | -| [`getInflationGovernor`](/docs/chains/solana/solana-api-endpoints/get-inflation-governor) | [`getInflationRate`](/docs/chains/solana/solana-api-endpoints/get-inflation-rate) | -| [`getInflationReward`](/docs/chains/solana/solana-api-endpoints/get-inflation-reward) | [`getLargestAccounts`](/docs/chains/solana/solana-api-endpoints/get-largest-accounts) | -| [`getLatestBlockhash`](/docs/chains/solana/solana-api-endpoints/get-latest-blockhash) | [`getLeaderSchedule`](/docs/chains/solana/solana-api-endpoints/get-leader-schedule) | -| [`getMaxRetransmitSlot`](/docs/chains/solana/solana-api-endpoints/get-max-retransmit-slot) | [`getMaxShredInsertSlot`](/docs/chains/solana/solana-api-endpoints/get-max-shred-insert-slot) | -| [`getMinimumBalanceForRentExemption`](/docs/chains/solana/solana-api-endpoints/get-minimum-balance-for-rent-exemption) | [`getMultipleAccounts`](/docs/chains/solana/solana-api-endpoints/get-multiple-accounts) | -| [`getPriorityFeeEstimate`](/docs/chains/solana/solana-api-endpoints/get-priority-fee-estimate) | [`getProgramAccounts`](/docs/chains/solana/solana-api-endpoints/get-program-accounts) | -| [`getRecentPerformanceSamples`](/docs/chains/solana/solana-api-endpoints/get-recent-performance-samples) | [`getRecentPrioritizationFees`](/docs/chains/solana/solana-api-endpoints/get-recent-prioritization-fees) | -| [`getSignaturesForAddress`](/docs/chains/solana/solana-api-endpoints/get-signatures-for-address) | [`getSignatureStatuses`](/docs/chains/solana/solana-api-endpoints/get-signature-statuses) | -| [`getSlot`](/docs/chains/solana/solana-api-endpoints/get-slot) | [`getSlotLeader`](/docs/chains/solana/solana-api-endpoints/get-slot-leader) | -| [`getSlotLeaders`](/docs/chains/solana/solana-api-endpoints/get-slot-leaders) | [`getStakeActivation`](/docs/chains/solana/solana-api-endpoints/get-stake-activation) | -| [`getStakeMinimumDelegation`](/docs/chains/solana/solana-api-endpoints/get-stake-minimum-delegation) | [`getSupply`](/docs/chains/solana/solana-api-endpoints/get-supply) | -| [`getTokenAccountBalance`](/docs/chains/solana/solana-api-endpoints/get-token-account-balance) | [`getTokenAccountsByDelegate`](/docs/chains/solana/solana-api-endpoints/get-token-accounts-by-delegate) | -| [`getTokenAccountsByOwner`](/docs/chains/solana/solana-api-endpoints/get-token-accounts-by-owner) | [`getTokenAccountsByOwnerAtSlot`](/docs/chains/solana/solana-api-endpoints/get-token-accounts-by-owner-at-slot) | -| [`getTokenLargestAccounts`](/docs/chains/solana/solana-api-endpoints/get-token-largest-accounts) | [`getTokenSupply`](/docs/chains/solana/solana-api-endpoints/get-token-supply) | -| [`getTransaction`](/docs/chains/solana/solana-api-endpoints/get-transaction) | [`getTransactionCount`](/docs/chains/solana/solana-api-endpoints/get-transaction-count) | -| [`getTransactionsForAddress`](/docs/chains/solana/solana-api-endpoints/get-transactions-for-address) | [`getVersion`](/docs/chains/solana/solana-api-endpoints/get-version) | -| [`getVoteAccounts`](/docs/chains/solana/solana-api-endpoints/get-vote-accounts) | [`isBlockhashValid`](/docs/chains/solana/solana-api-endpoints/is-blockhash-valid) | -| [`minimumLedgerSlot`](/docs/chains/solana/solana-api-endpoints/minimum-ledger-slot) | [`requestAirdrop`](/docs/chains/solana/solana-api-endpoints/request-airdrop) | -| [`sendTransaction`](/docs/chains/solana/solana-api-endpoints/send-transaction) | [`simulateBundle`](/docs/chains/solana/solana-api-endpoints/simulate-bundle) | -| [`simulateTransaction`](/docs/chains/solana/solana-api-endpoints/simulate-transaction) | | +| [`getBalanceByOwnerAtSlot`](/docs/chains/solana/solana-api-endpoints/get-balance-by-owner-at-slot) | [`getBlock`](/docs/chains/solana/solana-api-endpoints/get-block) | +| [`getBlockCommitment`](/docs/chains/solana/solana-api-endpoints/get-block-commitment) | [`getBlockHeight`](/docs/chains/solana/solana-api-endpoints/get-block-height) | +| [`getBlockProduction`](/docs/chains/solana/solana-api-endpoints/get-block-production) | [`getBlocks`](/docs/chains/solana/solana-api-endpoints/get-blocks) | +| [`getBlocksWithLimit`](/docs/chains/solana/solana-api-endpoints/get-blocks-with-limit) | [`getBlockTime`](/docs/chains/solana/solana-api-endpoints/get-block-time) | +| [`getClusterNodes`](/docs/chains/solana/solana-api-endpoints/get-cluster-nodes) | [`getEpochInfo`](/docs/chains/solana/solana-api-endpoints/get-epoch-info) | +| [`getEpochSchedule`](/docs/chains/solana/solana-api-endpoints/get-epoch-schedule) | [`getFeeForMessage`](/docs/chains/solana/solana-api-endpoints/get-fee-for-message) | +| [`getFirstAvailableBlock`](/docs/chains/solana/solana-api-endpoints/get-first-available-block) | [`getGenesisHash`](/docs/chains/solana/solana-api-endpoints/get-genesis-hash) | +| [`getHealth`](/docs/chains/solana/solana-api-endpoints/get-health) | [`getHighestSnapshotSlot`](/docs/chains/solana/solana-api-endpoints/get-highest-snapshot-slot) | +| [`getIdentity`](/docs/chains/solana/solana-api-endpoints/get-identity) | [`getInflationGovernor`](/docs/chains/solana/solana-api-endpoints/get-inflation-governor) | +| [`getInflationRate`](/docs/chains/solana/solana-api-endpoints/get-inflation-rate) | [`getInflationReward`](/docs/chains/solana/solana-api-endpoints/get-inflation-reward) | +| [`getLargestAccounts`](/docs/chains/solana/solana-api-endpoints/get-largest-accounts) | [`getLatestBlockhash`](/docs/chains/solana/solana-api-endpoints/get-latest-blockhash) | +| [`getLeaderSchedule`](/docs/chains/solana/solana-api-endpoints/get-leader-schedule) | [`getMaxRetransmitSlot`](/docs/chains/solana/solana-api-endpoints/get-max-retransmit-slot) | +| [`getMaxShredInsertSlot`](/docs/chains/solana/solana-api-endpoints/get-max-shred-insert-slot) | [`getMinimumBalanceForRentExemption`](/docs/chains/solana/solana-api-endpoints/get-minimum-balance-for-rent-exemption) | +| [`getMultipleAccounts`](/docs/chains/solana/solana-api-endpoints/get-multiple-accounts) | [`getPriorityFeeEstimate`](/docs/chains/solana/solana-api-endpoints/get-priority-fee-estimate) | +| [`getProgramAccounts`](/docs/chains/solana/solana-api-endpoints/get-program-accounts) | [`getRecentPerformanceSamples`](/docs/chains/solana/solana-api-endpoints/get-recent-performance-samples) | +| [`getRecentPrioritizationFees`](/docs/chains/solana/solana-api-endpoints/get-recent-prioritization-fees) | [`getSignaturesForAddress`](/docs/chains/solana/solana-api-endpoints/get-signatures-for-address) | +| [`getSignatureStatuses`](/docs/chains/solana/solana-api-endpoints/get-signature-statuses) | [`getSlot`](/docs/chains/solana/solana-api-endpoints/get-slot) | +| [`getSlotLeader`](/docs/chains/solana/solana-api-endpoints/get-slot-leader) | [`getSlotLeaders`](/docs/chains/solana/solana-api-endpoints/get-slot-leaders) | +| [`getStakeActivation`](/docs/chains/solana/solana-api-endpoints/get-stake-activation) | [`getStakeMinimumDelegation`](/docs/chains/solana/solana-api-endpoints/get-stake-minimum-delegation) | +| [`getSupply`](/docs/chains/solana/solana-api-endpoints/get-supply) | [`getTokenAccountBalance`](/docs/chains/solana/solana-api-endpoints/get-token-account-balance) | +| [`getTokenAccountsByDelegate`](/docs/chains/solana/solana-api-endpoints/get-token-accounts-by-delegate) | [`getTokenAccountsByOwner`](/docs/chains/solana/solana-api-endpoints/get-token-accounts-by-owner) | +| [`getTokenAccountsByOwnerAtSlot`](/docs/chains/solana/solana-api-endpoints/get-token-accounts-by-owner-at-slot) | [`getTokenLargestAccounts`](/docs/chains/solana/solana-api-endpoints/get-token-largest-accounts) | +| [`getTokenSupply`](/docs/chains/solana/solana-api-endpoints/get-token-supply) | [`getTransaction`](/docs/chains/solana/solana-api-endpoints/get-transaction) | +| [`getTransactionCount`](/docs/chains/solana/solana-api-endpoints/get-transaction-count) | [`getTransactionsForAddress`](/docs/chains/solana/solana-api-endpoints/get-transactions-for-address) | +| [`getVersion`](/docs/chains/solana/solana-api-endpoints/get-version) | [`getVoteAccounts`](/docs/chains/solana/solana-api-endpoints/get-vote-accounts) | +| [`isBlockhashValid`](/docs/chains/solana/solana-api-endpoints/is-blockhash-valid) | [`minimumLedgerSlot`](/docs/chains/solana/solana-api-endpoints/minimum-ledger-slot) | +| [`requestAirdrop`](/docs/chains/solana/solana-api-endpoints/request-airdrop) | [`sendTransaction`](/docs/chains/solana/solana-api-endpoints/send-transaction) | +| [`simulateBundle`](/docs/chains/solana/solana-api-endpoints/simulate-bundle) | [`simulateTransaction`](/docs/chains/solana/solana-api-endpoints/simulate-transaction) | ## Related APIs diff --git a/src/openrpc/chains/_components/solana/account.yaml b/src/openrpc/chains/_components/solana/account.yaml index d599552d5..7872a88be 100644 --- a/src/openrpc/chains/_components/solana/account.yaml +++ b/src/openrpc/chains/_components/solana/account.yaml @@ -326,6 +326,50 @@ components: description: >- Cursor for the next page, or `null` on the last page. Send it back in `config.pageKey` to continue paging. + GetBalanceByOwnerAtSlotScope: + title: GetBalanceByOwnerAtSlot Scope + type: string + description: >- + Which of the wallet's token accounts the balance covers. + Case-sensitive. + enum: + - all + - ata + default: all + GetBalanceByOwnerAtSlotResult: + title: GetBalanceByOwnerAtSlot Result + type: object + description: >- + A wallet's aggregate balance of a single SPL Token or Token-2022 + mint at the requested slot. The response shape is identical for + every scope, so callers never need to branch on it. + properties: + wallet: + $ref: "./base-types.yaml#/components/schemas/Pubkey" + description: The wallet queried. + mint: + $ref: "./base-types.yaml#/components/schemas/Pubkey" + description: The token mint queried. + isNative: + type: boolean + description: "`true` for Wrapped SOL." + balance: + type: string + description: >- + Human-readable amount (`balanceRaw` scaled by `decimals`). + Returned as a string so large values survive JSON parsing + without precision loss. + balanceRaw: + type: string + description: >- + Raw token amount, as an integer string. Parse as a big + integer, not a float. + decimals: + type: integer + description: Mint decimals. + slot: + type: integer + description: The slot the balance was computed at. LargestAccountsConfig: title: LargestAccounts Configuration type: object diff --git a/src/openrpc/chains/_components/solana/methods.yaml b/src/openrpc/chains/_components/solana/methods.yaml index 0eb64389b..e5f6b6dd4 100644 --- a/src/openrpc/chains/_components/solana/methods.yaml +++ b/src/openrpc/chains/_components/solana/methods.yaml @@ -320,6 +320,124 @@ components: Internal error. Retry the request; if it persists, contact support. + getBalanceByOwnerAtSlot: + name: getBalanceByOwnerAtSlot + summary: >- + Returns a wallet's total balance of a single SPL Token or + Token-2022 mint as of a specific slot. + description: >- + Returns a wallet's total balance of a single SPL Token or + Token-2022 mint as of a specific slot, already summed across + every token account the wallet held of that mint. It is the + aggregate counterpart to `getTokenAccountsByOwnerAtSlot`: where + that method returns the inventory, this returns the number. + + + A wallet can own an unlimited number of token accounts for the + same mint, so "the balance" is genuinely ambiguous. The optional + `scope` parameter chooses which question to answer. + + + - `all` (default) sums across every token account the wallet + held of that mint at that slot. Use it for portfolio value, cost + basis, PnL, tax reporting, and treasury reconciliation. + + - `ata` returns the balance of the wallet's canonical Associated + Token Account only, the deterministic address derived from + (`wallet`, token program, `mint`). It excludes auxiliary + accounts created by programs and is substantially faster because + it resolves one known address instead of aggregating every + account the wallet holds. The correct token program is selected + automatically from the mint, so Token-2022 mints derive their + ATA correctly. + + + For a wallet holding a single token account of the mint, both + scopes return the same value. For a wallet holding many, they + can differ by orders of magnitude. + + + Unlike `getTokenAccountsByOwnerAtSlot`, there is no "latest + slot" default: omitting `slot` is an error. Accepts either an + object (recommended) or a positional array + `[wallet, mint, slot, scope]`. The `wallet` field also accepts + `owner` as an alias in the object form. + x-compute-units: 40 + params: + - name: wallet + required: true + description: >- + The base58-encoded Pubkey of the wallet whose balance you + want. `owner` is accepted as an alias in the object form. + schema: + $ref: "./base-types.yaml#/components/schemas/Pubkey" + - name: mint + required: true + description: >- + The base58-encoded Pubkey of the token mint. SPL Token and + Token-2022 mints are both supported. + schema: + $ref: "./base-types.yaml#/components/schemas/Pubkey" + - name: slot + required: true + description: >- + The slot to reconstruct the balance at. There is no default, + omitting `slot` is an error. + schema: + type: integer + minimum: 0 + - name: scope + required: false + description: >- + Which of the wallet's token accounts the balance covers. + Defaults to `all`. Case-sensitive. + schema: + $ref: "./account.yaml#/components/schemas/GetBalanceByOwnerAtSlotScope" + examples: + - name: getBalanceByOwnerAtSlot example + params: + - name: wallet + value: "FHX9fPAUVA1MxPme28f4eeVH81QVRHDWofa2V6FUJaiR" + - name: mint + value: "poLisWXnNRwC6oBu1vHiuKQzFjGL4XDSu4g9qjz9qVk" + - name: slot + value: 225000000 + - name: scope + value: all + result: + name: Balance at slot + value: + wallet: "FHX9fPAUVA1MxPme28f4eeVH81QVRHDWofa2V6FUJaiR" + mint: "poLisWXnNRwC6oBu1vHiuKQzFjGL4XDSu4g9qjz9qVk" + isNative: false + balance: "38205.4" + balanceRaw: "3820540000000" + decimals: 8 + slot: 225000000 + result: + name: Balance at slot + description: >- + The wallet's aggregate balance of the requested mint at the + requested slot, plus the slot the balance was computed at. + schema: + $ref: "./account.yaml#/components/schemas/GetBalanceByOwnerAtSlotResult" + errors: + - code: -32602 + message: >- + Invalid params. Common causes include a missing or malformed + `wallet`/`owner`, a missing or malformed `mint`, a missing + `slot`, an unknown `scope` value (only `all` and `ata` are + accepted, case-sensitive), or a `mint` that is not present + in the index. + - code: -32600 + message: >- + Unsupported method on `SOLANA_MAINNET`. The `method` field + was not `getBalanceByOwnerAtSlot`. + - code: -32603 + message: >- + Internal error. Retry the request; if it persists, contact + support. + getLargestAccounts: name: getLargestAccounts description: Returns the 20 largest accounts, by lamport balance. diff --git a/src/openrpc/chains/solana/solana.yaml b/src/openrpc/chains/solana/solana.yaml index 72f79159f..0f9f51a7e 100644 --- a/src/openrpc/chains/solana/solana.yaml +++ b/src/openrpc/chains/solana/solana.yaml @@ -83,6 +83,8 @@ methods: - $ref: ../_components/solana/methods.yaml#/components/methods/simulateBundle - $ref: >- ../_components/solana/methods.yaml#/components/methods/getTokenAccountsByOwnerAtSlot + - $ref: >- + ../_components/solana/methods.yaml#/components/methods/getBalanceByOwnerAtSlot - $ref: ../_components/solana/methods.yaml#/components/methods/getHealth - $ref: ../_components/solana/methods.yaml#/components/methods/sendTransaction - $ref: ../_components/solana/methods.yaml#/components/methods/simulateTransaction @@ -141,6 +143,7 @@ x-bot-ignore: - getTokenAccounts - getTokenAccounts_v2 - getTokenAccountsByOwnerAtSlot + - getBalanceByOwnerAtSlot - getTransaction - alchemy_getProgramAccounts - alchemy_getTokenAccountsByDelegate