Update indexer client#207
Conversation
Review or Edit in CodeSandboxOpen the branch in Web Editor • VS Code • Insiders |
|
|
|
@marino39 is attempting to deploy a commit to the Foundry development Team on Vercel. A member of the Team first needs to authorize it. |
Reviewer's GuideAdds 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 flowsequenceDiagram
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()
Class diagram for Indexer and IndexerGateway WebRPC clientsclassDiagram
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
Class diagram for WebRPC error hierarchy and helpersclassDiagram
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
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
Summary of ChangesHello @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
Using Gemini Code AssistThe 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
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 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
|
There was a problem hiding this comment.
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>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
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.
* 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>
* 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>
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:
Enhancements: