Skip to content

[docs-agent] Fix Solana DAS Try It defaults for getTokenAccounts and searchAssets#1287

Merged
dexterliu merged 8 commits into
mainfrom
docs/solana-das-try-it-defaults
May 8, 2026
Merged

[docs-agent] Fix Solana DAS Try It defaults for getTokenAccounts and searchAssets#1287
dexterliu merged 8 commits into
mainfrom
docs/solana-das-try-it-defaults

Conversation

@JackReacher0807
Copy link
Copy Markdown
Collaborator

Summary

Andrei reported that the Try It feature on the Solana DAS docs pages for getTokenAccounts and searchAssets does not work with the defaulted values in the form. Both methods fail when a user clicks Try It without manually editing the form.

Root causes (verified live against https://solana-mainnet.g.alchemy.com/v2/docs-demo):

getTokenAccounts

  • The spec listed programId, commitment, minContextSlot, dataSlice, and encoding as optional params. None of these exist on the Alchemy DAS proxy:
    "unknown field `programId`, expected one of `ownerAddress`, `mintAddress`, `limit`,
    `page`, `before`, `after`, `displayOptions`, `options`, `cursor`"
    
    These look copy-pasted from the standard Solana RPC getTokenAccountsByOwner shape but DAS does not accept them.
  • ownerAddress was required: false, so Try It did not auto-fill the example, and the server then rejected with Either 'ownerAddress' or 'mintAddress' must be provided.

searchAssets

  • The Alchemy DAS proxy enforces ownerAddress on every call, including with other filters (creatorAddress / authorityAddress / grouping), returning Database Error: Custom Error: No owner address provided. The spec marked it required: false.
  • delegateAddress is a phantom field (server expects delegate).
  • mutable is a phantom field (not in the server's allow-list).
  • grouping was typed as array of string with a single-string example, but the server requires a 2-tuple [groupKey, groupValue] (e.g., ["collection", "<collectionAddress>"]).

Changes

src/openrpc/alchemy/solana-das/solana-das.yaml:

getTokenAccounts:

  • ownerAddressrequired: true (the example value now auto-populates the Try It form).
  • Removed phantom params: programId, commitment, minContextSlot, dataSlice, encoding.
  • Added the actually-supported params that were missing: page, before, after, displayOptions, options.showZeroBalance.

searchAssets:

  • ownerAddressrequired: true.
  • Renamed delegateAddressdelegate (server name).
  • Removed phantom mutable.
  • Fixed grouping to a 2-tuple shape (["<groupKey>", "<groupValue>"]).
  • Added missing accepted params: tokenType (enum), compressed, compressible, supplyMint, royaltyTargetType, royaltyTarget, royaltyAmount, name, cursor, displayOptions, options.*.

Verification

After the change, sending the Try It defaults end-to-end:

# getTokenAccounts → 200 OK, 100 token accounts returned
{"params":{"ownerAddress":"86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY","page":1,"limit":100}}

# searchAssets → 200 OK, 50 items returned
{"params":{"ownerAddress":"86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY","tokenType":"all",
           "sortBy":{"sortBy":"created","sortDirection":"asc"},"limit":50,"page":1,
           "negate":false,"conditionType":"all"}}

pnpm run generate:rpc and pnpm run validate:rpc both pass.

Out of scope

  • Full schema audit of result shapes for both methods.
  • The parallel Photon API Try It issue (DOCS-72) is a separate fix already in review.

Linear

DOCS-73 — https://linear.app/alchemyapi/issue/DOCS-73/solana-das-try-it-defaults-broken-for-gettokenaccounts-and

Requested by

@dexterliu (via Slack thread)

…searchAssets

Both methods rendered Try It forms whose defaulted values were rejected by the Alchemy DAS proxy:

- getTokenAccounts spec listed phantom params (programId, commitment, minContextSlot, dataSlice, encoding) that the server returns 'unknown field' for. ownerAddress was required: false so the example value did not auto-fill, then the server rejected with 'Either ownerAddress or mintAddress must be provided'.
- searchAssets spec marked ownerAddress optional (server enforces it on every call), used delegateAddress instead of the server's delegate, included a non-existent mutable field, and shipped a single-string grouping schema while the server requires a 2-tuple [groupKey, groupValue].

Changes:

- getTokenAccounts: ownerAddress is now required: true, phantom params removed, missing supported params added (page, before, after, displayOptions, options.showZeroBalance).
- searchAssets: ownerAddress is now required: true, delegateAddress renamed to delegate, mutable removed, grouping fixed to a 2-tuple shape, missing accepted params added (tokenType, compressed, compressible, supplyMint, royaltyTargetType, royaltyTarget, royaltyAmount, name, displayOptions, options.*).

Verified the new defaults end-to-end against solana-mainnet.g.alchemy.com/v2/docs-demo for both methods.

Refs DOCS-73

Requested-by: @dexterliu
@JackReacher0807 JackReacher0807 requested a review from a team as a code owner May 7, 2026 21:03
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

🔗 Preview Mode

Name Status Preview Updated (UTC)
Alchemy Docs ✅ Ready 🔗 Visit Preview May 8, 2026, 9:05 PM

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 97c177bbbd

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/openrpc/alchemy/solana-das/solana-das.yaml
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

🔍 Link Check

Status: ⏭️ Skipped (no content changes)

View workflow run

…flict params

After live-probing the Alchemy DAS proxy more carefully, several additional issues that the first commit did not address:

- supply: server expects u64, our spec had it as object {printMaxSupply, printCurrentSupply}. Server returns 'invalid type: map, expected u64' on every call that includes supply. Fixed to integer.
- sortBy.sortBy enum: server uses snake_case 'recent_action', our spec used camelCase 'recentAction' across all 5 DAS methods that have a sortBy block (getAssetsByAuthority, getAssetsByOwner, getAssetsByGroup, getAssetsByCreator, searchAssets). Picking 'recentAction' from the form would error with 'unknown variant'. Fixed across all 5.
- options vs displayOptions: server treats them as the same field and rejects 'duplicate field options' if both are present. Removed displayOptions from both getTokenAccounts and searchAssets, kept options as the canonical name, documented the alias in the description.
- ownerType vs tokenType: server treats them as mutually exclusive ('ownerType is not supported when using tokenType field'). Removed ownerType from searchAssets — tokenType is the modern, upstream-recommended way.
- royaltyTargetType: was untyped string, server enforces enum [creators, fanout, single].
- royaltyTarget: was string, server expects a Pubkey (validates it).
- royaltyAmount: documented basis-points range [0, 10000].
- supply: minimum 0 added.

Verified end-to-end against solana-mainnet.g.alchemy.com/v2/docs-demo with the realistic Try It payload (example values + form defaults) for both methods.

Refs DOCS-73

Requested-by: @dexterliu
… tokenType)

Fern's Try It auto-populates enum-typed optional fields with their first enum value when no example value is provided. With both 'interface' and 'tokenType' listed, the form sends 'interface': 'V1_NFT' alongside 'tokenType': 'all', and the server rejects with 'interface is not supported when using tokenType field'.

Confirmed via live probing that 'interface' is the ONLY top-level optional that mutually excludes with 'tokenType' on the Alchemy DAS proxy. All other optionals (creatorVerified, compressed, compressible, frozen, burnt, negate, name, jsonUri, creatorAddress, authorityAddress, delegate, supplyMint, royaltyTarget, royaltyAmount, supply, royaltyTargetType) pair fine.

Dropping 'interface' from the spec since 'tokenType' is the modern, upstream-recommended path and covers the common cases. Documented the exclusion in the tokenType description so callers using the raw API know the legacy interface filter still exists server-side.

Verified the realistic Try It payload returns 200 OK with 50 items.

Refs DOCS-73

Requested-by: @dexterliu
…eld semantics

Reported on Slack: a user pasted a wallet pubkey into the Try It form and got 0 results. The descriptions on ownerAddress ("The owner address to filter token accounts by") and mintAddress ("The mint address to filter token accounts by. Can be used in place of ownerAddress") are too terse to make the field choice obvious — a user can read mintAddress's description as 'put any address here' and end up filtering owner=86xCn AND mint=HDKX, which intersects to zero.

Tightened both descriptions:
- ownerAddress now explicitly says 'wallet address whose token accounts you want to list' and frames it as the common case.
- mintAddress now leads with 'INSTEAD OF ownerAddress' so it is clear this is a mint, not a wallet, and tells the user to leave it empty when they only want owner-scoped results.

Verified live: HDKXtYrMrSxZ9rXrSYnVX52AWVvtsojNauCfxcooMdJb passed solely as ownerAddress returns 100 token accounts; with the same value also pasted into mintAddress, the result correctly drops to 0.

Refs DOCS-73

Requested-by: @dexterliu
Server's tokenType enum is case-sensitive: it accepts 'fungible', 'nonFungible', 'regularNFT', 'compressedNFT', 'all' (NFT in uppercase). Our spec had 'regularNft' / 'compressedNft' (lowercase nft) which Helius's upstream docs also use, but the Alchemy DAS proxy returns:

  unknown variant 'regularNft', expected one of 'fungible', 'nonFungible', 'regularNFT', 'compressedNFT', 'all'

Picking either lowercase variant from the Try It enum dropdown would yield zero results / an error. Fixed the enum to match the server. The example value remains 'all' so the default Try It payload is unaffected.

Refs DOCS-73

Requested-by: @dexterliu
…s as [])

