From 84e8cec255f34456cdf08476b747a6f08ae5b6a8 Mon Sep 17 00:00:00 2001 From: Francisco Rolotti <102830313+franrolotti@users.noreply.github.com> Date: Wed, 11 Mar 2026 12:00:49 +0100 Subject: [PATCH 1/4] feat: add explicit chain config support (Sepolia-ready) and remove Gnosis hardcoding --- README.md | 33 +++++++++++++++ src/components/auth/login-button-privy.tsx | 14 +++---- src/components/auth/login-button.tsx | 2 - .../connected-user/privy-provider.tsx | 36 +++++++++------- .../connected-user/provider-general.tsx | 34 +++++++++------ src/components/connected-user/provider.tsx | 6 +-- src/components/navbar/account-menu.tsx | 5 ++- src/components/navbar/account-section.tsx | 1 + src/components/navbar/account-widget.tsx | 37 +++++++--------- src/context/lib.tsx | 42 ++++++++++++++++--- src/hooks/use-bread-balance.ts | 4 +- src/utils/active-chain.ts | 7 +++- 12 files changed, 150 insertions(+), 71 deletions(-) diff --git a/README.md b/README.md index 5f15997..bbce28d 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,39 @@ function App() { } ``` +### Web3 Chain Configuration + +`BreadUIKitProvider` now supports explicit chain configuration. + +```tsx +import { BreadUIKitProvider } from "@breadcoop/ui"; +import { erc20Abi } from "viem"; + + + {children} +; +``` + +`chainId` is the primary target network used by login/switch-chain and reads. +`supportedChainIds` controls which chains are treated as connected vs unsupported. + +### Migration Notes + +- Preferred: pass `chainId` (and optionally `supportedChainIds`) explicitly. +- Legacy fallback: `isProd` is still accepted for backward compatibility (`true -> 100`, `false -> 31337`). +- For Sepolia, set `chainId={11155111}` to avoid automatic switching to Gnosis. + ## Components ### Typography diff --git a/src/components/auth/login-button-privy.tsx b/src/components/auth/login-button-privy.tsx index 09c91ff..8d0984f 100644 --- a/src/components/auth/login-button-privy.tsx +++ b/src/components/auth/login-button-privy.tsx @@ -5,13 +5,14 @@ import { ReactNode } from "react"; import LiftedButton from "../LiftedButton/LiftedButton"; import { ButtonShell } from "./button-shell"; import { App } from "../../interface/app"; -import { gnosis } from "viem/chains"; +import { useBreadUIKitContext } from "../../context/lib"; export interface LoginButtonPrivyProps { app: App; status: "CONNECTED" | "LOADING" | "UNSUPPORTED_CHAIN" | "NOT_CONNECTED"; label?: string; rightIcon?: ReactNode; + // Deprecated: chain behavior is now controlled via BreadUIKitProvider config. isProd?: boolean; } @@ -20,8 +21,8 @@ export const LoginButtonPrivy = ({ status, label = "Sign In", rightIcon, - isProd = true, }: LoginButtonPrivyProps) => { + const { chainId } = useBreadUIKitContext(); const className = app === "fund" ? "bg-primary-orange" @@ -42,7 +43,7 @@ export const LoginButtonPrivy = ({ return ( ); @@ -63,11 +64,11 @@ export const LoginButtonPrivy = ({ function SwitchNetwork({ activeWallet, - isProd, + chainId, className, }: { activeWallet: ConnectedWallet; - isProd: boolean; + chainId: number; className?: string; }) { return ( @@ -77,8 +78,7 @@ function SwitchNetwork({ if (!activeWallet) return; try { - const targetChainId = isProd ? gnosis.id : 31337; - await activeWallet.switchChain(targetChainId); + await activeWallet.switchChain(chainId); } catch (error) { console.error("Failed to switch chain:", error); } diff --git a/src/components/auth/login-button.tsx b/src/components/auth/login-button.tsx index 8e4c437..b1dab27 100644 --- a/src/components/auth/login-button.tsx +++ b/src/components/auth/login-button.tsx @@ -9,7 +9,6 @@ import { useAuthProvider } from "../../context/lib"; export const LoginButton = ({ label = "Sign In", - isProd, ...props }: LoginButtonPrivyProps) => { const authProvider = useAuthProvider(); @@ -18,7 +17,6 @@ export const LoginButton = ({ return ( ); diff --git a/src/components/connected-user/privy-provider.tsx b/src/components/connected-user/privy-provider.tsx index 0787711..5620348 100644 --- a/src/components/connected-user/privy-provider.tsx +++ b/src/components/connected-user/privy-provider.tsx @@ -1,23 +1,31 @@ "use client"; import { ReactNode, useMemo } from "react"; -import { anvil, gnosis } from "viem/chains"; +import { anvil, gnosis, sepolia } from "viem/chains"; import { type Hex } from "viem"; import { usePrivy, useWallets } from "@privy-io/react-auth"; import { TConnectedUserState, TUserConnected } from "."; import { ConnectedUserContext } from "./context"; +import { useBreadUIKitContext } from "../../context/lib"; interface IConnectedUserProviderPrivyProps { children: ReactNode; - isProd: boolean; +} + +function resolveChain(chainId: number) { + if (chainId === gnosis.id) return gnosis; + if (chainId === anvil.id) return anvil; + if (chainId === sepolia.id) return sepolia; + + return sepolia; } export function ConnectedUserProviderPrivy({ - isProd, children, }: IConnectedUserProviderPrivyProps) { const { ready, authenticated } = usePrivy(); const { wallets } = useWallets(); + const { chainId: configuredChainId, supportedChainIds } = useBreadUIKitContext(); const embeddedWallet = useMemo(() => { return wallets.find( @@ -36,25 +44,25 @@ export function ConnectedUserProviderPrivy({ } const address = embeddedWallet.address as Hex; - const chainId = embeddedWallet.chainId; + const walletChainId = embeddedWallet.chainId; + const currentChainId = walletChainId + ? parseInt(walletChainId.split(":")[1], 10) + : undefined; - const parsedChainId = chainId ? parseInt(chainId.split(":")[1]) : undefined; - - let _status: TUserConnected["status"] = "CONNECTED"; - if (isProd) { - _status = parsedChainId === gnosis.id ? "CONNECTED" : "UNSUPPORTED_CHAIN"; - } else { - _status = parsedChainId === anvil.id ? "CONNECTED" : "UNSUPPORTED_CHAIN"; - } + const isSupportedChain = + currentChainId !== undefined && supportedChainIds.includes(currentChainId); + const _status: TUserConnected["status"] = isSupportedChain + ? "CONNECTED" + : "UNSUPPORTED_CHAIN"; - const chain = isProd ? gnosis : anvil; + const chain = resolveChain(currentChainId ?? configuredChainId); return { status: _status, address, chain, }; - }, [ready, authenticated, embeddedWallet, isProd]); + }, [ready, authenticated, embeddedWallet, configuredChainId, supportedChainIds]); // Embedded wallets are never Safe wallets const isSafe = useMemo(() => { diff --git a/src/components/connected-user/provider-general.tsx b/src/components/connected-user/provider-general.tsx index 2728bdc..c751aa6 100644 --- a/src/components/connected-user/provider-general.tsx +++ b/src/components/connected-user/provider-general.tsx @@ -4,17 +4,26 @@ import { ReactNode, useMemo } from "react"; import { TConnectedUserState, TUserConnected } from "./interface"; import { useAccount } from "wagmi"; import { useAutoConnect } from "../../hooks/use-auto-connect"; -import { anvil, gnosis } from "viem/chains"; +import { anvil, gnosis, sepolia } from "viem/chains"; import { ConnectedUserContext } from "./context"; +import { useBreadUIKitContext } from "../../context/lib"; interface IConnectedUserProviderGeneralProps { children: ReactNode; - isProd: boolean; } -export function ConnectedUserProviderGeneral({ isProd, children }: IConnectedUserProviderGeneralProps) { +function resolveChain(chainId: number) { + if (chainId === gnosis.id) return gnosis; + if (chainId === anvil.id) return anvil; + if (chainId === sepolia.id) return sepolia; + + return sepolia; +} + +export function ConnectedUserProviderGeneral({ children }: IConnectedUserProviderGeneralProps) { const { isConnected, connector, address, status, chain } = useAccount(); const { isSafe } = useAutoConnect(connector); + const { chainId, supportedChainIds } = useBreadUIKitContext(); const user = useMemo(() => { if (status === "connecting" && !address) { @@ -25,20 +34,19 @@ export function ConnectedUserProviderGeneral({ isProd, children }: IConnectedUse return { status: "NOT_CONNECTED" }; } - let _staus: TUserConnected["status"] = "CONNECTED"; - if (isProd) { - _staus = - chain?.id === gnosis.id ? "CONNECTED" : "UNSUPPORTED_CHAIN"; - } else { - _staus = chain?.id === anvil.id ? "CONNECTED" : "UNSUPPORTED_CHAIN"; - } + const currentChainId = chain?.id; + const isSupportedChain = + currentChainId !== undefined && supportedChainIds.includes(currentChainId); + const userStatus: TUserConnected["status"] = isSupportedChain + ? "CONNECTED" + : "UNSUPPORTED_CHAIN"; return { - status: _staus, + status: userStatus, address, - chain: chain || (isProd ? gnosis : anvil), + chain: chain || resolveChain(chainId), }; - }, [isConnected, address, chain, status]); + }, [isConnected, address, chain, status, chainId, supportedChainIds]); const value = useMemo(() => ({ user, isSafe }), [user, isSafe]); diff --git a/src/components/connected-user/provider.tsx b/src/components/connected-user/provider.tsx index 316a2b2..7a19a67 100644 --- a/src/components/connected-user/provider.tsx +++ b/src/components/connected-user/provider.tsx @@ -7,11 +7,11 @@ import { ConnectedUserProviderGeneral } from "./provider-general"; interface IConnectedUserProviderProps { children: ReactNode; - isProd: boolean; + // Deprecated: chain behavior is now controlled via BreadUIKitProvider config. + isProd?: boolean; } export function ConnectedUserProvider({ - isProd, children, }: IConnectedUserProviderProps) { const authProvider = useAuthProvider(); @@ -21,5 +21,5 @@ export function ConnectedUserProvider({ ? ConnectedUserProviderPrivy : ConnectedUserProviderGeneral; - return {children}; + return {children}; } diff --git a/src/components/navbar/account-menu.tsx b/src/components/navbar/account-menu.tsx index 55364ea..25bcc36 100644 --- a/src/components/navbar/account-menu.tsx +++ b/src/components/navbar/account-menu.tsx @@ -1,7 +1,7 @@ "use client"; import * as NavigationMenu from "@radix-ui/react-navigation-menu"; -import { type Address } from "viem"; +import { type Address, type Chain } from "viem"; import { Body } from "../typography/Typography"; import { truncateAddress } from "../../utils/truncate-address"; import { CaretDownIcon } from "@phosphor-icons/react"; @@ -12,11 +12,13 @@ import { appsConfig } from "../../utils/app"; export interface AccountMenuProps extends Pick { userAddress: Address; + chain: Chain; app: App; } const AccountMenu = ({ userAddress, + chain, ensNameResult, app, widgetItems, @@ -44,6 +46,7 @@ const AccountMenu = ({ diff --git a/src/components/navbar/account-widget.tsx b/src/components/navbar/account-widget.tsx index c787a56..659a7ae 100644 --- a/src/components/navbar/account-widget.tsx +++ b/src/components/navbar/account-widget.tsx @@ -2,7 +2,6 @@ import { ArrowUpRightIcon, - CopyIcon, GraphIcon, UserCircleIcon, WalletIcon, @@ -13,21 +12,19 @@ import { UseEnsNameReturnType } from "wagmi"; import { GetEnsNameReturnType } from "@wagmi/core"; import { Body } from "../typography/Typography"; import { truncateAddress } from "../../utils/truncate-address"; -import { copyToClipboard } from "../../utils/copy-to-clipboard"; import { Logo } from "../Logo"; import LogoutButton from "./log-out"; import { App } from "../../interface/app"; import { appsConfig } from "../../utils/app"; import { useBreadBalance } from "../../hooks/use-bread-balance"; -import { Address } from "viem"; +import { Address, type Chain } from "viem"; import NavAccountWidgetItem from "./account-widget-item"; import { FormattedDecimalNumber } from "../typography/formatted-dec-num"; import { CopyButtonIcon } from "../buttons"; -const GNOSIS_LINK = "https://gnosisscan.io/address/"; - export interface NavAccountDetailsProps { userAddress: Address; + chain: Chain; ensNameResult: UseEnsNameReturnType | { data: string | undefined; isLoading: boolean; @@ -42,6 +39,7 @@ export interface NavAccountDetailsProps { const NavAccountDetails = ({ className, userAddress, + chain, ensNameResult, app, widgetItems, @@ -50,6 +48,8 @@ const NavAccountDetails = ({ const { BREAD } = useBreadBalance({ address: userAddress }); const appIconColor = appsConfig[app].text; + const explorerUrl = chain.blockExplorers?.default.url; + const accountUrl = explorerUrl ? `${explorerUrl}/address/${userAddress || ""}` : undefined; return ( - - - + {accountUrl ? ( + + + + ) : null} - - Gnosis chain + {chain.name} {actionItems} diff --git a/src/context/lib.tsx b/src/context/lib.tsx index b5f9e03..23fad52 100644 --- a/src/context/lib.tsx +++ b/src/context/lib.tsx @@ -26,6 +26,8 @@ type TokenConfig = { type BreadUIKitContextType = { isProd: boolean; + chainId: number; + supportedChainIds: number[]; tokenConfig: TokenConfig; app: App; authProvider: AuthProvider; @@ -37,24 +39,52 @@ export const BreadUIKitContext = createContext< export const BreadUIKitProvider = ({ isProd, + chainId, + supportedChainIds, tokenConfig, children, app, authProvider, }: { - isProd: boolean; + isProd?: boolean; + chainId?: number; + supportedChainIds?: number[]; tokenConfig: TokenConfig; app: App; authProvider: AuthProvider; children: React.ReactNode; }) => { - if (isProd) { - tokenConfig.BREAD.address = - "0xa555d5344f6FB6c65da19e403Cb4c1eC4a1a5Ee3"; - } + const legacyIsProd = isProd ?? true; + const effectiveChainId = chainId ?? (legacyIsProd ? 100 : 31337); + const effectiveSupportedChainIds = + supportedChainIds && supportedChainIds.length > 0 + ? supportedChainIds + : [effectiveChainId]; + const effectiveIsProd = isProd ?? effectiveChainId === 100; + + const resolvedTokenConfig = { + ...tokenConfig, + BREAD: { + ...tokenConfig.BREAD, + // Keep legacy behavior only when the chain is still derived from isProd. + address: + chainId === undefined && effectiveIsProd + ? "0xa555d5344f6FB6c65da19e403Cb4c1eC4a1a5Ee3" + : tokenConfig.BREAD.address, + }, + }; return ( - + {children} ); diff --git a/src/hooks/use-bread-balance.ts b/src/hooks/use-bread-balance.ts index 5576dc1..cfc7f95 100644 --- a/src/hooks/use-bread-balance.ts +++ b/src/hooks/use-bread-balance.ts @@ -1,12 +1,10 @@ import { Address, erc20Abi, formatUnits } from "viem"; import { useBlock, useReadContract } from "wagmi"; import { useBreadUIKitContext } from "../context/lib"; -import { getActiveChainId } from "../utils/active-chain"; import { useEffect, useMemo } from "react"; export const useBreadBalance = ({ address }: { address: Address }) => { - const { tokenConfig, isProd } = useBreadUIKitContext(); - const chainId = getActiveChainId(isProd); + const { tokenConfig, chainId } = useBreadUIKitContext(); const { data: blockNumber } = useBlock({ watch: true, chainId }); const { diff --git a/src/utils/active-chain.ts b/src/utils/active-chain.ts index 66df5b2..5f71035 100644 --- a/src/utils/active-chain.ts +++ b/src/utils/active-chain.ts @@ -1 +1,6 @@ -export const getActiveChainId = (isProd: boolean) => isProd ? 100 : 31337; +export const getActiveChainId = (chainIdOrIsProd: number | boolean) => { + if (typeof chainIdOrIsProd === "number") return chainIdOrIsProd; + + // Deprecated fallback for legacy callers. + return chainIdOrIsProd ? 100 : 31337; +}; From d4fbec0f62155d0228b8e82a58961d61e240b948 Mon Sep 17 00:00:00 2001 From: Francisco Rolotti <102830313+franrolotti@users.noreply.github.com> Date: Wed, 11 Mar 2026 12:24:20 +0100 Subject: [PATCH 2/4] fix: avoid forced sepolia fallback and remove ignored isProd component props --- src/components/auth/login-button-privy.tsx | 2 -- .../connected-user/privy-provider.tsx | 10 +------ .../connected-user/provider-general.tsx | 10 +------ src/components/connected-user/provider.tsx | 11 +------ .../connected-user/resolve-chain.ts | 29 +++++++++++++++++++ 5 files changed, 32 insertions(+), 30 deletions(-) create mode 100644 src/components/connected-user/resolve-chain.ts diff --git a/src/components/auth/login-button-privy.tsx b/src/components/auth/login-button-privy.tsx index 8d0984f..19d1df5 100644 --- a/src/components/auth/login-button-privy.tsx +++ b/src/components/auth/login-button-privy.tsx @@ -12,8 +12,6 @@ export interface LoginButtonPrivyProps { status: "CONNECTED" | "LOADING" | "UNSUPPORTED_CHAIN" | "NOT_CONNECTED"; label?: string; rightIcon?: ReactNode; - // Deprecated: chain behavior is now controlled via BreadUIKitProvider config. - isProd?: boolean; } export const LoginButtonPrivy = ({ diff --git a/src/components/connected-user/privy-provider.tsx b/src/components/connected-user/privy-provider.tsx index 5620348..089ba3a 100644 --- a/src/components/connected-user/privy-provider.tsx +++ b/src/components/connected-user/privy-provider.tsx @@ -1,25 +1,17 @@ "use client"; import { ReactNode, useMemo } from "react"; -import { anvil, gnosis, sepolia } from "viem/chains"; import { type Hex } from "viem"; import { usePrivy, useWallets } from "@privy-io/react-auth"; import { TConnectedUserState, TUserConnected } from "."; import { ConnectedUserContext } from "./context"; import { useBreadUIKitContext } from "../../context/lib"; +import { resolveChain } from "./resolve-chain"; interface IConnectedUserProviderPrivyProps { children: ReactNode; } -function resolveChain(chainId: number) { - if (chainId === gnosis.id) return gnosis; - if (chainId === anvil.id) return anvil; - if (chainId === sepolia.id) return sepolia; - - return sepolia; -} - export function ConnectedUserProviderPrivy({ children, }: IConnectedUserProviderPrivyProps) { diff --git a/src/components/connected-user/provider-general.tsx b/src/components/connected-user/provider-general.tsx index c751aa6..9c35860 100644 --- a/src/components/connected-user/provider-general.tsx +++ b/src/components/connected-user/provider-general.tsx @@ -4,22 +4,14 @@ import { ReactNode, useMemo } from "react"; import { TConnectedUserState, TUserConnected } from "./interface"; import { useAccount } from "wagmi"; import { useAutoConnect } from "../../hooks/use-auto-connect"; -import { anvil, gnosis, sepolia } from "viem/chains"; import { ConnectedUserContext } from "./context"; import { useBreadUIKitContext } from "../../context/lib"; +import { resolveChain } from "./resolve-chain"; interface IConnectedUserProviderGeneralProps { children: ReactNode; } -function resolveChain(chainId: number) { - if (chainId === gnosis.id) return gnosis; - if (chainId === anvil.id) return anvil; - if (chainId === sepolia.id) return sepolia; - - return sepolia; -} - export function ConnectedUserProviderGeneral({ children }: IConnectedUserProviderGeneralProps) { const { isConnected, connector, address, status, chain } = useAccount(); const { isSafe } = useAutoConnect(connector); diff --git a/src/components/connected-user/provider.tsx b/src/components/connected-user/provider.tsx index 7a19a67..5fa0878 100644 --- a/src/components/connected-user/provider.tsx +++ b/src/components/connected-user/provider.tsx @@ -1,19 +1,10 @@ "use client"; -import { ReactNode } from "react"; import { useAuthProvider } from "../../context/lib"; import { ConnectedUserProviderPrivy } from "./privy-provider"; import { ConnectedUserProviderGeneral } from "./provider-general"; -interface IConnectedUserProviderProps { - children: ReactNode; - // Deprecated: chain behavior is now controlled via BreadUIKitProvider config. - isProd?: boolean; -} - -export function ConnectedUserProvider({ - children, -}: IConnectedUserProviderProps) { +export function ConnectedUserProvider({ children }: { children: React.ReactNode }) { const authProvider = useAuthProvider(); const Provider = diff --git a/src/components/connected-user/resolve-chain.ts b/src/components/connected-user/resolve-chain.ts new file mode 100644 index 0000000..beee72e --- /dev/null +++ b/src/components/connected-user/resolve-chain.ts @@ -0,0 +1,29 @@ +import { type Chain } from "viem"; +import { anvil, gnosis, sepolia } from "viem/chains"; + +const KNOWN_CHAINS: Record = { + [gnosis.id]: gnosis, + [anvil.id]: anvil, + [sepolia.id]: sepolia, +}; + +function createFallbackChain(chainId: number): Chain { + return { + id: chainId, + name: `Chain ${chainId}`, + nativeCurrency: { + name: "Ether", + symbol: "ETH", + decimals: 18, + }, + rpcUrls: { + default: { + http: [], + }, + }, + }; +} + +export function resolveChain(chainId: number): Chain { + return KNOWN_CHAINS[chainId] || createFallbackChain(chainId); +} From 0a284d2b812b0a772ef8dfe82a5272dc711b7105 Mon Sep 17 00:00:00 2001 From: Francisco Rolotti <102830313+franrolotti@users.noreply.github.com> Date: Wed, 11 Mar 2026 12:31:39 +0100 Subject: [PATCH 3/4] fix: restore deprecated isProd TS props and harden Privy chainId parsing --- src/components/auth/login-button.tsx | 8 +++++++- src/components/connected-user/privy-provider.tsx | 6 +++++- src/components/connected-user/provider.tsx | 8 +++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/components/auth/login-button.tsx b/src/components/auth/login-button.tsx index b1dab27..8c6f8cb 100644 --- a/src/components/auth/login-button.tsx +++ b/src/components/auth/login-button.tsx @@ -7,10 +7,16 @@ import { import { LoginButtonGeneral } from "./login-button-general"; import { useAuthProvider } from "../../context/lib"; +export interface LoginButtonProps extends LoginButtonPrivyProps { + /** @deprecated Chain behavior is controlled via BreadUIKitProvider config. */ + isProd?: boolean; +} + export const LoginButton = ({ label = "Sign In", + isProd: _isProd, ...props -}: LoginButtonPrivyProps) => { +}: LoginButtonProps) => { const authProvider = useAuthProvider(); if (authProvider === "privy") { diff --git a/src/components/connected-user/privy-provider.tsx b/src/components/connected-user/privy-provider.tsx index 089ba3a..9ce2031 100644 --- a/src/components/connected-user/privy-provider.tsx +++ b/src/components/connected-user/privy-provider.tsx @@ -37,9 +37,13 @@ export function ConnectedUserProviderPrivy({ const address = embeddedWallet.address as Hex; const walletChainId = embeddedWallet.chainId; - const currentChainId = walletChainId + const parsedChainId = walletChainId ? parseInt(walletChainId.split(":")[1], 10) : undefined; + const currentChainId = + parsedChainId !== undefined && Number.isFinite(parsedChainId) + ? parsedChainId + : undefined; const isSupportedChain = currentChainId !== undefined && supportedChainIds.includes(currentChainId); diff --git a/src/components/connected-user/provider.tsx b/src/components/connected-user/provider.tsx index 5fa0878..d01ce32 100644 --- a/src/components/connected-user/provider.tsx +++ b/src/components/connected-user/provider.tsx @@ -4,7 +4,13 @@ import { useAuthProvider } from "../../context/lib"; import { ConnectedUserProviderPrivy } from "./privy-provider"; import { ConnectedUserProviderGeneral } from "./provider-general"; -export function ConnectedUserProvider({ children }: { children: React.ReactNode }) { +interface ConnectedUserProviderProps { + children: React.ReactNode; + /** @deprecated Chain behavior is controlled via BreadUIKitProvider config. */ + isProd?: boolean; +} + +export function ConnectedUserProvider({ children, isProd: _isProd }: ConnectedUserProviderProps) { const authProvider = useAuthProvider(); const Provider = From 8939b96ac33ef5b45d085d08d8038dbe24858e4c Mon Sep 17 00:00:00 2001 From: Francisco Rolotti <102830313+franrolotti@users.noreply.github.com> Date: Wed, 11 Mar 2026 12:39:47 +0100 Subject: [PATCH 4/4] fix: ensure configured chainId is always included in supportedChainIds to prevent unsupported loop --- src/context/lib.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/context/lib.tsx b/src/context/lib.tsx index 23fad52..f86c951 100644 --- a/src/context/lib.tsx +++ b/src/context/lib.tsx @@ -56,10 +56,14 @@ export const BreadUIKitProvider = ({ }) => { const legacyIsProd = isProd ?? true; const effectiveChainId = chainId ?? (legacyIsProd ? 100 : 31337); - const effectiveSupportedChainIds = - supportedChainIds && supportedChainIds.length > 0 - ? supportedChainIds - : [effectiveChainId]; + const effectiveSupportedChainIds = Array.from( + new Set([ + ...(supportedChainIds && supportedChainIds.length > 0 + ? supportedChainIds + : [effectiveChainId]), + effectiveChainId, + ]), + ); const effectiveIsProd = isProd ?? effectiveChainId === 100; const resolvedTokenConfig = {