From da5d8ec53b4d60dd1ad6ed2cd9d638f466b22b3a Mon Sep 17 00:00:00 2001 From: Joaquim Verges Date: Wed, 11 Dec 2024 19:58:24 +1300 Subject: [PATCH] fix: Autoconnect previously linked wallets (#5688) --- .changeset/happy-suns-nail.md | 5 ++++ .../src/components/styled-connect-embed.tsx | 2 +- .../hooks/wallets/useAddConnectedWallet.ts | 2 +- .../core/hooks/wallets/useAutoConnect.ts | 2 +- .../native/hooks/wallets/useLinkProfile.ts | 25 +++++++++++++------ .../react/native/hooks/wallets/useProfiles.ts | 25 +++++++++++++------ .../react/web/hooks/wallets/useLinkProfile.ts | 23 +++++++++++------ .../react/web/hooks/wallets/useProfiles.ts | 25 +++++++++++++------ .../screens/LinkProfileScreen.tsx | 8 ++++-- .../thirdweb/src/wallets/manager/index.ts | 8 ++++-- 10 files changed, 87 insertions(+), 38 deletions(-) create mode 100644 .changeset/happy-suns-nail.md diff --git a/.changeset/happy-suns-nail.md b/.changeset/happy-suns-nail.md new file mode 100644 index 00000000000..a5188f95ea0 --- /dev/null +++ b/.changeset/happy-suns-nail.md @@ -0,0 +1,5 @@ +--- +"thirdweb": patch +--- + +Autoconnect previously linked wallets diff --git a/apps/playground-web/src/components/styled-connect-embed.tsx b/apps/playground-web/src/components/styled-connect-embed.tsx index 15f905d5f29..937f7d0ce98 100644 --- a/apps/playground-web/src/components/styled-connect-embed.tsx +++ b/apps/playground-web/src/components/styled-connect-embed.tsx @@ -25,7 +25,7 @@ export function StyledConnectEmbed( return account ? (
- +
) : ( w.id !== lastActiveWalletId && lastConnectedWalletIds.includes(w.id), ); diff --git a/packages/thirdweb/src/react/native/hooks/wallets/useLinkProfile.ts b/packages/thirdweb/src/react/native/hooks/wallets/useLinkProfile.ts index 99392af4353..eba52743881 100644 --- a/packages/thirdweb/src/react/native/hooks/wallets/useLinkProfile.ts +++ b/packages/thirdweb/src/react/native/hooks/wallets/useLinkProfile.ts @@ -1,9 +1,9 @@ -import { useMutation } from "@tanstack/react-query"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; import { isEcosystemWallet } from "../../../../wallets/ecosystem/is-ecosystem-wallet.js"; import type { AuthArgsType } from "../../../../wallets/in-app/core/authentication/types.js"; import type { Ecosystem } from "../../../../wallets/in-app/core/wallet/types.js"; import { linkProfile } from "../../../../wallets/in-app/web/lib/auth/index.js"; -import { useAdminWallet } from "../../../core/hooks/wallets/useAdminWallet.js"; +import { useConnectedWallets } from "../../../core/hooks/wallets/useConnectedWallets.js"; /** * Links a web2 or web3 profile to the connected in-app or ecosystem account. @@ -77,16 +77,25 @@ import { useAdminWallet } from "../../../core/hooks/wallets/useAdminWallet.js"; * @wallet */ export function useLinkProfile() { - const wallet = useAdminWallet(); + const wallets = useConnectedWallets(); + const queryClient = useQueryClient(); return useMutation({ mutationKey: ["profiles"], - mutationFn: async (options: Omit) => { - const ecosystem: Ecosystem | undefined = - wallet && isEcosystemWallet(wallet) - ? { id: wallet.id, partnerId: wallet.getConfig()?.partnerId } - : undefined; + mutationFn: async (options: AuthArgsType) => { + const ecosystemWallet = wallets.find((w) => isEcosystemWallet(w)); + const ecosystem: Ecosystem | undefined = ecosystemWallet + ? { + id: ecosystemWallet.id, + partnerId: ecosystemWallet.getConfig()?.partnerId, + } + : undefined; const optionsWithEcosystem = { ...options, ecosystem } as AuthArgsType; return linkProfile(optionsWithEcosystem); }, + onSuccess() { + setTimeout(() => { + queryClient.invalidateQueries({ queryKey: ["profiles"] }); + }, 500); + }, }); } diff --git a/packages/thirdweb/src/react/native/hooks/wallets/useProfiles.ts b/packages/thirdweb/src/react/native/hooks/wallets/useProfiles.ts index 2e429021a24..a4a6ddb2262 100644 --- a/packages/thirdweb/src/react/native/hooks/wallets/useProfiles.ts +++ b/packages/thirdweb/src/react/native/hooks/wallets/useProfiles.ts @@ -4,7 +4,7 @@ import { isEcosystemWallet } from "../../../../wallets/ecosystem/is-ecosystem-wa import type { Profile } from "../../../../wallets/in-app/core/authentication/types.js"; import type { Ecosystem } from "../../../../wallets/in-app/core/wallet/types.js"; import { getProfiles } from "../../../../wallets/in-app/web/lib/auth/index.js"; -import { useAdminWallet } from "../../../core/hooks/wallets/useAdminWallet.js"; +import { useConnectedWallets } from "../../../core/hooks/wallets/useConnectedWallets.js"; /** * Retrieves all linked profiles of the connected in-app or ecosystem account. @@ -29,15 +29,24 @@ import { useAdminWallet } from "../../../core/hooks/wallets/useAdminWallet.js"; export function useProfiles(args: { client: ThirdwebClient; }): UseQueryResult { - const wallet = useAdminWallet(); + const wallets = useConnectedWallets(); + const enabled = + wallets.length > 0 && + wallets.some((w) => w.id === "inApp" || isEcosystemWallet(w)); return useQuery({ - queryKey: ["profiles", wallet?.id, wallet?.getAccount()?.address], - enabled: !!wallet && (wallet.id === "inApp" || isEcosystemWallet(wallet)), + queryKey: [ + "profiles", + wallets.map((w) => `${w.id}-${w.getAccount()?.address}`), + ], + enabled, queryFn: async () => { - const ecosystem: Ecosystem | undefined = - wallet && isEcosystemWallet(wallet) - ? { id: wallet.id, partnerId: wallet.getConfig()?.partnerId } - : undefined; + const ecosystemWallet = wallets.find((w) => isEcosystemWallet(w)); + const ecosystem: Ecosystem | undefined = ecosystemWallet + ? { + id: ecosystemWallet.id, + partnerId: ecosystemWallet.getConfig()?.partnerId, + } + : undefined; return getProfiles({ client: args.client, ecosystem, diff --git a/packages/thirdweb/src/react/web/hooks/wallets/useLinkProfile.ts b/packages/thirdweb/src/react/web/hooks/wallets/useLinkProfile.ts index c0b27cd30ba..fe72dbe06dd 100644 --- a/packages/thirdweb/src/react/web/hooks/wallets/useLinkProfile.ts +++ b/packages/thirdweb/src/react/web/hooks/wallets/useLinkProfile.ts @@ -1,9 +1,9 @@ -import { useMutation } from "@tanstack/react-query"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; import { isEcosystemWallet } from "../../../../wallets/ecosystem/is-ecosystem-wallet.js"; import type { AuthArgsType } from "../../../../wallets/in-app/core/authentication/types.js"; import type { Ecosystem } from "../../../../wallets/in-app/core/wallet/types.js"; import { linkProfile } from "../../../../wallets/in-app/web/lib/auth/index.js"; -import { useAdminWallet } from "../../../core/hooks/wallets/useAdminWallet.js"; +import { useConnectedWallets } from "../../../core/hooks/wallets/useConnectedWallets.js"; /** * Links a web2 or web3 profile to the connected in-app or ecosystem account. @@ -76,16 +76,25 @@ import { useAdminWallet } from "../../../core/hooks/wallets/useAdminWallet.js"; * @wallet */ export function useLinkProfile() { - const wallet = useAdminWallet(); + const wallets = useConnectedWallets(); + const queryClient = useQueryClient(); return useMutation({ mutationKey: ["profiles"], mutationFn: async (options: AuthArgsType) => { - const ecosystem: Ecosystem | undefined = - wallet && isEcosystemWallet(wallet) - ? { id: wallet.id, partnerId: wallet.getConfig()?.partnerId } - : undefined; + const ecosystemWallet = wallets.find((w) => isEcosystemWallet(w)); + const ecosystem: Ecosystem | undefined = ecosystemWallet + ? { + id: ecosystemWallet.id, + partnerId: ecosystemWallet.getConfig()?.partnerId, + } + : undefined; const optionsWithEcosystem = { ...options, ecosystem } as AuthArgsType; return linkProfile(optionsWithEcosystem); }, + onSuccess() { + setTimeout(() => { + queryClient.invalidateQueries({ queryKey: ["profiles"] }); + }, 500); + }, }); } diff --git a/packages/thirdweb/src/react/web/hooks/wallets/useProfiles.ts b/packages/thirdweb/src/react/web/hooks/wallets/useProfiles.ts index 2e429021a24..a4a6ddb2262 100644 --- a/packages/thirdweb/src/react/web/hooks/wallets/useProfiles.ts +++ b/packages/thirdweb/src/react/web/hooks/wallets/useProfiles.ts @@ -4,7 +4,7 @@ import { isEcosystemWallet } from "../../../../wallets/ecosystem/is-ecosystem-wa import type { Profile } from "../../../../wallets/in-app/core/authentication/types.js"; import type { Ecosystem } from "../../../../wallets/in-app/core/wallet/types.js"; import { getProfiles } from "../../../../wallets/in-app/web/lib/auth/index.js"; -import { useAdminWallet } from "../../../core/hooks/wallets/useAdminWallet.js"; +import { useConnectedWallets } from "../../../core/hooks/wallets/useConnectedWallets.js"; /** * Retrieves all linked profiles of the connected in-app or ecosystem account. @@ -29,15 +29,24 @@ import { useAdminWallet } from "../../../core/hooks/wallets/useAdminWallet.js"; export function useProfiles(args: { client: ThirdwebClient; }): UseQueryResult { - const wallet = useAdminWallet(); + const wallets = useConnectedWallets(); + const enabled = + wallets.length > 0 && + wallets.some((w) => w.id === "inApp" || isEcosystemWallet(w)); return useQuery({ - queryKey: ["profiles", wallet?.id, wallet?.getAccount()?.address], - enabled: !!wallet && (wallet.id === "inApp" || isEcosystemWallet(wallet)), + queryKey: [ + "profiles", + wallets.map((w) => `${w.id}-${w.getAccount()?.address}`), + ], + enabled, queryFn: async () => { - const ecosystem: Ecosystem | undefined = - wallet && isEcosystemWallet(wallet) - ? { id: wallet.id, partnerId: wallet.getConfig()?.partnerId } - : undefined; + const ecosystemWallet = wallets.find((w) => isEcosystemWallet(w)); + const ecosystem: Ecosystem | undefined = ecosystemWallet + ? { + id: ecosystemWallet.id, + partnerId: ecosystemWallet.getConfig()?.partnerId, + } + : undefined; return getProfiles({ client: args.client, ecosystem, diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/LinkProfileScreen.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/LinkProfileScreen.tsx index a0790a51c2e..dcfac333282 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/LinkProfileScreen.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/LinkProfileScreen.tsx @@ -43,7 +43,9 @@ export function LinkProfileScreen(props: { walletConnect={props.walletConnect} wallet={activeWallet as Wallet<"inApp">} done={() => { - queryClient.invalidateQueries({ queryKey: ["profiles"] }); + setTimeout(() => { + queryClient.invalidateQueries({ queryKey: ["profiles"] }); + }, 500); props.onBack(); }} connectLocale={props.locale} @@ -67,7 +69,9 @@ export function LinkProfileScreen(props: { } done={() => { - queryClient.invalidateQueries({ queryKey: ["profiles"] }); + setTimeout(() => { + queryClient.invalidateQueries({ queryKey: ["profiles"] }); + }, 500); props.onBack(); }} connectLocale={props.locale} diff --git a/packages/thirdweb/src/wallets/manager/index.ts b/packages/thirdweb/src/wallets/manager/index.ts index 1dfbdb43baf..fe5a8ef7e6c 100644 --- a/packages/thirdweb/src/wallets/manager/index.ts +++ b/packages/thirdweb/src/wallets/manager/index.ts @@ -230,11 +230,15 @@ export function createConnectionManager(storage: AsyncStorage) { // save last connected wallet ids to storage effect( - () => { + async () => { + const prevAccounts = (await getStoredConnectedWalletIds(storage)) || []; const accounts = connectedWallets.getValue(); const ids = accounts.map((acc) => acc?.id).filter((c) => !!c) as string[]; - storage.setItem(CONNECTED_WALLET_IDS, stringify(ids)); + storage.setItem( + CONNECTED_WALLET_IDS, + stringify(Array.from(new Set([...prevAccounts, ...ids]))), + ); }, [connectedWallets], false,