diff --git a/account-kit/core/src/store/store.test.ts b/account-kit/core/src/store/store.test.ts
index b4148948e6..bd894f55ad 100644
--- a/account-kit/core/src/store/store.test.ts
+++ b/account-kit/core/src/store/store.test.ts
@@ -218,7 +218,157 @@ describe("createConfig tests", () => {
               "421614": {},
             },
           },
-          "version": 8,
+          "version": 9,
+        }
+      `);
+  });
+
+  it("should serialize/deserialize state correctly when using single chain config", async () => {
+    const config = createConfig({
+      chain: sepolia,
+      transport: alchemy({ rpcUrl: "/api/sepolia" }),
+      signerConnection: { rpcUrl: "/api/signer" },
+      sessionConfig: {
+        expirationTimeMs: 1000,
+      },
+      policyId: "test-policy-id",
+      storage: () => localStorage,
+    });
+
+    await config.store.persist.rehydrate();
+
+    config.store.setState({
+      accounts: createDefaultAccountState([sepolia]),
+    });
+
+    expect(JSON.parse(localStorage.getItem(DEFAULT_STORAGE_KEY) ?? "{}"))
+      .toMatchInlineSnapshot(`
+        {
+          "state": {
+            "accountConfigs": {
+              "11155111": {},
+            },
+            "chain": {
+              "blockExplorers": {
+                "default": {
+                  "apiUrl": "https://api-sepolia.etherscan.io/api",
+                  "name": "Etherscan",
+                  "url": "https://sepolia.etherscan.io",
+                },
+              },
+              "contracts": {
+                "ensRegistry": {
+                  "address": "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",
+                },
+                "ensUniversalResolver": {
+                  "address": "0xc8Af999e38273D658BE1b921b88A9Ddf005769cC",
+                  "blockCreated": 5317080,
+                },
+                "multicall3": {
+                  "address": "0xca11bde05977b3631167028862be2a173976ca11",
+                  "blockCreated": 751532,
+                },
+              },
+              "id": 11155111,
+              "name": "Sepolia",
+              "nativeCurrency": {
+                "decimals": 18,
+                "name": "Sepolia Ether",
+                "symbol": "ETH",
+              },
+              "rpcUrls": {
+                "alchemy": {
+                  "http": [
+                    "https://eth-sepolia.g.alchemy.com/v2",
+                  ],
+                },
+                "default": {
+                  "http": [
+                    "https://rpc.sepolia.org",
+                  ],
+                },
+              },
+              "testnet": true,
+            },
+            "config": {
+              "client": {
+                "connection": {
+                  "rpcUrl": "/api/signer",
+                },
+              },
+              "sessionConfig": {
+                "expirationTimeMs": 1000,
+              },
+            },
+            "connections": {
+              "__type": "Map",
+              "value": [
+                [
+                  11155111,
+                  {
+                    "chain": {
+                      "blockExplorers": {
+                        "default": {
+                          "apiUrl": "https://api-sepolia.etherscan.io/api",
+                          "name": "Etherscan",
+                          "url": "https://sepolia.etherscan.io",
+                        },
+                      },
+                      "contracts": {
+                        "ensRegistry": {
+                          "address": "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",
+                        },
+                        "ensUniversalResolver": {
+                          "address": "0xc8Af999e38273D658BE1b921b88A9Ddf005769cC",
+                          "blockCreated": 5317080,
+                        },
+                        "multicall3": {
+                          "address": "0xca11bde05977b3631167028862be2a173976ca11",
+                          "blockCreated": 751532,
+                        },
+                      },
+                      "id": 11155111,
+                      "name": "Sepolia",
+                      "nativeCurrency": {
+                        "decimals": 18,
+                        "name": "Sepolia Ether",
+                        "symbol": "ETH",
+                      },
+                      "rpcUrls": {
+                        "alchemy": {
+                          "http": [
+                            "https://eth-sepolia.g.alchemy.com/v2",
+                          ],
+                        },
+                        "default": {
+                          "http": [
+                            "https://rpc.sepolia.org",
+                          ],
+                        },
+                      },
+                      "testnet": true,
+                    },
+                    "policyId": "test-policy-id",
+                    "transport": {
+                      "__type": "Transport",
+                      "rpcUrl": "/api/sepolia",
+                    },
+                  },
+                ],
+              ],
+            },
+            "signerStatus": {
+              "isAuthenticating": false,
+              "isConnected": false,
+              "isDisconnected": false,
+              "isInitializing": true,
+              "status": "INITIALIZING",
+            },
+            "smartAccountClients": {
+              "11155111": {},
+            },
+          },
+          "version": 9,
         }
       `);
   });
diff --git a/account-kit/core/src/store/store.ts b/account-kit/core/src/store/store.ts
index 2b2d22395d..c55f576015 100644
--- a/account-kit/core/src/store/store.ts
+++ b/account-kit/core/src/store/store.ts
@@ -110,7 +110,7 @@ export const createAccountKitStore = (
             skipHydration: ssr,
             partialize: ({ signer, accounts, ...writeableState }) =>
               writeableState,
-            version: 8,
+            version: 9,
           })
         : () => createInitialStoreState(params)
     )
diff --git a/account-kit/react/src/components/dialog/dialog.tsx b/account-kit/react/src/components/dialog/dialog.tsx
index 32561bde20..42e4e477a8 100644
--- a/account-kit/react/src/components/dialog/dialog.tsx
+++ b/account-kit/react/src/components/dialog/dialog.tsx
@@ -1,3 +1,5 @@
+"use client";
+
 import { useCallback, useEffect, useState, type ReactNode } from "react";
 import { createPortal } from "react-dom";
 import { RemoveScroll } from "react-remove-scroll";
diff --git a/examples/ui-demo/src/app/config.tsx b/examples/ui-demo/src/app/config.tsx
new file mode 100644
index 0000000000..b01bf7c77b
--- /dev/null
+++ b/examples/ui-demo/src/app/config.tsx
@@ -0,0 +1,82 @@
+import { AuthCardHeader } from "@/components/shared/AuthCardHeader";
+import { alchemy, arbitrumSepolia } from "@account-kit/infra";
+import { cookieStorage, createConfig } from "@account-kit/react";
+import { AccountKitTheme } from "@account-kit/react/tailwind";
+import { QueryClient } from "@tanstack/react-query";
+
+export type Config = {
+  auth: {
+    showEmail: boolean;
+    showExternalWallets: boolean;
+    showPasskey: boolean;
+    addPasskey: boolean;
+  };
+  ui: {
+    theme: "light" | "dark";
+    primaryColor: {
+      dark: string;
+      light: string;
+    };
+    borderRadius: AccountKitTheme["borderRadius"];
+    illustrationStyle: "outline" | "linear" | "filled" | "flat";
+    logoLight:
+      | {
+          fileName: string;
+          fileSrc: string;
+        }
+      | undefined;
+    logoDark:
+      | {
+          fileName: string;
+          fileSrc: string;
+        }
+      | undefined;
+  };
+  supportUrl?: string;
+};
+
+export const DEFAULT_CONFIG: Config = {
+  auth: {
+    showEmail: true,
+    showExternalWallets: false,
+    showPasskey: true,
+    addPasskey: true,
+  },
+  ui: {
+    theme: "light",
+    primaryColor: {
+      light: "#363FF9",
+      dark: "#9AB7FF",
+    },
+    borderRadius: "sm",
+    illustrationStyle: "outline",
+    logoLight: undefined,
+    logoDark: undefined,
+  },
+};
+
+export const queryClient = new QueryClient();
+
+export const alchemyConfig = createConfig(
+  {
+    transport: alchemy({ rpcUrl: "/api/rpc" }),
+    chain: arbitrumSepolia,
+    ssr: true,
+    policyId: process.env.NEXT_PUBLIC_PAYMASTER_POLICY_ID,
+    storage: cookieStorage,
+  },
+  {
+    illustrationStyle: DEFAULT_CONFIG.ui.illustrationStyle,
+    auth: {
+      sections: [[{ type: "email" as const }], [{ type: "passkey" as const }]],
+      addPasskeyOnSignup: DEFAULT_CONFIG.auth.addPasskey,
+      header: (
+        <AuthCardHeader
+          theme={DEFAULT_CONFIG.ui.theme}
+          logoDark={DEFAULT_CONFIG.ui.logoDark}
+          logoLight={DEFAULT_CONFIG.ui.logoLight}
+        />
+      ),
+    },
+  }
+);
diff --git a/examples/ui-demo/src/app/layout.tsx b/examples/ui-demo/src/app/layout.tsx
index c6bf51eda9..23e7d9f1b3 100644
--- a/examples/ui-demo/src/app/layout.tsx
+++ b/examples/ui-demo/src/app/layout.tsx
@@ -1,5 +1,8 @@
+import { cookieToInitialState } from "@account-kit/core";
 import type { Metadata } from "next";
 import { Inter } from "next/font/google";
+import { headers } from "next/headers";
+import { alchemyConfig } from "./config";
 import "./globals.css";
 import { Providers } from "./providers";
 
@@ -15,10 +18,15 @@ export default function RootLayout({
 }: Readonly<{
   children: React.ReactNode;
 }>) {
+  const initialState = cookieToInitialState(
+    alchemyConfig,
+    headers().get("cookie") ?? undefined
+  );
+
   return (
     <html lang="en" className="light">
       <body className={inter.className}>
-        <Providers>{children}</Providers>
+        <Providers initialState={initialState}>{children}</Providers>
       </body>
     </html>
   );
diff --git a/examples/ui-demo/src/app/page.tsx b/examples/ui-demo/src/app/page.tsx
index b74cd9a6ba..5078f7ef5e 100644
--- a/examples/ui-demo/src/app/page.tsx
+++ b/examples/ui-demo/src/app/page.tsx
@@ -1,22 +1,22 @@
 "use client";
 
+import { useConfig } from "@/app/state";
 import { Authentication } from "@/components/configuration/Authentication";
 import { Styling } from "@/components/configuration/Styling";
+import { MobileSplashPage } from "@/components/preview/MobileSplashPage";
+import {
+  EOAPostLoginActions,
+  EOAPostLoginContents,
+} from "@/components/shared/eoa-post-login/EOAPostLoginContents";
+import { RenderUserConnectionAvatar } from "@/components/shared/user-connection-avatar/RenderUserConnectionAvatar";
+import { cn } from "@/lib/utils";
+import { useUser } from "@account-kit/react";
 import { Inter, Public_Sans } from "next/font/google";
 import { useState } from "react";
 import { AuthCardWrapper } from "../components/preview/AuthCardWrapper";
 import { CodePreview } from "../components/preview/CodePreview";
 import { CodePreviewSwitch } from "../components/shared/CodePreviewSwitch";
 import { TopNav } from "../components/topnav/TopNav";
-import { RenderUserConnectionAvatar } from "@/components/shared/user-connection-avatar/RenderUserConnectionAvatar";
-import { useUser } from "@account-kit/react";
-import { MobileSplashPage } from "@/components/preview/MobileSplashPage";
-import { cn } from "@/lib/utils";
-import { useConfig } from "@/app/state";
-import {
-  EOAPostLoginContents,
-  EOAPostLoginActions,
-} from "@/components/shared/eoa-post-login/EOAPostLoginContents";
 
 const publicSans = Public_Sans({
   subsets: ["latin"],
diff --git a/examples/ui-demo/src/app/providers.tsx b/examples/ui-demo/src/app/providers.tsx
index 6b98fe713b..c3e3965f1c 100644
--- a/examples/ui-demo/src/app/providers.tsx
+++ b/examples/ui-demo/src/app/providers.tsx
@@ -1,45 +1,23 @@
 "use client";
 
-import { AuthCardHeader } from "@/components/shared/AuthCardHeader";
-import { alchemy, arbitrumSepolia } from "@account-kit/infra";
-import { AlchemyAccountProvider, createConfig } from "@account-kit/react";
-import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
-import { PropsWithChildren, Suspense } from "react";
-import { ConfigContextProvider, DEFAULT_CONFIG } from "./state";
 import { ToastProvider } from "@/contexts/ToastProvider";
+import { AlchemyClientState } from "@account-kit/core";
+import { AlchemyAccountProvider } from "@account-kit/react";
+import { QueryClientProvider } from "@tanstack/react-query";
+import { PropsWithChildren, Suspense } from "react";
+import { alchemyConfig, queryClient } from "./config";
+import { ConfigContextProvider } from "./state";
 
-const queryClient = new QueryClient();
-
-const alchemyConfig = createConfig(
-  {
-    transport: alchemy({ rpcUrl: "/api/rpc" }),
-    chain: arbitrumSepolia,
-    ssr: true,
-    policyId: process.env.NEXT_PUBLIC_PAYMASTER_POLICY_ID,
-  },
-  {
-    illustrationStyle: DEFAULT_CONFIG.ui.illustrationStyle,
-    auth: {
-      sections: [[{ type: "email" as const }], [{ type: "passkey" as const }]],
-      addPasskeyOnSignup: DEFAULT_CONFIG.auth.addPasskey,
-      header: (
-        <AuthCardHeader
-          theme={DEFAULT_CONFIG.ui.theme}
-          logoDark={DEFAULT_CONFIG.ui.logoDark}
-          logoLight={DEFAULT_CONFIG.ui.logoLight}
-        />
-      ),
-    },
-  }
-);
-
-export const Providers = (props: PropsWithChildren<{}>) => {
+export const Providers = (
+  props: PropsWithChildren<{ initialState?: AlchemyClientState }>
+) => {
   return (
     <Suspense>
       <QueryClientProvider client={queryClient}>
         <AlchemyAccountProvider
           config={alchemyConfig}
           queryClient={queryClient}
+          initialState={props.initialState}
         >
           <ToastProvider>
             <ConfigContextProvider>{props.children}</ConfigContextProvider>
diff --git a/examples/ui-demo/src/app/state.tsx b/examples/ui-demo/src/app/state.tsx
index 51859fb2df..05b4f3bdca 100644
--- a/examples/ui-demo/src/app/state.tsx
+++ b/examples/ui-demo/src/app/state.tsx
@@ -1,3 +1,5 @@
+"use client";
+
 import { AuthCardHeader } from "@/components/shared/AuthCardHeader";
 import {
   AlchemyAccountsUIConfig,
@@ -5,7 +7,6 @@ import {
   useUiConfig,
 } from "@account-kit/react";
 import {
-  AccountKitTheme,
   getBorderRadiusBaseVariableName,
   getBorderRadiusValue,
   getColorVariableName,
@@ -19,37 +20,7 @@ import {
   useEffect,
   useState,
 } from "react";
-
-export type Config = {
-  auth: {
-    showEmail: boolean;
-    showExternalWallets: boolean;
-    showPasskey: boolean;
-    addPasskey: boolean;
-  };
-  ui: {
-    theme: "light" | "dark";
-    primaryColor: {
-      dark: string;
-      light: string;
-    };
-    borderRadius: AccountKitTheme["borderRadius"];
-    illustrationStyle: "outline" | "linear" | "filled" | "flat";
-    logoLight:
-      | {
-          fileName: string;
-          fileSrc: string;
-        }
-      | undefined;
-    logoDark:
-      | {
-          fileName: string;
-          fileSrc: string;
-        }
-      | undefined;
-  };
-  supportUrl?: string;
-};
+import { Config, DEFAULT_CONFIG } from "./config";
 
 export type ConfigContextType = {
   config: Config;
@@ -58,26 +29,6 @@ export type ConfigContextType = {
   setNFTTransfered: Dispatch<SetStateAction<boolean>>;
 };
 
-export const DEFAULT_CONFIG: Config = {
-  auth: {
-    showEmail: true,
-    showExternalWallets: false,
-    showPasskey: true,
-    addPasskey: true,
-  },
-  ui: {
-    theme: "light",
-    primaryColor: {
-      light: "#363FF9",
-      dark: "#9AB7FF",
-    },
-    borderRadius: "sm",
-    illustrationStyle: "outline",
-    logoLight: undefined,
-    logoDark: undefined,
-  },
-};
-
 export const ConfigContext = createContext<ConfigContextType>({
   config: DEFAULT_CONFIG,
   setConfig: () => undefined,
diff --git a/examples/ui-demo/src/components/preview/AuthCardWrapper.tsx b/examples/ui-demo/src/components/preview/AuthCardWrapper.tsx
index 234549ddd2..37b10cc3a6 100644
--- a/examples/ui-demo/src/components/preview/AuthCardWrapper.tsx
+++ b/examples/ui-demo/src/components/preview/AuthCardWrapper.tsx
@@ -1,9 +1,10 @@
+"use client";
+
 import { useConfig } from "@/app/state";
 import { cn } from "@/lib/utils";
-import { AuthCard, useSmartAccountClient, useUser } from "@account-kit/react";
-import { MintCard } from "../shared/MintCard";
-import { LoadingIcon } from "../icons/loading";
+import { AuthCard, useUser } from "@account-kit/react";
 import { EOAPostLogin } from "../shared/eoa-post-login/EOAPostLogin";
+import { MintCard } from "../shared/MintCard";
 
 export function AuthCardWrapper({ className }: { className?: string }) {
   const { config } = useConfig();
@@ -25,10 +26,7 @@ export function AuthCardWrapper({ className }: { className?: string }) {
 
 const RenderContent = () => {
   const user = useUser();
-  const { client } = useSmartAccountClient({ type: "LightAccount" });
-
   const hasUser = !!user;
-  const hasClient = !!client;
 
   if (!hasUser) {
     return (
@@ -42,14 +40,6 @@ const RenderContent = () => {
 
   const isEOAUser = user.type === "eoa";
 
-  if (hasClient) {
-    return (
-      <div className="py-14 pt-20">
-        <MintCard />
-      </div>
-    );
-  }
-
   if (isEOAUser) {
     return (
       <div className="py-14 pt-20 h-full lg:h-auto">
@@ -58,5 +48,9 @@ const RenderContent = () => {
     );
   }
 
-  return <LoadingIcon />;
+  return (
+    <div className="py-14 pt-20">
+      <MintCard />
+    </div>
+  );
 };
diff --git a/examples/ui-demo/src/components/preview/CodePreview.tsx b/examples/ui-demo/src/components/preview/CodePreview.tsx
index d503646e9e..4164c4b863 100644
--- a/examples/ui-demo/src/components/preview/CodePreview.tsx
+++ b/examples/ui-demo/src/components/preview/CodePreview.tsx
@@ -1,4 +1,5 @@
-import { Config, DEFAULT_CONFIG, useConfig } from "@/app/state";
+import { Config, DEFAULT_CONFIG } from "@/app/config";
+import { useConfig } from "@/app/state";
 import dedent from "dedent";
 import { Check, Copy } from "lucide-react";
 import { useState } from "react";
@@ -141,7 +142,7 @@ function getConfigCode(config: Config) {
 
   return dedent`
   import { AlchemyAccountsUIConfig, createConfig } from "@account-kit/react";
-  import { sepolia } from "@account-kit/infra";
+  import { sepolia, alchemy } from "@account-kit/infra";
   import { QueryClient } from "@tanstack/react-query";
 
   const uiConfig: AlchemyAccountsUIConfig = {
@@ -161,7 +162,7 @@ function getConfigCode(config: Config) {
   export const config = createConfig({
     // if you don't want to leak api keys, you can proxy to a backend and set the rpcUrl instead here
     // get this from the app config you create at https://dashboard.alchemy.com/accounts
-    apiKey: "your-api-key",
+    transport: alchemy({ apiKey: "your-api-key" }),
     chain: sepolia,
     ssr: true, // set to false if you're not using server-side rendering
   }, uiConfig);
diff --git a/examples/ui-demo/src/components/shared/AuthCardHeader.tsx b/examples/ui-demo/src/components/shared/AuthCardHeader.tsx
index 752f101869..7c8c5b6bf2 100644
--- a/examples/ui-demo/src/components/shared/AuthCardHeader.tsx
+++ b/examples/ui-demo/src/components/shared/AuthCardHeader.tsx
@@ -1,4 +1,4 @@
-import { Config } from "@/app/state";
+import { Config } from "@/app/config";
 
 export function AuthCardHeader({
   logoDark,
diff --git a/examples/ui-demo/src/components/shared/MintCard.tsx b/examples/ui-demo/src/components/shared/MintCard.tsx
index c747a95c62..f3b81ff11c 100644
--- a/examples/ui-demo/src/components/shared/MintCard.tsx
+++ b/examples/ui-demo/src/components/shared/MintCard.tsx
@@ -1,21 +1,21 @@
 "use client";
-import Image from "next/image";
-import { CheckIcon } from "../icons/check";
-import { GasIcon } from "../icons/gas";
-import { DrawIcon } from "../icons/draw";
-import { ReceiptIcon } from "../icons/receipt";
-import React, { useCallback, useState } from "react";
-import { LoadingIcon } from "../icons/loading";
-import { ExternalLinkIcon } from "../icons/external-link";
+import { useConfig } from "@/app/state";
+import { useToast } from "@/hooks/useToast";
+import { AccountKitNftMinterABI, nftContractAddress } from "@/utils/config";
 import {
   useSendUserOperation,
   useSmartAccountClient,
 } from "@account-kit/react";
-import { AccountKitNftMinterABI, nftContractAddress } from "@/utils/config";
-import { encodeFunctionData } from "viem";
-import { useConfig } from "@/app/state";
 import { useQuery } from "@tanstack/react-query";
-import { useToast } from "@/hooks/useToast";
+import Image from "next/image";
+import { useCallback, useState } from "react";
+import { encodeFunctionData } from "viem";
+import { CheckIcon } from "../icons/check";
+import { DrawIcon } from "../icons/draw";
+import { ExternalLinkIcon } from "../icons/external-link";
+import { GasIcon } from "../icons/gas";
+import { LoadingIcon } from "../icons/loading";
+import { ReceiptIcon } from "../icons/receipt";
 
 type NFTLoadingState = "loading" | "success";
 
@@ -60,7 +60,9 @@ export const MintCard = () => {
     });
   };
 
-  const { client } = useSmartAccountClient({ type: "LightAccount" });
+  const { client, isLoadingClient } = useSmartAccountClient({
+    type: "LightAccount",
+  });
   const { sendUserOperationResult, sendUserOperation } = useSendUserOperation({
     client,
     waitForTxn: true,
@@ -196,7 +198,10 @@ export const MintCard = () => {
         {!nftTransfered ? (
           <button
             className="btn btn-primary w-full p-2 radius mb-4"
-            disabled={Object.values(status).some((x) => x === "loading")}
+            disabled={
+              Object.values(status).some((x) => x === "loading") ||
+              isLoadingClient
+            }
             onClick={handleCollectNFT}
           >
             Collect NFT