Skip to content

[Feat] Complete the typed read-only query surface #87

Description

@al-onyxprotocol

Summary

Complete the typed read-only query surface so that read-heavy consumers such as ADAMANT Explorer can use typed methods for every node query, without falling back to the generic api.get().

Motivation

These gaps were found while migrating ADAMANT Explorer to adamant-api v3, see Adamant-im/adamant-explorer#11. Closing them gives TypeScript consumers correct types for options the node already supports.

All node behavior below was verified against ADAMANT Node v0.10.0 (endless.adamant.im).

Detailed description

1. Shared CONTROL_PARAMETERS allows chat-only flags on /api/transactions

includeDirectTransfers and withoutDirectTransfers pass through the shared CONTROL_PARAMETERS set in src/api/utils.ts, but they are only valid for /api/chats/get and /api/chatrooms; node v0.10.0 rejects both on /api/transactions with Parameter is not supported. The type level is already scoped (ChatroomsOptions vs TransactionsOptions), but the runtime transformer is shared, so a typed getTransactions() call can produce a request the node rejects. Scope the control parameters per endpoint so /api/transactions requests cannot carry chat-only flags.

2. No typed method for accounts/top

The /api/accounts/top endpoint has no typed method or response DTO. Add getTopAccounts({limit, offset}). Note the endpoint is opt-in: the node registers the route only when started with topAccounts enabled (TOP=TRUE), since it sorts mem_accounts by balance on every request. The SDK method should exist regardless, like any other public API surface that depends on node configuration.

3. Option types miss parameters the node supports

  • GetBlocksOptions: no orderBy (the explorer uses height:desc)
  • GetDelegatesOptions: no orderBy (rate:asc)
  • GetPeersOptions: no orderBy (ip:asc) and no state filter (?state=2 verified working); consider version and broadhash as well

The options pass through at runtime, so plain JavaScript works, but TypeScript consumers get type errors for valid queries.

4. searchDelegates has no limit

The node supports limit on /api/delegates/search (verified), but the method signature accepts only q.

5. Document the condition composition model, with examples

Measurements in this comment show how the node composes mixed and:/or: chains: conditions are concatenated into one flat WHERE string in query-string order, the first condition's prefix is ignored, no parentheses are added, and SQL precedence applies (AND binds tighter than OR). None of this is covered by the querying-transactions guide today.

Consequences that the guide must spell out with worked examples:

  • Shapes like (A AND B) OR C are expressible by ordering conditions; A AND (B OR C) is not expressible at all
  • With transformTransactionQuery, the wire order of conditions follows the JS object key insertion order, so {and: {…}, or: {…}} and {or: {…}, and: {…}} can return different result sets

A runtime warning when a query mixes both groups would turn a silent wrong-result into a visible hint, at no maintenance cost.

The node-side documentation counterpart for docs.adamant.im is tracked separately in the Adamant-im/docs repository.

6. New block subscriptions (blocked by the node)

WebSocketClient handles only newTrans. Once Adamant-im/adamant#256 adds a newBlock client WebSocket event, expose a block subscription API so explorers and pools can stop polling /api/blocks.

Alternatives

Keep using the generic api.get() for the uncovered queries: works, but bypasses typing, and the gaps stay invisible to TypeScript consumers.

Proposed technical implementation

  • Scope control parameters per endpoint so /api/transactions requests cannot carry chat-only flags
  • Add getTopAccounts() with a response DTO
  • Add orderBy to GetBlocksOptions, GetDelegatesOptions, and GetPeersOptions; add state to GetPeersOptions
  • Add limit to searchDelegates
  • Document the condition composition model in the querying-transactions guide: flat WHERE string in query-string order, first-condition prefix ignored, SQL precedence, no grouping — with the worked examples from the measurements comment
  • Document that the options-object key order defines the wire order of conditions, and therefore the query semantics
  • Add a runtime warning when a query mixes and and or groups
  • After [Feat] Emit newBlock events over the client WebSocket API adamant#256: add newBlock subscription support to WebSocketClient

Verification: typed calls return responses identical to the equivalent raw queries (equal count values on a v0.10.0 node), tsc passes for the new options, and the documentation site reflects the added parameters.

Metadata

Metadata

Assignees

No one assigned

    Labels

    APIsAPI design, endpoints, and integrationsNodeJSBackend logic, APIs, and Node.js environmentTypeScriptCode and typing improvements in TypeScriptenhancementNew feature or request

    Fields

    No fields configured for Feature.

    Projects

    Status
    Planned

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions