diff --git a/.changeset/fifty-houses-punch.md b/.changeset/fifty-houses-punch.md
new file mode 100644
index 00000000000..802340f6689
--- /dev/null
+++ b/.changeset/fifty-houses-punch.md
@@ -0,0 +1,5 @@
+---
+"thirdweb": patch
+---
+
+Enable Sign in with Wallet for ecosystems
diff --git a/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/components/client/auth-options-form.client.tsx b/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/components/client/auth-options-form.client.tsx
index 54c4770531d..dcc7c558bde 100644
--- a/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/components/client/auth-options-form.client.tsx
+++ b/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/components/client/auth-options-form.client.tsx
@@ -227,7 +227,10 @@ export function AuthOptionsForm({ ecosystem }: { ecosystem: Ecosystem }) {
className="h-6 w-6"
/>
- {option.slice(0, 1).toUpperCase() + option.slice(1)}
+ {option === "siwe"
+ ? "Wallet"
+ : option.slice(0, 1).toUpperCase() +
+ option.slice(1)}
diff --git a/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/types.ts b/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/types.ts
index 909728152c8..a2bc2575f1f 100644
--- a/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/types.ts
+++ b/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/types.ts
@@ -1,6 +1,9 @@
export const authOptions = [
"email",
"phone",
+ "passkey",
+ "siwe",
+ "guest",
"google",
"facebook",
"x",
@@ -12,7 +15,6 @@ export const authOptions = [
"apple",
"coinbase",
"line",
- "guest",
] as const;
export type Ecosystem = {
diff --git a/apps/dashboard/src/components/wallets/ConnectWalletMiniPlayground/MiniPlayground.tsx b/apps/dashboard/src/components/wallets/ConnectWalletMiniPlayground/MiniPlayground.tsx
index 5e12590cbce..b0cd2a63265 100644
--- a/apps/dashboard/src/components/wallets/ConnectWalletMiniPlayground/MiniPlayground.tsx
+++ b/apps/dashboard/src/components/wallets/ConnectWalletMiniPlayground/MiniPlayground.tsx
@@ -79,6 +79,7 @@ function usePlaygroundWallets() {
github: false,
coinbase: false,
guest: false,
+ wallet: false,
});
const [enabledWallets, setEnabledWallets] = useState({
diff --git a/apps/playground-web/src/components/in-app-wallet/ecosystem.tsx b/apps/playground-web/src/components/in-app-wallet/ecosystem.tsx
index fc119a3b53d..b2ae2f43c34 100644
--- a/apps/playground-web/src/components/in-app-wallet/ecosystem.tsx
+++ b/apps/playground-web/src/components/in-app-wallet/ecosystem.tsx
@@ -8,7 +8,7 @@ const getEcosystem = () => {
process.env.NEXT_PUBLIC_IN_APP_WALLET_URL?.endsWith(".thirdweb-dev.com")
) {
// dev ecosystem
- return "ecosystem.bonfire-development";
+ return "ecosystem.catlovers";
}
// prod ecosystem
return "ecosystem.new-age";
diff --git a/packages/thirdweb/src/extensions/prebuilts/deploy-erc1155.test.ts b/packages/thirdweb/src/extensions/prebuilts/deploy-erc1155.test.ts
index 8cdd6c804ca..47cc2863c82 100644
--- a/packages/thirdweb/src/extensions/prebuilts/deploy-erc1155.test.ts
+++ b/packages/thirdweb/src/extensions/prebuilts/deploy-erc1155.test.ts
@@ -1,19 +1,19 @@
import { describe, expect, it } from "vitest";
import { ANVIL_CHAIN } from "../../../test/src/chains.js";
import { TEST_CLIENT } from "../../../test/src/test-clients.js";
-import { TEST_ACCOUNT_A } from "../../../test/src/test-wallets.js";
+import { TEST_ACCOUNT_B } from "../../../test/src/test-wallets.js";
import { getContract } from "../../contract/contract.js";
import { name } from "../common/read/name.js";
import { deployERC1155Contract } from "./deploy-erc1155.js";
-// skip this test suite if there is no secret key available to test with
-// TODO: remove reliance on secret key during unit tests entirely
+const account = TEST_ACCOUNT_B;
+
describe.runIf(process.env.TW_SECRET_KEY)("deployERC1155", () => {
it("should deploy ERC1155 drop", async () => {
const address = await deployERC1155Contract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
- account: TEST_ACCOUNT_A,
+ account,
type: "DropERC1155",
params: {
name: "EditionDrop",
@@ -35,7 +35,7 @@ describe.runIf(process.env.TW_SECRET_KEY)("deployERC1155", () => {
const address = await deployERC1155Contract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
- account: TEST_ACCOUNT_A,
+ account,
type: "TokenERC1155",
params: {
name: "Edition",
diff --git a/packages/thirdweb/src/extensions/prebuilts/deploy-pack.test.ts b/packages/thirdweb/src/extensions/prebuilts/deploy-pack.test.ts
index 78af18c88b6..cfb5cc3dcef 100644
--- a/packages/thirdweb/src/extensions/prebuilts/deploy-pack.test.ts
+++ b/packages/thirdweb/src/extensions/prebuilts/deploy-pack.test.ts
@@ -1,14 +1,16 @@
import { describe, expect, it } from "vitest";
import { ANVIL_CHAIN } from "~test/chains.js";
import { TEST_CLIENT } from "~test/test-clients.js";
-import { TEST_ACCOUNT_A } from "~test/test-wallets.js";
+import { TEST_ACCOUNT_C } from "~test/test-wallets.js";
import { isAddress } from "../../utils/address.js";
import { deployPackContract } from "./deploy-pack.js";
+const account = TEST_ACCOUNT_C;
+
describe.runIf(process.env.TW_SECRET_KEY)("deploy-pack contract", () => {
it("should deploy Pack contract", async () => {
const address = await deployPackContract({
- account: TEST_ACCOUNT_A,
+ account,
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
params: {
diff --git a/packages/thirdweb/src/react/web/wallets/ecosystem/EcosystemWalletConnectUI.tsx b/packages/thirdweb/src/react/web/wallets/ecosystem/EcosystemWalletConnectUI.tsx
index 0baf6c852b5..6a8904b7ded 100644
--- a/packages/thirdweb/src/react/web/wallets/ecosystem/EcosystemWalletConnectUI.tsx
+++ b/packages/thirdweb/src/react/web/wallets/ecosystem/EcosystemWalletConnectUI.tsx
@@ -129,6 +129,7 @@ function EcosystemWalletConnectUI(props: {
done={done}
onBack={goBackToMain || (() => setSelectionData({}))}
locale={props.connectLocale}
+ isLinking={state.walletLogin.linking}
/>
);
}
diff --git a/packages/thirdweb/src/react/web/wallets/in-app/InAppWalletConnectUI.tsx b/packages/thirdweb/src/react/web/wallets/in-app/InAppWalletConnectUI.tsx
index 1c271669c00..038d1e1b88d 100644
--- a/packages/thirdweb/src/react/web/wallets/in-app/InAppWalletConnectUI.tsx
+++ b/packages/thirdweb/src/react/web/wallets/in-app/InAppWalletConnectUI.tsx
@@ -116,6 +116,7 @@ function InAppWalletConnectUI(props: {
done={done}
onBack={goBackToMain || (() => setSelectionData({}))}
locale={props.connectLocale}
+ isLinking={state.walletLogin.linking}
/>
);
}
diff --git a/packages/thirdweb/src/react/web/wallets/in-app/WalletAuth.tsx b/packages/thirdweb/src/react/web/wallets/in-app/WalletAuth.tsx
index c7d905d4c6d..0328b5a9657 100644
--- a/packages/thirdweb/src/react/web/wallets/in-app/WalletAuth.tsx
+++ b/packages/thirdweb/src/react/web/wallets/in-app/WalletAuth.tsx
@@ -28,6 +28,7 @@ export function WalletAuth(props: {
inAppLocale: InAppWalletLocale;
onBack: () => void;
walletConnect: { projectId?: string } | undefined;
+ isLinking: boolean;
meta?: {
title?: string;
titleIconUrl?: string;
@@ -61,16 +62,25 @@ export function WalletAuth(props: {
setStatus("loading");
walletToConnect.current = walletToLink;
try {
- await linkProfile({
- client: props.client,
- strategy: "wallet",
- wallet: walletToLink,
- chain: wallet.getChain() || defineChain(1),
- ecosystem,
- }).catch((e) => {
- setError(e.message);
- throw e;
- });
+ if (props.isLinking) {
+ await linkProfile({
+ client: props.client,
+ strategy: "wallet",
+ wallet: walletToLink,
+ chain: wallet.getChain() || defineChain(1),
+ ecosystem,
+ }).catch((e) => {
+ setError(e.message);
+ throw e;
+ });
+ } else {
+ await wallet.connect({
+ client: props.client,
+ strategy: "wallet",
+ wallet: walletToLink,
+ chain: walletToLink.getChain() || defineChain(1),
+ });
+ }
addConnectedWallet(walletToLink);
done();
} catch {
diff --git a/packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx b/packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
index 2b2784a166a..6ea4eb673d8 100644
--- a/packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
+++ b/packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
@@ -57,7 +57,9 @@ export type ConnectWalletSelectUIState =
connectionPromise: Promise;
};
passkeyLogin?: boolean;
- walletLogin?: boolean;
+ walletLogin?: {
+ linking: boolean;
+ };
};
const defaultAuthOptions: AuthOption[] = [
@@ -186,6 +188,7 @@ export const ConnectWalletSocialOptions = (
const passKeyEnabled = authOptions.includes("passkey");
const guestEnabled = authOptions.includes("guest");
+ const siweEnabled = authOptions.includes("wallet");
const placeholder =
inputMode === "email" ? locale.emailPlaceholder : locale.phonePlaceholder;
@@ -306,7 +309,9 @@ export const ConnectWalletSocialOptions = (
function handleWalletLogin() {
setData({
- walletLogin: true,
+ walletLogin: {
+ linking: props.isLinking || false,
+ },
});
props.select();
}
@@ -467,6 +472,18 @@ export const ConnectWalletSocialOptions = (
/>
)}
+ {/* SIWE login */}
+ {siweEnabled && (
+ {
+ handleWalletLogin();
+ }}
+ title={locale.signInWithWallet}
+ />
+ )}
+
{/* Guest login */}
{guestEnabled && (
o !== "siwe");
+ data.authOptions.push("wallet");
+ }
+
return data ?? null;
}
diff --git a/packages/thirdweb/src/wallets/in-app/core/authentication/getLoginPath.ts b/packages/thirdweb/src/wallets/in-app/core/authentication/getLoginPath.ts
index b61b529dfbb..2dc6705dcd4 100644
--- a/packages/thirdweb/src/wallets/in-app/core/authentication/getLoginPath.ts
+++ b/packages/thirdweb/src/wallets/in-app/core/authentication/getLoginPath.ts
@@ -3,8 +3,8 @@ import { getThirdwebBaseUrl } from "../../../../utils/domains.js";
import { type AuthOption, authOptions } from "../../../../wallets/types.js";
import type { Ecosystem } from "../wallet/types.js";
-const getLoginOptionRoute = (option: AuthOption | "wallet") => {
- if (!authOptions.includes(option as AuthOption) && option !== "wallet") {
+const getLoginOptionRoute = (option: AuthOption) => {
+ if (!authOptions.includes(option as AuthOption)) {
throw new Error(`Unknown auth option ${option}`);
}
switch (option) {
@@ -22,7 +22,7 @@ export const getLoginUrl = ({
mode = "popup",
redirectUrl,
}: {
- authOption: AuthOption | "wallet";
+ authOption: AuthOption;
client: ThirdwebClient;
ecosystem?: Ecosystem;
mode?: "popup" | "redirect" | "window";
@@ -60,7 +60,7 @@ export const getLoginCallbackUrl = ({
client,
ecosystem,
}: {
- authOption: AuthOption | "wallet";
+ authOption: AuthOption;
client: ThirdwebClient;
ecosystem?: Ecosystem;
}): string => {
diff --git a/packages/thirdweb/src/wallets/in-app/core/authentication/types.ts b/packages/thirdweb/src/wallets/in-app/core/authentication/types.ts
index 33026dc95f8..93839b232d6 100644
--- a/packages/thirdweb/src/wallets/in-app/core/authentication/types.ts
+++ b/packages/thirdweb/src/wallets/in-app/core/authentication/types.ts
@@ -112,7 +112,7 @@ export type OAuthRedirectObject = {
// TODO: type this better for each auth provider
export type Profile = {
- type: AuthOption | "wallet";
+ type: AuthOption;
details: {
id?: string;
email?: string;
diff --git a/packages/thirdweb/src/wallets/types.ts b/packages/thirdweb/src/wallets/types.ts
index f2442b8c575..52fc33f8314 100644
--- a/packages/thirdweb/src/wallets/types.ts
+++ b/packages/thirdweb/src/wallets/types.ts
@@ -41,6 +41,7 @@ export const authOptions = [
"email",
"phone",
"passkey",
+ "wallet",
] as const;
export type AuthOption = (typeof authOptions)[number];