Skip to content

Update indexer client#207

Merged
Dargon789 merged 8 commits intoDargon789:wagmi-projectfrom
0xsequence:update_indexer_client
Jan 17, 2026
Merged

Update indexer client#207
Dargon789 merged 8 commits intoDargon789:wagmi-projectfrom
0xsequence:update_indexer_client

Conversation

@Dargon789
Copy link
Owner

@Dargon789 Dargon789 commented Jan 17, 2026

0xsequence@2aa79b5

Summary by Sourcery

Add autogenerated TypeScript clients for the Indexer and IndexerGateway services, exposing the full indexer RPC schema and streaming APIs.

New Features:

  • Introduce a typed Indexer client for interacting with indexer RPC endpoints, including balance, token, marketplace, transaction, webhook, and subscription APIs.
  • Add an IndexerGateway client for cross-chain indexer access, including multi-chain balances, prices, chains listing, and transaction history.

Enhancements:

  • Provide shared WebRPC error types, JSON helpers, and query key helpers to integrate the indexer clients with existing fetching/caching layers.

@codesandbox
Copy link

codesandbox bot commented Jan 17, 2026

Review or Edit in CodeSandbox

Open the branch in Web EditorVS CodeInsiders

Open Preview

@bolt-new-by-stackblitz
Copy link

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@vercel
Copy link

vercel bot commented Jan 17, 2026

@marino39 is attempting to deploy a commit to the Foundry development Team on Vercel.

A member of the Team first needs to authorize it.

@sourcery-ai
Copy link

sourcery-ai bot commented Jan 17, 2026

Reviewer's Guide

Adds new autogenerated TypeScript WebRPC clients for the Indexer and IndexerGateway services, exposing the full v0.4.0 indexer schema, streaming helpers, error types, and query key utilities under packages/indexer/src.

Sequence diagram for Indexer subscribeReceipts streaming flow

sequenceDiagram
  actor App
  participant IndexerClient
  participant IndexerServiceClient as Indexer
  participant FetchFunction as FetchFn
  participant IndexerServer

  App->>IndexerClient: subscribeReceipts(req, options)
  IndexerClient->>IndexerServiceClient: create AbortController
  IndexerServiceClient->>FetchFunction: fetch("/rpc/Indexer/SubscribeReceipts", httpRequest)
  FetchFunction-->>IndexerServer: HTTP POST with SSE
  IndexerServer-->>FetchFunction: HTTP 200 SSE stream
  FetchFunction-->>IndexerServiceClient: Response
  IndexerServiceClient->>IndexerServiceClient: sseResponse(res, options, retryFetch)
  IndexerServiceClient-->>App: onOpen()

  loop For each SSE event
    IndexerServer-->>IndexerServiceClient: JSON line with receipt or webrpcError
    alt Valid receipt message
      IndexerServiceClient-->>App: onMessage(SubscribeReceiptsResponse)
    else Error message with webrpcError
      IndexerServiceClient-->>App: onError(WebrpcError, retryFetch)
    end
  end

  alt Network error or timeout
    IndexerServiceClient-->>App: onError(WebrpcStreamLostError, retryFetch)
    App-->>IndexerServiceClient: retryFetch()
  end

  alt Client aborts
    App->>IndexerServiceClient: controller.abort(reason)
    IndexerServiceClient-->>App: onError(WebrpcClientAbortedError, noReconnect)
  end

  IndexerServiceClient-->>App: onClose()
Loading

Class diagram for Indexer and IndexerGateway WebRPC clients

classDiagram

