Add viem fallback client helper - #162
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new createViemFallbackClient helper to @goodwidget/core to create viem public/wallet clients backed by a cached Chainlist RPC list, and exposes it via both the package root and a @goodwidget/core/viemFallbackClient subpath.
Changes:
- Introduces
createViemFallbackClientwith RPC caching, refresh behavior, and fallback transport composition. - Exports the helper/types from the core root and adds a dedicated subpath build/export entry.
- Adds core README usage docs and adds
viemas a core dependency (lockfile updated accordingly).
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Updates lockfile to include viem and normalizes dependency resolutions. |
| packages/core/tsup.config.ts | Adds a viemFallbackClient entrypoint to the build output. |
| packages/core/src/viemFallbackClient.ts | Implements the Chainlist-backed RPC cache + viem fallback transport/client wrappers. |
| packages/core/src/index.ts | Re-exports the helper and associated public types from the package root. |
| packages/core/README.md | Documents usage patterns, storage adapters, and options for the new helper. |
| packages/core/package.json | Adds viem dependency and exports ./viemFallbackClient subpath. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
Suppressed comments (1)
packages/core/src/viemFallbackClient.ts:171
- When
sanitizeRpcUrls()filters out every URL,createFallbackTransportfalls back tohttp()with no URL. In viem this can resolve back to the chain’s default RPC URL, potentially re-introducing non-HTTPS endpoints and undermining the “only HTTPS RPCs are used” guarantee. Safer to fail closed (or require an explicittransport).
const rpcUrls = await getRpcUrls(chain, fallbackRpcs)
const transports = rpcUrls.length > 0 ? rpcUrls.map((rpcUrl) => http(rpcUrl)) : [http()]
return fallback(transports)
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
| const refreshRpcs = async (): Promise<void> => { | ||
| if (!fetchImpl) throw new Error('fetch is not available') | ||
|
|
||
| const chainlistUrl = new URL(chainlistRpcsUrl) | ||
|
|
There was a problem hiding this comment.
- caching seems to only set up the list and does not apply any testing. so if the list contains cors issues, rate limit issues it will keep the original fetched list through its caching cycle
Potential solution:
fallback(
[http(primaryRpc), http(backupRpc)],
{ rank: true, retryCount: 1 },
)-
Integrator level rpc's should always be taken as primary defaults before considering locall fallback defaults. currently it goes as: Chainlist URLs → caller fallbackRpcs → chain.rpcUrls.default.http
-
No comments or tests are supplied
-
too much overly type-checking of input that causes very verbose code and long if statements. could be reduced I think as a lot of data is kind of deterministic in their expected type.
Summary
createViemFallbackClientto@goodwidget/corefor cached Chainlist RPC discovery and viem fallback HTTP transports.@goodwidget/core/viemFallbackClientsubpath.Notes
viemas a core dependency and normalizing existing peer-resolution entries.Verification
pnpm --filter @goodwidget/core buildpnpm --filter @goodwidget/core lint