Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/chubby-flowers-learn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/mobile": patch
---

🐛 route owner rpc through alchemy
10 changes: 10 additions & 0 deletions src/utils/wagmi/owner.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import AsyncStorage from "@react-native-async-storage/async-storage";

import * as infra from "@account-kit/infra";
import { sdk } from "@farcaster/miniapp-sdk";
import { farcasterMiniApp as miniAppConnector } from "@farcaster/miniapp-wagmi-connector";
import { http } from "viem";
import * as chains from "viem/chains";
import { createConfig, createStorage, custom, injected } from "wagmi";

import alchemyAPIKey from "@exactly/common/alchemyAPIKey";
import chain from "@exactly/common/generated/chain";

import publicClient from "../publicClient";
Expand All @@ -15,6 +17,14 @@ const config = createConfig({
connectors: [miniAppConnector(), injected()],
transports: {
...Object.fromEntries(Object.values(chains).map((c) => [c.id, http()])),
...Object.values(infra).reduce<Record<number, ReturnType<typeof http>>>((result, item) => {
if (typeof item !== "object" || !("id" in item) || !("rpcUrls" in item)) return result;
const c = item as { id: number; rpcUrls: { alchemy?: { http?: readonly string[] } } };
const url = c.rpcUrls.alchemy?.http?.[0];
if (!url) return result;
result[c.id] = http(`${url}/${alchemyAPIKey}`);
return result;
}, {}),
Comment thread
dieguezguille marked this conversation as resolved.
Comment thread
dieguezguille marked this conversation as resolved.
Comment on lines +20 to +27
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Empty alchemyAPIKey on anvil creates broken Alchemy transports, overriding previously working public RPCs

When running locally with anvil, alchemyAPIKey is "" (empty string) as set in common/alchemyAPIKey.ts:12. The new reduce does not guard against this—it unconditionally interpolates the key into the URL at line 25, producing URLs like https://opt-mainnet.g.alchemy.com/v2/ (no API key). These broken Alchemy transports override the working public http() transports (from line 19) for every chain present in @account-kit/infra. The primary chain is unaffected because [chain.id]: custom(publicClient) on line 28 takes precedence, but any non-primary chain (e.g., mainnet, base) that a connected owner wallet might switch to will fail. The rest of the codebase guards against this: src/utils/publicClient.ts:9 checks alchemyAPIKey ? ... : http().

Suggested change
...Object.values(infra).reduce<Record<number, ReturnType<typeof http>>>((result, item) => {
if (typeof item !== "object" || !("id" in item) || !("rpcUrls" in item)) return result;
const c = item as { id: number; rpcUrls: { alchemy?: { http?: readonly string[] } } };
const url = c.rpcUrls.alchemy?.http?.[0];
if (!url) return result;
result[c.id] = http(`${url}/${alchemyAPIKey}`);
return result;
}, {}),
...(alchemyAPIKey
? Object.values(infra).reduce<Record<number, ReturnType<typeof http>>>((result, item) => {
if (typeof item !== "object" || !("id" in item) || !("rpcUrls" in item)) return result;
const c = item as { id: number; rpcUrls: { alchemy?: { http?: readonly string[] } } };
const url = c.rpcUrls.alchemy?.http?.[0];
if (!url) return result;
result[c.id] = http(`${url}/${alchemyAPIKey}`);
return result;
}, {})
: {}),
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

[chain.id]: custom(publicClient),
},
storage: createStorage({ key: "wagmi.owner", storage: AsyncStorage }),
Expand Down
Loading