class IndexerClient {
  <<interface>>
  +addWebhookListener(req: AddWebhookListenerRequest, headers: object, signal: AbortSignal) Promise~AddWebhookListenerResponse~
  +fetchTransactionReceipt(req: FetchTransactionReceiptRequest, headers: object, signal: AbortSignal) Promise~FetchTransactionReceiptResponse~
  +fetchTransactionReceiptWithFilter(req: FetchTransactionReceiptWithFilterRequest, headers: object, signal: AbortSignal) Promise~FetchTransactionReceiptWithFilterResponse~
  +getAllWebhookListeners(req: GetAllWebhookListenersRequest, headers: object, signal: AbortSignal) Promise~GetAllWebhookListenersResponse~
  +getBalanceUpdates(req: GetBalanceUpdatesRequest, headers: object, signal: AbortSignal) Promise~GetBalanceUpdatesResponse~
  +getChainID(headers: object, signal: AbortSignal) Promise~GetChainIDResponse~
  +getEtherBalance(req: GetEtherBalanceRequest, headers: object, signal: AbortSignal) Promise~GetEtherBalanceResponse~
  +getMarketplaceOrders(req: GetMarketplaceOrdersRequest, headers: object, signal: AbortSignal) Promise~GetMarketplaceOrdersResponse~
  +getMarketplaceTopOrders(req: GetMarketplaceTopOrdersRequest, headers: object, signal: AbortSignal) Promise~GetMarketplaceTopOrdersResponse~
  +getNativeTokenBalance(req: GetNativeTokenBalanceRequest, headers: object, signal: AbortSignal) Promise~GetNativeTokenBalanceResponse~
  +getTokenBalances(req: GetTokenBalancesRequest, headers: object, signal: AbortSignal) Promise~GetTokenBalancesResponse~
  +getTokenBalancesByContract(req: GetTokenBalancesByContractRequest, headers: object, signal: AbortSignal) Promise~GetTokenBalancesByContractResponse~
  +getTokenBalancesDetails(req: GetTokenBalancesDetailsRequest, headers: object, signal: AbortSignal) Promise~GetTokenBalancesDetailsResponse~
  +getTokenBalancesSummary(req: GetTokenBalancesSummaryRequest, headers: object, signal: AbortSignal) Promise~GetTokenBalancesSummaryResponse~
  +getTokenIDRanges(req: GetTokenIDRangesRequest, headers: object, signal: AbortSignal) Promise~GetTokenIDRangesResponse~
  +getTokenIDs(req: GetTokenIDsRequest, headers: object, signal: AbortSignal) Promise~GetTokenIDsResponse~
  +getTokenPrice(req: GetTokenPriceRequest, headers: object, signal: AbortSignal) Promise~GetTokenPriceResponse~
  +getTokenPrices(req: GetTokenPricesRequest, headers: object, signal: AbortSignal) Promise~GetTokenPricesResponse~
  +getTokenSupplies(req: GetTokenSuppliesRequest, headers: object, signal: AbortSignal) Promise~GetTokenSuppliesResponse~
  +getTokenSuppliesMap(req: GetTokenSuppliesMapRequest, headers: object, signal: AbortSignal) Promise~GetTokenSuppliesMapResponse~
  +getTransactionHistory(req: GetTransactionHistoryRequest, headers: object, signal: AbortSignal) Promise~GetTransactionHistoryResponse~
  +getWebhookListener(req: GetWebhookListenerRequest, headers: object, signal: AbortSignal) Promise~GetWebhookListenerResponse~
  +listTokenPrices(req: ListTokenPricesRequest, headers: object, signal: AbortSignal) Promise~ListTokenPricesResponse~
  +pauseAllWebhookListeners(req: PauseAllWebhookListenersRequest, headers: object, signal: AbortSignal) Promise~PauseAllWebhookListenersResponse~
  +ping(headers: object, signal: AbortSignal) Promise~PingResponse~
  +removeAllWebhookListeners(req: RemoveAllWebhookListenersRequest, headers: object, signal: AbortSignal) Promise~RemoveAllWebhookListenersResponse~
  +removeWebhookListener(req: RemoveWebhookListenerRequest, headers: object, signal: AbortSignal) Promise~RemoveWebhookListenerResponse~
  +resumeAllWebhookListeners(req: ResumeAllWebhookListenersRequest, headers: object, signal: AbortSignal) Promise~ResumeAllWebhookListenersResponse~
  +runtimeStatus(headers: object, signal: AbortSignal) Promise~RuntimeStatusResponse~
  +subscribeBalanceUpdates(req: SubscribeBalanceUpdatesRequest, options: WebrpcStreamOptions~SubscribeBalanceUpdatesResponse~) WebrpcStreamController
  +subscribeEvents(req: SubscribeEventsRequest, options: WebrpcStreamOptions~SubscribeEventsResponse~) WebrpcStreamController
  +subscribeReceipts(req: SubscribeReceiptsRequest, options: WebrpcStreamOptions~SubscribeReceiptsResponse~) WebrpcStreamController
  +syncBalance(req: SyncBalanceRequest, headers: object, signal: AbortSignal) Promise~SyncBalanceResponse~
  +toggleWebhookListener(req: ToggleWebhookListenerRequest, headers: object, signal: AbortSignal) Promise~ToggleWebhookListenerResponse~
  +updateWebhookListener(req: UpdateWebhookListenerRequest, headers: object, signal: AbortSignal) Promise~UpdateWebhookListenerResponse~
  +version(headers: object, signal: AbortSignal) Promise~VersionResponse~
}

class Indexer {
  -hostname: string
  -fetch: Fetch
  -path: string
  +constructor(hostname: string, fetch: Fetch)
  +queryKey: any
  +addWebhookListener(req: AddWebhookListenerRequest, headers: object, signal: AbortSignal) Promise~AddWebhookListenerResponse~
  +fetchTransactionReceipt(req: FetchTransactionReceiptRequest, headers: object, signal: AbortSignal) Promise~FetchTransactionReceiptResponse~
  +fetchTransactionReceiptWithFilter(req: FetchTransactionReceiptWithFilterRequest, headers: object, signal: AbortSignal) Promise~FetchTransactionReceiptWithFilterResponse~
  +getAllWebhookListeners(req: GetAllWebhookListenersRequest, headers: object, signal: AbortSignal) Promise~GetAllWebhookListenersResponse~
  +getBalanceUpdates(req: GetBalanceUpdatesRequest, headers: object, signal: AbortSignal) Promise~GetBalanceUpdatesResponse~
  +getChainID(headers: object, signal: AbortSignal) Promise~GetChainIDResponse~
  +getEtherBalance(req: GetEtherBalanceRequest, headers: object, signal: AbortSignal) Promise~GetEtherBalanceResponse~
  +getMarketplaceOrders(req: GetMarketplaceOrdersRequest, headers: object, signal: AbortSignal) Promise~GetMarketplaceOrdersResponse~
  +getMarketplaceTopOrders(req: GetMarketplaceTopOrdersRequest, headers: object, signal: AbortSignal) Promise~GetMarketplaceTopOrdersResponse~
  +getNativeTokenBalance(req: GetNativeTokenBalanceRequest, headers: object, signal: AbortSignal) Promise~GetNativeTokenBalanceResponse~
  +getTokenBalances(req: GetTokenBalancesRequest, headers: object, signal: AbortSignal) Promise~GetTokenBalancesResponse~
  +getTokenBalancesByContract(req: GetTokenBalancesByContractRequest, headers: object, signal: AbortSignal) Promise~GetTokenBalancesByContractResponse~
  +getTokenBalancesDetails(req: GetTokenBalancesDetailsRequest, headers: object, signal: AbortSignal) Promise~GetTokenBalancesDetailsResponse~
  +getTokenBalancesSummary(req: GetTokenBalancesSummaryRequest, headers: object, signal: AbortSignal) Promise~GetTokenBalancesSummaryResponse~
  +getTokenIDRanges(req: GetTokenIDRangesRequest, headers: object, signal: AbortSignal) Promise~GetTokenIDRangesResponse~
  +getTokenIDs(req: GetTokenIDsRequest, headers: object, signal: AbortSignal) Promise~GetTokenIDsResponse~
  +getTokenPrice(req: GetTokenPriceRequest, headers: object, signal: AbortSignal) Promise~GetTokenPriceResponse~
  +getTokenPrices(req: GetTokenPricesRequest, headers: object, signal: AbortSignal) Promise~GetTokenPricesResponse~
  +getTokenSupplies(req: GetTokenSuppliesRequest, headers: object, signal: AbortSignal) Promise~GetTokenSuppliesResponse~
  +getTokenSuppliesMap(req: GetTokenSuppliesMapRequest, headers: object, signal: AbortSignal) Promise~GetTokenSuppliesMapResponse~
  +getTransactionHistory(req: GetTransactionHistoryRequest, headers: object, signal: AbortSignal) Promise~GetTransactionHistoryResponse~
  +getWebhookListener(req: GetWebhookListenerRequest, headers: object, signal: AbortSignal) Promise~GetWebhookListenerResponse~
  +listTokenPrices(req: ListTokenPricesRequest, headers: object, signal: AbortSignal) Promise~ListTokenPricesResponse~
  +pauseAllWebhookListeners(req: PauseAllWebhookListenersRequest, headers: object, signal: AbortSignal) Promise~PauseAllWebhookListenersResponse~
  +ping(headers: object, signal: AbortSignal) Promise~PingResponse~
  +removeAllWebhookListeners(req: RemoveAllWebhookListenersRequest, headers: object, signal: AbortSignal) Promise~RemoveAllWebhookListenersResponse~
  +removeWebhookListener(req: RemoveWebhookListenerRequest, headers: object, signal: AbortSignal) Promise~RemoveWebhookListenerResponse~
  +resumeAllWebhookListeners(req: ResumeAllWebhookListenersRequest, headers: object, signal: AbortSignal) Promise~ResumeAllWebhookListenersResponse~
  +runtimeStatus(headers: object, signal: AbortSignal) Promise~RuntimeStatusResponse~
  +subscribeBalanceUpdates(req: SubscribeBalanceUpdatesRequest, options: WebrpcStreamOptions~SubscribeBalanceUpdatesResponse~) WebrpcStreamController
  +subscribeEvents(req: SubscribeEventsRequest, options: WebrpcStreamOptions~SubscribeEventsResponse~) WebrpcStreamController
  +subscribeReceipts(req: SubscribeReceiptsRequest, options: WebrpcStreamOptions~SubscribeReceiptsResponse~) WebrpcStreamController
  +syncBalance(req: SyncBalanceRequest, headers: object, signal: AbortSignal) Promise~SyncBalanceResponse~
  +toggleWebhookListener(req: ToggleWebhookListenerRequest, headers: object, signal: AbortSignal) Promise~ToggleWebhookListenerResponse~
  +updateWebhookListener(req: UpdateWebhookListenerRequest, headers: object, signal: AbortSignal) Promise~UpdateWebhookListenerResponse~
  +version(headers: object, signal: AbortSignal) Promise~VersionResponse~
}