Fern's Try It auto-populates array-typed optional fields with an empty array. The Alchemy DAS server requires grouping to be a strict 2-element tuple ['<groupKey>', '<groupValue>'], so any auto-filled empty array yields:

  invalid length 0, expected a tuple of size 2

There is no way to express 'auto-fill with a 2-tuple matching the server' in OpenRPC's draft-07 schema in a way that produces sensible default Try It values: dropping minItems/maxItems makes Fern fill ['string'] (length 1, still rejected), adding an example forces every Try It run to filter by that specific collection, and a default-tuple value would require choosing a real collection address to put in the spec.

Removing 'grouping' from the params list so the Try It form no longer auto-fills it. The collection-grouping filter is still supported by the underlying API; documented this in the searchAssets method description so power users know to pass it directly when calling the API from their own client.

Verified the realistic Try It payload (example values + all schema defaults + first-enum-of-unmapped-enums + all booleans=false) now returns 33-50 items end-to-end against solana-mainnet.g.alchemy.com/v2/docs-demo.

Refs DOCS-73

Requested-by: @dexterliu
… zero results

Andrei reported the example response is empty (no error, but no items). Live-reproduced the cause: Fern's Try It auto-populates inline scalar optionals (type: string and type: integer with no default and not in the example) with type-based placeholders ("string" and 1 respectively). For Pubkey-typed fields that go through a $ref, this does not happen, which is why getTokenAccounts works even with mintAddress/cursor/before/after listed.

For searchAssets, four inline-scalar filters silently filter the result to zero when auto-filled:

  name='string'       → 0 results (name substring match)
  jsonUri='string'    → 0 results (URI exact match)
  royaltyAmount=1     → 0 results (basis-points exact match)
  supply=1            → 3 results (still narrows aggressively)

Confirmed end-to-end: with all four sent, total=0 with no error — exactly Andrei's symptom. The Pubkey-typed fields (creatorAddress, authorityAddress, delegate, supplyMint, royaltyTarget) are NOT auto-filled because they go through a $ref to base-types/Pubkey, so they do not contribute. royaltyTargetType (enum) auto-fills with 'creators' and that alone returns 3 items, so it stays.

Removed name, jsonUri, royaltyAmount, supply from the params list. Documented in the searchAssets method description that these (plus grouping from the previous commit) are still supported when called from a user's own client. Verified the realistic Try It payload now returns 50 items end-to-end for both the example owner and Andrei's test address.

Refs DOCS-73

Requested-by: @dexterliu
@dexterliu dexterliu self-requested a review May 8, 2026 21:06
dexterliu
dexterliu previously approved these changes May 8, 2026
@github-actions github-actions Bot dismissed dexterliu’s stale review May 8, 2026 21:07

@dexterliu you are listed as the originator of this docs request (via the Requested-by trailer on a docs-agent commit). Per the docs-agent self-review policy, the originator can't approve their own request. Please ask another team member to review.

@dexterliu dexterliu merged commit 46bb798 into main May 8, 2026
15 checks passed
@dexterliu dexterliu deleted the docs/solana-das-try-it-defaults branch May 8, 2026 21:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants