diff --git a/apps/wallet-ui/src/app/[ecosystem]/(ui)/layout.tsx b/apps/wallet-ui/src/app/[ecosystem]/(authed)/layout.tsx
similarity index 100%
rename from apps/wallet-ui/src/app/[ecosystem]/(ui)/layout.tsx
rename to apps/wallet-ui/src/app/[ecosystem]/(authed)/layout.tsx
diff --git a/apps/wallet-ui/src/app/[ecosystem]/(ui)/wallet/[address]/layout.tsx b/apps/wallet-ui/src/app/[ecosystem]/(authed)/wallet/[address]/layout.tsx
similarity index 86%
rename from apps/wallet-ui/src/app/[ecosystem]/(ui)/wallet/[address]/layout.tsx
rename to apps/wallet-ui/src/app/[ecosystem]/(authed)/wallet/[address]/layout.tsx
index 0b1b35c428d..735bbdd557c 100644
--- a/apps/wallet-ui/src/app/[ecosystem]/(ui)/wallet/[address]/layout.tsx
+++ b/apps/wallet-ui/src/app/[ecosystem]/(authed)/wallet/[address]/layout.tsx
@@ -1,11 +1,9 @@
import { ChainCombobox } from "@/components/ChainCombobox";
-import { getCurrentUser } from "@/lib/auth";
import { getChains } from "@/lib/chains";
import { client } from "@/lib/client";
import { getEcosystemInfo } from "@/lib/ecosystems";
import { SIMPLEHASH_NFT_SUPPORTED_CHAIN_IDS } from "@/util/simplehash";
import type { Metadata, ResolvingMetadata } from "next";
-import { redirect } from "next/navigation";
import { resolveName } from "thirdweb/extensions/ens";
import { shortenAddress } from "thirdweb/utils";
@@ -34,23 +32,17 @@ export default async function Layout({
children: React.ReactNode;
params: { ecosystem: string; address: string };
}) {
- const userAddressPromise = getCurrentUser();
const ensPromise = resolveName({
client,
address: params.address,
});
const thirdwebChainsPromise = getChains();
- const [userAddress, ens, thirdwebChains] = await Promise.all([
- userAddressPromise,
+ const [ens, thirdwebChains] = await Promise.all([
ensPromise,
thirdwebChainsPromise,
]);
- if (userAddress !== params.address) {
- redirect(`/wallet/${userAddress}`);
- }
-
const simpleHashChains = thirdwebChains.filter((chain) =>
SIMPLEHASH_NFT_SUPPORTED_CHAIN_IDS.includes(chain.chainId),
);
diff --git a/apps/wallet-ui/src/app/[ecosystem]/(ui)/wallet/[address]/loading.tsx b/apps/wallet-ui/src/app/[ecosystem]/(authed)/wallet/[address]/loading.tsx
similarity index 100%
rename from apps/wallet-ui/src/app/[ecosystem]/(ui)/wallet/[address]/loading.tsx
rename to apps/wallet-ui/src/app/[ecosystem]/(authed)/wallet/[address]/loading.tsx
diff --git a/apps/wallet-ui/src/app/[ecosystem]/(authed)/wallet/[address]/page.tsx b/apps/wallet-ui/src/app/[ecosystem]/(authed)/wallet/[address]/page.tsx
new file mode 100644
index 00000000000..5438a916a3b
--- /dev/null
+++ b/apps/wallet-ui/src/app/[ecosystem]/(authed)/wallet/[address]/page.tsx
@@ -0,0 +1,18 @@
+import { AutoConnectWalletConnect } from "@/components/AutoConnectWalletConnect";
+import NftGallery from "@/components/NftGallery";
+import { getAddress } from "thirdweb";
+
+export default function Page({
+ params: { address },
+ searchParams: { chainId, uri },
+}: {
+ params: { address: string };
+ searchParams: { chainId?: string; uri?: string };
+}) {
+ return (
+ <>
+
+
+ >
+ );
+}
diff --git a/apps/wallet-ui/src/app/[ecosystem]/(ui)/wallet/[address]/page.tsx b/apps/wallet-ui/src/app/[ecosystem]/(ui)/wallet/[address]/page.tsx
deleted file mode 100644
index 10228f3c0a3..00000000000
--- a/apps/wallet-ui/src/app/[ecosystem]/(ui)/wallet/[address]/page.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import NftGallery from "@/components/NftGallery";
-import { getAddress } from "thirdweb";
-
-export default async function Page({
- params: { address },
- searchParams: { chainId },
-}: {
- params: { address: string };
- searchParams: { chainId: string };
-}) {
- return ;
-}
diff --git a/apps/wallet-ui/src/app/[ecosystem]/login/layout.tsx b/apps/wallet-ui/src/app/[ecosystem]/login/layout.tsx
index 0c9e87c22e1..c28be22248f 100644
--- a/apps/wallet-ui/src/app/[ecosystem]/login/layout.tsx
+++ b/apps/wallet-ui/src/app/[ecosystem]/login/layout.tsx
@@ -5,9 +5,7 @@ export default async function Layout({
children,
}: { children: React.ReactNode }) {
const userAddress = await getCurrentUser();
- console.log("userAddress", userAddress);
if (userAddress) {
- console.log("redirecting to wallet", userAddress);
redirect(`/wallet/${userAddress}`);
}
diff --git a/apps/wallet-ui/src/app/[ecosystem]/login/page.tsx b/apps/wallet-ui/src/app/[ecosystem]/login/page.tsx
index 19f35213c97..e8b397b8066 100644
--- a/apps/wallet-ui/src/app/[ecosystem]/login/page.tsx
+++ b/apps/wallet-ui/src/app/[ecosystem]/login/page.tsx
@@ -1,33 +1,5 @@
-"use client";
-import { generatePayload, getCurrentUser, login, logout } from "@/lib/auth";
-import { client } from "@/lib/client";
-import { useTheme } from "next-themes";
-import { useRouter } from "next/navigation";
-import type { VerifyLoginPayloadParams } from "thirdweb/auth";
-import { ConnectEmbed } from "thirdweb/react";
-import { ecosystemWallet } from "thirdweb/wallets";
+import { ConnectEmbed } from "@/components/ConnectEmbed";
-export default function Page({ params }: { params: { ecosystem: string } }) {
- const { theme } = useTheme();
- const router = useRouter();
-
- return (
- {
- const success = await login(loginParams);
- if (success) {
- router.push(`/wallet/${loginParams.payload.address}`);
- }
- },
- isLoggedIn: async () => !!(await getCurrentUser()),
- doLogout: logout,
- }}
- />
- );
+export default function Page() {
+ return ;
}
diff --git a/apps/wallet-ui/src/app/[ecosystem]/wc/page.tsx b/apps/wallet-ui/src/app/[ecosystem]/wc/page.tsx
new file mode 100644
index 00000000000..19a8a9fb1f0
--- /dev/null
+++ b/apps/wallet-ui/src/app/[ecosystem]/wc/page.tsx
@@ -0,0 +1,17 @@
+// This page is to accept a Wallet Connect request
+import { getCurrentUser } from "@/lib/auth";
+import { redirect } from "next/navigation";
+
+export default async function Page({
+ searchParams: { uri },
+}: {
+ searchParams: { uri: string };
+}) {
+ const currentUser = await getCurrentUser();
+
+ if (!currentUser) {
+ redirect(`/login?uri=${encodeURIComponent(uri)}`);
+ }
+
+ redirect(`/wallet/${currentUser}?uri=${encodeURIComponent(uri)}`);
+}
diff --git a/apps/wallet-ui/src/components/AutoConnectWalletConnect.tsx b/apps/wallet-ui/src/components/AutoConnectWalletConnect.tsx
new file mode 100644
index 00000000000..d1fe09e61da
--- /dev/null
+++ b/apps/wallet-ui/src/components/AutoConnectWalletConnect.tsx
@@ -0,0 +1,8 @@
+"use client";
+
+import { useWalletConnect } from "@/hooks/useWalletConnect";
+
+export function AutoConnectWalletConnect({ uri }: { uri?: string }) {
+ useWalletConnect({ uri });
+ return <>>;
+}
diff --git a/apps/wallet-ui/src/components/ConnectButton.tsx b/apps/wallet-ui/src/components/ConnectButton.tsx
index eb25c3e0bf4..e5cb72e0338 100644
--- a/apps/wallet-ui/src/components/ConnectButton.tsx
+++ b/apps/wallet-ui/src/components/ConnectButton.tsx
@@ -1,5 +1,4 @@
"use client";
-import { generatePayload, isLoggedIn, login, logout } from "@/lib/auth";
import { client } from "@/lib/client";
import { useTheme } from "next-themes";
import {
@@ -24,14 +23,6 @@ export default function ConnectButton({
wallets={[ecosystemWallet(ecosystem)]}
client={client}
theme={theme === "light" ? "light" : "dark"}
- auth={{
- getLoginPayload: generatePayload,
- doLogin: async (p) => {
- login(p);
- },
- isLoggedIn,
- doLogout: logout,
- }}
/>
);
}
diff --git a/apps/wallet-ui/src/components/ConnectEmbed.tsx b/apps/wallet-ui/src/components/ConnectEmbed.tsx
new file mode 100644
index 00000000000..e40a2031004
--- /dev/null
+++ b/apps/wallet-ui/src/components/ConnectEmbed.tsx
@@ -0,0 +1,37 @@
+"use client";
+import { generatePayload, getCurrentUser, login, logout } from "@/lib/auth";
+import { client } from "@/lib/client";
+import { useTheme } from "next-themes";
+import { useParams, useRouter, useSearchParams } from "next/navigation";
+import type { VerifyLoginPayloadParams } from "thirdweb/auth";
+import { ConnectEmbed as ThirdwebConnectEmbed } from "thirdweb/react";
+import { ecosystemWallet } from "thirdweb/wallets";
+
+export function ConnectEmbed() {
+ const { theme } = useTheme();
+ const router = useRouter();
+ const params = useParams();
+ const searchParams = useSearchParams();
+
+ return (
+ {
+ const success = await login(loginParams);
+ if (success) {
+ router.push(
+ `/wallet/${loginParams.payload.address}?${searchParams.toString()}`,
+ );
+ }
+ },
+ isLoggedIn: async () => !!(await getCurrentUser()),
+ doLogout: logout,
+ }}
+ />
+ );
+}
diff --git a/apps/wallet-ui/src/hooks/useWalletConnect.tsx b/apps/wallet-ui/src/hooks/useWalletConnect.tsx
new file mode 100644
index 00000000000..e064e4111ca
--- /dev/null
+++ b/apps/wallet-ui/src/hooks/useWalletConnect.tsx
@@ -0,0 +1,40 @@
+import { client } from "@/lib/client";
+import { useQuery } from "@tanstack/react-query";
+import { CheckIcon } from "lucide-react";
+import { toast } from "sonner";
+import { useActiveWallet } from "thirdweb/react";
+import {
+ createWalletConnectClient,
+ createWalletConnectSession,
+} from "thirdweb/wallets";
+
+export function useWalletConnect({ uri }: { uri?: string }) {
+ const wallet = useActiveWallet();
+
+ useQuery({
+ queryKey: ["wallet-connect", uri],
+ queryFn: async () => {
+ if (!wallet || !uri) throw new Error("Unreachable");
+ const wcClient = await createWalletConnectClient({
+ wallet: wallet,
+ client: client,
+ });
+
+ createWalletConnectSession({
+ walletConnectClient: wcClient,
+ uri,
+ });
+
+ toast.success("Wallet connected.", {
+ id: "wallet-connect",
+ icon: ,
+ duration: 5000,
+ });
+
+ return true;
+ },
+ enabled: !!uri || !!wallet,
+ });
+
+ return;
+}
diff --git a/packages/thirdweb/src/wallets/wallet-connect/receiver/index.ts b/packages/thirdweb/src/wallets/wallet-connect/receiver/index.ts
index 16722082cf2..ca9df6aa3d6 100644
--- a/packages/thirdweb/src/wallets/wallet-connect/receiver/index.ts
+++ b/packages/thirdweb/src/wallets/wallet-connect/receiver/index.ts
@@ -284,7 +284,7 @@ export async function createWalletConnectClient(
* client: client,
* });
*
- * const session = await createWalletConnectSession({
+ * const session = createWalletConnectSession({
* walletConnectClient: client,
* uri: "wc:...",
* });
diff --git a/packages/thirdweb/src/wallets/wallet-connect/receiver/session-request.ts b/packages/thirdweb/src/wallets/wallet-connect/receiver/session-request.ts
index d07964ffe4c..c3903a48861 100644
--- a/packages/thirdweb/src/wallets/wallet-connect/receiver/session-request.ts
+++ b/packages/thirdweb/src/wallets/wallet-connect/receiver/session-request.ts
@@ -1,6 +1,12 @@
import type { ThirdwebClient } from "../../../client/client.js";
import type { Hex } from "../../../utils/encoding/hex.js";
import type { Wallet } from "../../interfaces/wallet.js";
+import { handleSendRawTransactionRequest } from "./request-handlers/send-raw-transaction.js";
+import { handleSendTransactionRequest } from "./request-handlers/send-transaction.js";
+import { handleSignTransactionRequest } from "./request-handlers/sign-transaction.js";
+import { handleSignTypedDataRequest } from "./request-handlers/sign-typed-data.js";
+// Due to some edge cases, we can't import these handlers dynamically
+import { handleSignRequest } from "./request-handlers/sign.js";
import type {
WalletConnectAddEthereumChainRequestParams,
WalletConnectClient,
@@ -54,9 +60,6 @@ export async function fulfillRequest(options: {
params: request.params as WalletConnectSignRequestPrams,
});
} else {
- const { handleSignRequest } = await import(
- "./request-handlers/sign.js"
- );
result = await handleSignRequest({
account,
params: request.params as WalletConnectSignRequestPrams,
@@ -71,9 +74,6 @@ export async function fulfillRequest(options: {
params: request.params as WalletConnectSignRequestPrams,
});
} else {
- const { handleSignRequest } = await import(
- "./request-handlers/sign.js"
- );
result = await handleSignRequest({
account,
params: request.params as WalletConnectSignRequestPrams,
@@ -88,9 +88,6 @@ export async function fulfillRequest(options: {
params: request.params as WalletConnectSignTypedDataRequestParams,
});
} else {
- const { handleSignTypedDataRequest } = await import(
- "./request-handlers/sign-typed-data.js"
- );
result = await handleSignTypedDataRequest({
account,
params: request.params as WalletConnectSignTypedDataRequestParams,
@@ -105,9 +102,6 @@ export async function fulfillRequest(options: {
params: request.params as WalletConnectSignTypedDataRequestParams,
});
} else {
- const { handleSignTypedDataRequest } = await import(
- "./request-handlers/sign-typed-data.js"
- );
result = await handleSignTypedDataRequest({
account,
params: request.params as WalletConnectSignTypedDataRequestParams,
@@ -122,9 +116,6 @@ export async function fulfillRequest(options: {
params: request.params as WalletConnectTransactionRequestParams,
});
} else {
- const { handleSignTransactionRequest } = await import(
- "./request-handlers/sign-transaction.js"
- );
result = await handleSignTransactionRequest({
account,
params: request.params as WalletConnectTransactionRequestParams,
@@ -141,10 +132,6 @@ export async function fulfillRequest(options: {
params: request.params as WalletConnectTransactionRequestParams,
});
} else {
- const { handleSendTransactionRequest } = await import(
- "./request-handlers/send-transaction.js"
- );
-
result = await handleSendTransactionRequest({
account,
chainId,
@@ -163,10 +150,6 @@ export async function fulfillRequest(options: {
params: request.params as WalletConnectRawTransactionRequestParams,
});
} else {
- const { handleSendRawTransactionRequest } = await import(
- "./request-handlers/send-raw-transaction.js"
- );
-
result = await handleSendRawTransactionRequest({
account,
chainId,