class IndexerGatewayClient {
  <<interface>>
  +getBalanceUpdates(req: GetBalanceUpdatesRequest, headers: object, signal: AbortSignal) Promise~GetBalanceUpdatesResponse~
  +getChains(req: GetChainsRequest, headers: object, signal: AbortSignal) Promise~GetChainsResponse~
  +getNativeTokenBalance(req: GetNativeTokenBalanceRequest, headers: object, signal: AbortSignal) Promise~GetNativeTokenBalanceResponse~
  +getTokenBalances(req: GetTokenBalancesRequest, headers: object, signal: AbortSignal) Promise~GetTokenBalancesResponse~
  +getTokenBalancesByContract(req: GetTokenBalancesByContractRequest, headers: object, signal: AbortSignal) Promise~GetTokenBalancesByContractResponse~
  +getTokenBalancesDetails(req: GetTokenBalancesDetailsRequest, headers: object, signal: AbortSignal) Promise~GetTokenBalancesDetailsResponse~
  +getTokenBalancesSummary(req: GetTokenBalancesSummaryRequest, headers: object, signal: AbortSignal) Promise~GetTokenBalancesSummaryResponse~
  +getTokenPrice(req: GetTokenPriceRequest, headers: object, signal: AbortSignal) Promise~GetTokenPriceResponse~
  +getTokenPrices(req: GetTokenPricesRequest, headers: object, signal: AbortSignal) Promise~GetTokenPricesResponse~
  +getTransactionHistory(req: GetTransactionHistoryRequest, headers: object, signal: AbortSignal) Promise~GetTransactionHistoryResponse~
  +ping(headers: object, signal: AbortSignal) Promise~PingResponse~
  +runtimeStatus(headers: object, signal: AbortSignal) Promise~RuntimeStatusResponse~
  +version(headers: object, signal: AbortSignal) Promise~VersionResponse~
}

class IndexerGateway {
  -hostname: string
  -fetch: Fetch
  -path: string
  +constructor(hostname: string, fetch: Fetch)
  +queryKey: any
  +getBalanceUpdates(req: GetBalanceUpdatesRequest, headers: object, signal: AbortSignal) Promise~GetBalanceUpdatesResponse~
  +getChains(req: GetChainsRequest, headers: object, signal: AbortSignal) Promise~GetChainsResponse~
  +getNativeTokenBalance(req: GetNativeTokenBalanceRequest, headers: object, signal: AbortSignal) Promise~GetNativeTokenBalanceResponse~
  +getTokenBalances(req: GetTokenBalancesRequest, headers: object, signal: AbortSignal) Promise~GetTokenBalancesResponse~
  +getTokenBalancesByContract(req: GetTokenBalancesByContractRequest, headers: object, signal: AbortSignal) Promise~GetTokenBalancesByContractResponse~
  +getTokenBalancesDetails(req: GetTokenBalancesDetailsRequest, headers: object, signal: AbortSignal) Promise~GetTokenBalancesDetailsResponse~
  +getTokenBalancesSummary(req: GetTokenBalancesSummaryRequest, headers: object, signal: AbortSignal) Promise~GetTokenBalancesSummaryResponse~
  +getTokenPrice(req: GetTokenPriceRequest, headers: object, signal: AbortSignal) Promise~GetTokenPriceResponse~
  +getTokenPrices(req: GetTokenPricesRequest, headers: object, signal: AbortSignal) Promise~GetTokenPricesResponse~
  +getTransactionHistory(req: GetTransactionHistoryRequest, headers: object, signal: AbortSignal) Promise~GetTransactionHistoryResponse~
  +ping(headers: object, signal: AbortSignal) Promise~PingResponse~
  +runtimeStatus(headers: object, signal: AbortSignal) Promise~RuntimeStatusResponse~
  +version(headers: object, signal: AbortSignal) Promise~VersionResponse~
}

class WebrpcStreamOptions {
  +headers: HeadersInit
  +signal: AbortSignal
  +onMessage(message: any) void
  +onError(error: WebrpcError, reconnect: function) void
  +onOpen() void
  +onClose() void
}

class WebrpcStreamController {
  +abort(reason: any) void
  +closed: Promise~void~
}

class Fetch {
  <<type>>
}

IndexerClient <|.. Indexer
IndexerGatewayClient <|.. IndexerGateway
WebrpcStreamOptions --> WebrpcStreamController
Indexer --> Fetch
IndexerGateway --> Fetch
Loading

Class diagram for WebRPC error hierarchy and helpers

classDiagram

class WebrpcError {
  <<abstract>>
  +code: number
  +status: number
  +message: string
  +name: string
  +cause: string
  +constructor(error: WebrpcErrorParams)
  +static new(payload: any) WebrpcError
}

class WebrpcEndpointError {
  +constructor(error: WebrpcErrorParams)
}
class WebrpcRequestFailedError {
  +constructor(error: WebrpcErrorParams)
}
class WebrpcBadRouteError {
  +constructor(error: WebrpcErrorParams)
}
class WebrpcBadMethodError {
  +constructor(error: WebrpcErrorParams)
}
class WebrpcBadRequestError {
  +constructor(error: WebrpcErrorParams)
}
class WebrpcBadResponseError {
  +constructor(error: WebrpcErrorParams)
}
class WebrpcServerPanicError {
  +constructor(error: WebrpcErrorParams)
}
class WebrpcInternalErrorError {
  +constructor(error: WebrpcErrorParams)
}
class WebrpcClientAbortedError {
  +constructor(error: WebrpcErrorParams)
}
class WebrpcStreamLostError {
  +constructor(error: WebrpcErrorParams)
}
class WebrpcStreamFinishedError {
  +constructor(error: WebrpcErrorParams)
}

class AbortedError {
  +constructor(error: WebrpcErrorParams)
}
class AccessKeyMismatchError {
  +constructor(error: WebrpcErrorParams)
}
class AccessKeyNotFoundError {
  +constructor(error: WebrpcErrorParams)
}
class AtLeastOneKeyError {
  +constructor(error: WebrpcErrorParams)
}
class GeoblockedError {
  +constructor(error: WebrpcErrorParams)
}
class InvalidArgumentError {
  +constructor(error: WebrpcErrorParams)
}
class InvalidOriginError {
  +constructor(error: WebrpcErrorParams)
}
class InvalidServiceError {
  +constructor(error: WebrpcErrorParams)
}
class MaxAccessKeysError {
  +constructor(error: WebrpcErrorParams)
}
class MetadataCallFailedError {
  +constructor(error: WebrpcErrorParams)
}
class MethodNotFoundError {
  +constructor(error: WebrpcErrorParams)
}
class NoDefaultKeyError {
  +constructor(error: WebrpcErrorParams)
}
class NotFoundError {
  +constructor(error: WebrpcErrorParams)
}
class PermissionDeniedError {
  +constructor(error: WebrpcErrorParams)
}
class ProjectNotFoundError {
  +constructor(error: WebrpcErrorParams)
}
class QueryFailedError {
  +constructor(error: WebrpcErrorParams)
}
class QuotaExceededError {
  +constructor(error: WebrpcErrorParams)
}
class RateLimitError {
  +constructor(error: WebrpcErrorParams)
}
class RateLimitedError {
  +constructor(error: WebrpcErrorParams)
}
class RequestConflictError {
  +constructor(error: WebrpcErrorParams)
}
class ResourceExhaustedError {
  +constructor(error: WebrpcErrorParams)
}
class SessionExpiredError {
  +constructor(error: WebrpcErrorParams)
}
class TimeoutError {
  +constructor(error: WebrpcErrorParams)
}
class UnauthorizedError {
  +constructor(error: WebrpcErrorParams)
}
class UnauthorizedUserError {
  +constructor(error: WebrpcErrorParams)
}
class UnavailableError {
  +constructor(error: WebrpcErrorParams)
}

class WebrpcErrorParams {
  +name: string
  +code: number
  +message: string
  +status: number
  +cause: string
}

class WebrpcErrorCodes {
  <<enum>>
}
class errors {
  <<enum>>
}

class webrpcErrorByCode {
  <<map>>
  +[code: number]: any
}

WebrpcEndpointError --|> WebrpcError
WebrpcRequestFailedError --|> WebrpcError
WebrpcBadRouteError --|> WebrpcError
WebrpcBadMethodError --|> WebrpcError
WebrpcBadRequestError --|> WebrpcError
WebrpcBadResponseError --|> WebrpcError
WebrpcServerPanicError --|> WebrpcError
WebrpcInternalErrorError --|> WebrpcError
WebrpcClientAbortedError --|> WebrpcError
WebrpcStreamLostError --|> WebrpcError
WebrpcStreamFinishedError --|> WebrpcError

AbortedError --|> WebrpcError
AccessKeyMismatchError --|> WebrpcError
AccessKeyNotFoundError --|> WebrpcError
AtLeastOneKeyError --|> WebrpcError
GeoblockedError --|> WebrpcError
InvalidArgumentError --|> WebrpcError
InvalidOriginError --|> WebrpcError
InvalidServiceError --|> WebrpcError
MaxAccessKeysError --|> WebrpcError
MetadataCallFailedError --|> WebrpcError
MethodNotFoundError --|> WebrpcError
NoDefaultKeyError --|> WebrpcError
NotFoundError --|> WebrpcError
PermissionDeniedError --|> WebrpcError
ProjectNotFoundError --|> WebrpcError
QueryFailedError --|> WebrpcError
QuotaExceededError --|> WebrpcError
RateLimitError --|> WebrpcError
RateLimitedError --|> WebrpcError
RequestConflictError --|> WebrpcError
ResourceExhaustedError --|> WebrpcError
SessionExpiredError --|> WebrpcError
TimeoutError --|> WebrpcError
UnauthorizedError --|> WebrpcError
UnauthorizedUserError --|> WebrpcError
UnavailableError --|> WebrpcError

webrpcErrorByCode --> WebrpcError
Loading

File-Level Changes

Change Details Files
Introduce a full WebRPC TypeScript client for the Indexer service, including all schema types, methods, streaming support, and error handling.
  • Add IndexerClient interface with all RPC methods (balances, marketplace, webhooks, subscriptions, metadata, status, etc.) including deprecations and docs.
  • Implement Indexer class that wraps fetch with JSON encoding/decoding, shared request builder, and standardized WebRPC error mapping.
  • Provide SSE-based streaming utilities (sseResponse, WebrpcStreamOptions, WebrpcStreamController) for subscription-style methods with reconnect/error handling.
  • Define full RIDL schema types (balances, marketplace orders, tokens, metadata, runtime status, webhooks) and JSON helpers (JsonEncode/JsonDecode).
  • Expose a comprehensive hierarchy of WebRPC error classes, error code enums, and helpers such as VersionFromHeader and WebrpcHeaderValue.
packages/indexer/src/indexer.gen.ts
Introduce a WebRPC TypeScript client for the IndexerGateway aggregation service, mirroring the v0.4.0 gateway schema and error model.
  • Add IndexerGatewayClient interface and IndexerGateway class with methods for cross-chain balance queries, token prices, transaction history, chains listing, and health/version.
  • Reuse the same schema type definitions as the Indexer client where applicable, plus gateway-specific wrapper types (GatewayTokenBalance, GatewayNativeTokenBalance, GatewayPrice, etc.).
  • Implement shared HTTP request builder and JSON encode/decode helpers with WebRPC header management, matching the Indexer client conventions.
  • Define gateway-specific runtime status types and expose the same WebRPC error hierarchy and error-code mapping as the Indexer client.
  • Add VersionFromHeader and code-gen metadata constants for the IndexerGateway service to allow clients to introspect generator/schema versions.
packages/indexer/src/indexergw.gen.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@snyk-io
Copy link

snyk-io bot commented Jan 17, 2026

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@gemini-code-assist
Copy link

Summary of Changes

Hello @Dargon789, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces updated auto-generated TypeScript clients for the Indexer and IndexerGateway services. These new clients reflect the latest v0.4.0 schema version of the sequence-indexer and were generated using webrpc-gen@v0.31.2. This update ensures that the client-side code is synchronized with the most recent API definitions, providing access to new functionalities and improvements.

Highlights

  • New Indexer Client: Introduction of "packages/indexer/src/indexer.gen.ts", an auto-generated TypeScript client for the Indexer service.
  • New Indexer Gateway Client: Introduction of "packages/indexer/src/indexergw.gen.ts", an auto-generated TypeScript client for the IndexerGateway service.
  • Schema Version Update: Both new clients are generated based on "sequence-indexer v0.4.0" and "webrpc-gen@v0.31.2", indicating an update to the underlying API schema and code generation tools.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 4 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location> `packages/indexer/src/indexer.gen.ts:1974-1983` </location>
<code_context>
+  const intervalId = setInterval(() => {
</code_context>

<issue_to_address>
**issue (bug_risk):** The SSE timeout interval is only cleared on timeout, which can leak intervals for normal close and error paths.

`intervalId` is only cleared on timeout; for other exits (EOF, server close, parse/Network/AbortError, etc.) the interval keeps running until timeout even though the stream is done. Please ensure `clearInterval(intervalId)` is called on all completion paths, e.g. via a `finally` around the main loop or immediately before each `return`.
</issue_to_address>

### Comment 2
<location> `packages/indexer/src/indexer.gen.ts:1946-1955` </location>
<code_context>
+        continue
+      }
+      let data: any
+      try {
+        data = JSON.parse(line)
+        if (data.hasOwnProperty('webrpcError')) {
+          const error = data.webrpcError
+          const code: number = typeof error.code === 'number' ? error.code : 0
+          onError((webrpcErrorByCode[code] || WebrpcError).new(error), retryFetch)
+          return
+        }
+      } catch (error) {
+        if (error instanceof Error && error.message === 'Abort signal cannot be used to reconnect') {
+          throw error
+        }
+        onError(
+          WebrpcBadResponseError.new({
+            status: res.status,
+            cause: `JSON.parse(): ${error instanceof Error ? error.message : String(error)}`
+          }),
+          retryFetch
+        )
+      }
+      onMessage(data)
+    }
+
</code_context>

<issue_to_address>
**issue (bug_risk):** Parsing errors in SSE messages still result in `onMessage` being called with `undefined`.

When `JSON.parse(line)` throws, the catch calls `onError(...)` but then execution continues and `onMessage(data)` is still invoked with `data` left as `undefined`. This means consumers can receive `onMessage(undefined)` on parse failures.

Consider either continuing the loop/returning from the catch, or guarding the callback (e.g. `if (data !== undefined) onMessage(data)`) so `onMessage` is only called with successfully parsed payloads.
</issue_to_address>

### Comment 3
<location> `packages/indexer/src/indexer.gen.ts:2053-2059` </location>
<code_context>
+  }
+}
+
+const createHttpRequest = (body: string = '{}', headers: object = {}, signal: AbortSignal | null = null): object => {
+  const reqHeaders: { [key: string]: string } = {
+    ...headers,
+    'Content-Type': 'application/json',
+    [WebrpcHeader]: WebrpcHeaderValue
+  }
+  return { method: 'POST', headers: reqHeaders, body, signal }
+}
+
</code_context>

<issue_to_address>
**issue (bug_risk):** Spreading `headers: object` into `{[key:string]: string}` breaks for `Headers` instances and non-string values.

`createHttpRequest` currently takes `headers: object` and spreads it into `{ [key: string]: string }`, which is unsafe for the full `HeadersInit` surface:

- `Headers` instances (allowed by `WebrpcOptions.headers: HeadersInit`) won’t spread correctly because their entries aren’t enumerable own properties, so those headers are effectively dropped.
- The spread assumes all values are `string`, but `HeadersInit` can include other shapes/values, risking runtime `TypeError`s.

Consider typing `headers` as `HeadersInit` and either:
- Construct a `Headers` instance and pass that directly to `fetch`, or
- Only spread plain `Record<string, string>` objects and handle `Headers` and `string[][]` cases explicitly.

Otherwise, user-supplied headers may be silently ignored when provided as a `Headers` instance.
</issue_to_address>

### Comment 4
<location> `packages/indexer/src/indexergw.gen.ts:1092-1098` </location>
<code_context>
+  }
+}
+
+const createHttpRequest = (body: string = '{}', headers: object = {}, signal: AbortSignal | null = null): object => {
+  const reqHeaders: { [key: string]: string } = {
+    ...headers,
+    'Content-Type': 'application/json',
+    [WebrpcHeader]: WebrpcHeaderValue
+  }
+  return { method: 'POST', headers: reqHeaders, body, signal }
+}
+
</code_context>

<issue_to_address>
**issue (bug_risk):** Same header spreading issue exists in the gateway client’s `createHttpRequest`.

This helper mirrors the `Indexer` client issue: `headers` is typed as `object` but spread into `{ [key: string]: string }`. `Headers` instances and other `HeadersInit` values won’t spread correctly, and non-string values can cause runtime errors.

Consider normalizing from `HeadersInit` (or using a `Headers` object directly) before building `reqHeaders` to avoid silently dropping or mis-handling user-provided headers and to keep behavior consistent across clients.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@Dargon789 Dargon789 merged commit 81c62ba into Dargon789:wagmi-project Jan 17, 2026
8 of 14 checks passed
Repository owner deleted a comment from vercel bot Jan 17, 2026
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request updates the auto-generated indexer clients for both the Indexer and IndexerGateway services. The new generated code is a significant improvement, adopting more modern TypeScript practices. My review focuses on a few areas in the generated code that could be further improved, likely by making changes to the webrpc-gen tool. I've pointed out a few places where type safety could be enhanced and code could be made more maintainable.

Dargon789 added a commit that referenced this pull request Jan 19, 2026
* 0xsequence/sequence.js/master (#166)

* Pin foundry to v1.5.0 instead of nightly (0xsequence#947) (#134)

* Bump next from 15.5.7 to 15.5.9 (0xsequence#944)

Bumps [next](https://github.com/vercel/next.js) from 15.5.7 to 15.5.9.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](vercel/next.js@v15.5.7...v15.5.9)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 15.5.9
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Pin foundry to v1.5.0 instead of nightly (0xsequence#947)

* Include repo and extras in syncpack config to ensure deps are synced (0xsequence#945)

* Include repo and extras in syncpack config to ensure deps are synced across all

* Updating support deps

* Updating deps

* Updating pnpm lock

* Fixing type errors within wdk tests

* Short circuit 404s (0xsequence#949)

* skip witness on signers that don't support it

* add passkey to test

* 3.0.0-beta.6

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Taylan Pince <taylanpince@gmail.com>
Co-authored-by: Corban Riley <corbanbrook@gmail.com>
Co-authored-by: Agusx1211 <agusgit@pm.me>

* Update packages/wallet/wdk/test/wallets.test.ts

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com>

* Update packages/wallet/wdk/test/wallets.test.ts

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Taylan Pince <taylanpince@gmail.com>
Co-authored-by: Corban Riley <corbanbrook@gmail.com>
Co-authored-by: Agusx1211 <agusgit@pm.me>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* Fix apple auth scope (0xsequence#950)

* Fix apple auth scope

* Fix Apple auth scope test

* 3.0.0-beta.7

* Update apple auth scope (0xsequence#951)

* 3.0.0-beta.8

* dapp-client: export TransportMessage and MessageType

* Update indexer client (#207)

* [AUTOMATED] Update: proto/clients/indexer*.gen.ts

* [AUTOMATED] Update: proto/clients/indexer*.gen.ts

* [AUTOMATED] Update: proto/clients/indexer*.gen.ts

* [AUTOMATED] Update: proto/clients/indexer*.gen.ts

* [AUTOMATED] Update: proto/clients/indexer*.gen.ts

* [AUTOMATED] Update: proto/clients/indexer*.gen.ts

* [AUTOMATED] Update: proto/clients/indexer*.gen.ts

* [AUTOMATED] Update: proto/clients/indexer*.gen.ts

---------

Co-authored-by: marino39 <722509+marino39@users.noreply.github.com>
Co-authored-by: pkieltyka <18831+pkieltyka@users.noreply.github.com>
Co-authored-by: xiam <385670+xiam@users.noreply.github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Taylan Pince <taylanpince@gmail.com>
Co-authored-by: Corban Riley <corbanbrook@gmail.com>
Co-authored-by: Agusx1211 <agusgit@pm.me>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: tolgahan-arikan <tolgahan.arikan@gmail.com>
Co-authored-by: marino39 <722509+marino39@users.noreply.github.com>
Co-authored-by: pkieltyka <18831+pkieltyka@users.noreply.github.com>
Co-authored-by: xiam <385670+xiam@users.noreply.github.com>
Dargon789 added a commit that referenced this pull request Jan 19, 2026
* 0xsequence/sequence.js/master (#166)

* Pin foundry to v1.5.0 instead of nightly (0xsequence#947) (#134)

* Bump next from 15.5.7 to 15.5.9 (0xsequence#944)

Bumps [next](https://github.com/vercel/next.js) from 15.5.7 to 15.5.9.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](vercel/next.js@v15.5.7...v15.5.9)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 15.5.9
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Pin foundry to v1.5.0 instead of nightly (0xsequence#947)

* Include repo and extras in syncpack config to ensure deps are synced (0xsequence#945)

* Include repo and extras in syncpack config to ensure deps are synced across all

* Updating support deps

* Updating deps

* Updating pnpm lock

* Fixing type errors within wdk tests

* Short circuit 404s (0xsequence#949)

* skip witness on signers that don't support it

* add passkey to test

* 3.0.0-beta.6

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Taylan Pince <taylanpince@gmail.com>
Co-authored-by: Corban Riley <corbanbrook@gmail.com>
Co-authored-by: Agusx1211 <agusgit@pm.me>

* Update packages/wallet/wdk/test/wallets.test.ts

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com>

* Update packages/wallet/wdk/test/wallets.test.ts

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Taylan Pince <taylanpince@gmail.com>
Co-authored-by: Corban Riley <corbanbrook@gmail.com>
Co-authored-by: Agusx1211 <agusgit@pm.me>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* Fix apple auth scope (0xsequence#950)

* Fix apple auth scope

* Fix Apple auth scope test

* 3.0.0-beta.7

* Update apple auth scope (0xsequence#951)

* 3.0.0-beta.8

* dapp-client: export TransportMessage and MessageType

* Update indexer client (#207)

* [AUTOMATED] Update: proto/clients/indexer*.gen.ts

* [AUTOMATED] Update: proto/clients/indexer*.gen.ts

* [AUTOMATED] Update: proto/clients/indexer*.gen.ts

* [AUTOMATED] Update: proto/clients/indexer*.gen.ts

* [AUTOMATED] Update: proto/clients/indexer*.gen.ts

* [AUTOMATED] Update: proto/clients/indexer*.gen.ts

* [AUTOMATED] Update: proto/clients/indexer*.gen.ts

* [AUTOMATED] Update: proto/clients/indexer*.gen.ts

---------

Co-authored-by: marino39 <722509+marino39@users.noreply.github.com>
Co-authored-by: pkieltyka <18831+pkieltyka@users.noreply.github.com>
Co-authored-by: xiam <385670+xiam@users.noreply.github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Taylan Pince <taylanpince@gmail.com>
Co-authored-by: Corban Riley <corbanbrook@gmail.com>
Co-authored-by: Agusx1211 <agusgit@pm.me>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: tolgahan-arikan <tolgahan.arikan@gmail.com>
Co-authored-by: marino39 <722509+marino39@users.noreply.github.com>
Co-authored-by: pkieltyka <18831+pkieltyka@users.noreply.github.com>
Co-authored-by: xiam <385670+xiam@users.noreply.github.com>
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.

# Class diagram for new explicit session config utilities # Sequence diagram for Indexer subscribeReceipts streaming flow

4 participants