fix(core): load wallet & network images on React Native#574
fix(core): load wallet & network images on React Native#574ignaciosantise wants to merge 2 commits into
Conversation
FetchUtil.fetchImage built its data URL with response.blob() + FileReader, but on React Native fetch(...).blob() throws "Creating blobs from 'ArrayBuffer' and 'ArrayBufferView' are not supported" for binary responses, so wallet and network images silently failed to load. Read the bytes via response.arrayBuffer() and base64-encode them into the data URL instead (dependency-free encoder, since RN guarantees neither Buffer nor btoa). Adds unit tests for fetchImage. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: ee0c466 The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Claude finished @ignaciosantise's task in 2m 42s —— View job Code Review
Found 1 issue(s)Issue 1:
|
| // responses, so Blob + FileReader can't be used to build the data URL | ||
| // (wallet/network images would silently fail to load). Read the bytes as | ||
| // an ArrayBuffer and base64-encode them into a data URL instead. | ||
| const arrayBuffer = await response.arrayBuffer(); |
There was a problem hiding this comment.
🤖 Auto Review Issue: fetchImage encodes error-response bodies as image data URLs
Severity: MEDIUM
Category: correctness
Tool: Claude Auto Review
Context:
- Pattern:
fetchImagecallsresponse.arrayBuffer()without first checkingresponse.ok.processResponse(used byget/post/etc.) does guard withresponse.ok;fetchImageis inconsistent. - Risk: For 4xx/5xx responses the error body is base64-encoded and returned as a data URL (e.g.
data:application/json;base64,...) instead ofundefined. Thecatchblock never fires becausearrayBuffer()itself succeeds on non-ok responses. - Impact: Callers receive a syntactically valid but semantically garbage data URL. The RN
Imagecomponent attempts (and silently fails) to render it rather than falling back to the placeholder as intended. - Trigger: Any image URL returning a non-2xx status (CDN 404, rate-limit 429, etc.).
Recommendation:
const response = await fetch(url, { headers });
if (!response.ok) {
return undefined;
}
const arrayBuffer = await response.arrayBuffer();There was a problem hiding this comment.
Good catch — this is valid. fetchImage does not guard on response.ok, so a 4xx/5xx would get base64-encoded into a data URL and RN's Image would fail silently instead of falling back to the placeholder.
Note this is not a regression — the previous blob() version had the same gap — but since we're rewriting this block it's the right place to fix it. Will add the if (!response.ok) return undefined; guard before arrayBuffer() (plus a test).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Problem
Wallet and network logos in the connect modal never load on React Native — the list shows only placeholder icons on both iOS and Android (wallet names load fine, since those come from plain JSON).
Root cause is in
FetchUtil.fetchImage(packages/core/src/utils/FetchUtil.ts), which builds the image data URL withresponse.blob()+FileReader.readAsDataURL:On React Native,
fetch(...).blob()for a binary (image) response throws:RN's
Blobimplementation can't be constructed from anArrayBufferbody, so the promise rejects,fetchImagereturnsundefined, andAssetUtil.getWalletImagefalls back to the placeholder. This is the only.blob()usage in the codebase.Observed with Expo SDK 56 / React Native 0.85.3 (New Architecture),
@reown/appkit-*@2.0.5. The imagefetchitself succeeds (HTTP 200,content-type: image/webp); only theblob()step fails.Fix
Read the response as an
ArrayBufferand base64-encode it into the data URL, avoidingBlob/FileReaderentirely:The base64 encoder is dependency-free — React Native guarantees neither a global
Buffernorbtoa, so relying on either would be fragile for a library.Tests
Adds unit tests for
fetchImage(ArrayBuffer → base64 data URL, default content-type,blob()not called, error →undefined). Fullpackages/coresuite passes:Verification
Patched into a multichain AppKit + wagmi app on Expo SDK 56 / RN 0.85.3:
🤖 Generated with Claude Code