Skip to content

fix(monitor): Fix TypeError in spokePoolAddress dedup#3167

Merged
mrice32 merged 4 commits intomasterfrom
ws-b3d8wj
Apr 7, 2026
Merged

fix(monitor): Fix TypeError in spokePoolAddress dedup#3167
mrice32 merged 4 commits intomasterfrom
ws-b3d8wj

Conversation

@mrice32
Copy link
Copy Markdown
Contributor

@mrice32 mrice32 commented Apr 7, 2026

Summary

  • Fixes TypeError: address.startsWith is not a function crash in the monitor bot introduced by improve: Fix noImplicitAny type crimes (1/n) #3157
  • SpokePoolClient.spokePoolAddress is an Address object, not a string. The noImplicitAny cleanup replaced working code that called .toNative() before passing to toAddressType() with a version that passes the Address object directly, which crashes when toAddressType calls .startsWith("0x") on it.
  • Deduplicates spoke pool addresses by converting to native strings via dedupArray, then converts back to Address via toAddressType — matching the original intent from refactor: Simplify Monitor balance reporting and delete TokenTransferClient #3111 more readably.

Why TypeScript didn't catch this

The relayer's tsconfig.json has both skipLibCheck: true and noImplicitAny: false. skipLibCheck prevents full type-checking of SDK .d.ts files, and when TypeScript can't resolve a type it silently infers any rather than erroring. So spokePoolAddress was typed as any, making toAddressType(any, number) valid — even though the actual runtime value is an Address object, not a string. Enabling noImplicitAny would have caught this at compile time.

Test plan

  • Verify monitor bot starts without TypeError: address.startsWith is not a function
  • Verify spoke pool address deduplication still works when the same address is deployed on multiple chains

🤖 Generated with Claude Code

…ss dedup

SpokePoolClient.spokePoolAddress is an Address object, not a string.
The noImplicitAny cleanup in #3157 replaced working code that called
.toNative() before passing to toAddressType() with a version that
passed the Address object directly, causing `address.startsWith is not
a function` at runtime.

Use the Address objects directly (skipping redundant toAddressType) and
deduplicate by string representation via Map since Set only deduplicates
objects by reference.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
bmzig
bmzig previously approved these changes Apr 7, 2026
Simplify the Map-based dedup to use dedupArray on native strings,
then convert back via toAddressType. Clearer intent, same result.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@mrice32
Copy link
Copy Markdown
Contributor Author

mrice32 commented Apr 7, 2026

@codex re-review

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: b1d6a56212

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Object.values(spokePoolClients).map(({ chainId, spokePoolAddress: address }) => toAddressType(address, chainId))
);
Object.values(spokePoolClients).map(({ spokePoolAddress }) => spokePoolAddress.toNative())
).map((address) => toAddressType(address, hubPoolClient.chainId));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve source chain when rebuilding deduped spoke addresses

After deduplicating with native strings, this maps every address back with hubPoolClient.chainId, which is the L1 EVM chain. constructSpokePoolClientsWithLookback can include non-EVM spoke pools (see getSpokePoolClientsForContract creating SVMSpokePoolClient for non-EVM chains), so a Solana/base58 spokePoolAddress will be reconstructed as if it were an EVM address and can fail parsing or produce the wrong Address type at runtime. The previous logic preserved each spoke pool’s own chain ID, so this introduces a regression specifically when SVM chains are enabled.

Useful? React with 👍 / 👎.

The previous commit used hubPoolClient.chainId (L1 EVM) when
reconstructing all addresses via toAddressType, which would
misclassify SVM spoke pool addresses as EvmAddress.

Instead, use the existing Address objects directly — they are already
correctly typed as EvmAddress/SvmAddress — and deduplicate by native
string representation via Map.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@mrice32
Copy link
Copy Markdown
Contributor Author

mrice32 commented Apr 7, 2026

@codex re-review.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Same logic, fewer lines. The comment now explains why a Map is used
(value-based dedup preserving Address subtypes).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@mrice32
Copy link
Copy Markdown
Contributor Author

mrice32 commented Apr 7, 2026

@codex re-review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@mrice32 mrice32 merged commit 472b851 into master Apr 7, 2026
4 checks passed
@mrice32 mrice32 deleted the ws-b3d8wj branch April 7, 2026 01:11
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.

2 participants