Skip to content
This repository has been archived by the owner on Jun 19, 2024. It is now read-only.

Commit

Permalink
refactor: update ConnectWallet component for simplified usage and imp…
Browse files Browse the repository at this point in the history
…ort paths
  • Loading branch information
jnsdls committed Jun 18, 2024
1 parent 6296bc1 commit 5322112
Show file tree
Hide file tree
Showing 78 changed files with 566 additions and 515 deletions.
202 changes: 151 additions & 51 deletions src/@3rdweb-sdk/react/components/connect-wallet/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,84 +3,184 @@
/* eslint-disable react/forbid-dom-props */
import { popularChains } from "../popularChains";
import { useTheme } from "next-themes";
import { ConnectWallet } from "@thirdweb-dev/react";
import { ConnectButton } from "thirdweb/react";
import {
useAddRecentlyUsedChainId,
useRecentlyUsedChains,
} from "hooks/chains/recentlyUsedChains";
import { useSetIsNetworkConfigModalOpen } from "hooks/networkConfigModal";
import { ComponentProps, useCallback } from "react";
// import { useSetIsNetworkConfigModalOpen } from "hooks/networkConfigModal";
import { useCallback, useMemo } from "react";
import Link from "next/link";
import Image from "next/image";
import { useTrack } from "../../../../hooks/analytics/useTrack";
import { CustomChainRenderer } from "../../../../components/selects/CustomChainRenderer";
import { useFavoriteChains } from "../../hooks/useFavoriteChains";
import { useTrack } from "hooks/analytics/useTrack";
// import { CustomChainRenderer } from "components/selects/CustomChainRenderer";
// import { useFavouriteChains } from "app/(dashboard)/(chain)/components/client/star-button";
// import type { Chain } from "@thirdweb-dev/chains";
import { thirdwebClient } from "@/constants/client";
import { THIRDWEB_API_HOST } from "constants/urls";
import { useSupportedChains } from "@thirdweb-dev/react";
import { defineDashboardChain } from "../../../../lib/v5-adapter";
import { GLOBAL_AUTH_TOKEN_KEY } from "../../../../constants/app";
import { fetchAuthToken } from "../../hooks/useApi";

export interface ConnectWalletProps {
shrinkMobile?: boolean;
upsellTestnet?: boolean;
onChainSelect?: (chainId: number) => void;
auth?: ComponentProps<typeof ConnectWallet>["auth"];
noAuth?: boolean;
disableChainConfig?: boolean;
disableAddCustomNetwork?: boolean;
}

export const CustomConnectWallet: React.FC<ConnectWalletProps> = ({
auth,
disableChainConfig,
disableAddCustomNetwork,
noAuth,
}) => {
const { theme } = useTheme();
const recentChains = useRecentlyUsedChains();
const recentChainsv4 = useRecentlyUsedChains();
const addRecentlyUsedChainId = useAddRecentlyUsedChainId();
const setIsNetworkConfigModalOpen = useSetIsNetworkConfigModalOpen();
// const setIsNetworkConfigModalOpen = useSetIsNetworkConfigModalOpen();
const t = theme === "light" ? "light" : "dark";
const favChainsQuery = useFavoriteChains();
const allv4Chains = useSupportedChains();
// const favChainsQuery = useFavouriteChains();

// const favChains = useMemo(() => {
// if (favChainsQuery.data) {
// const _chains: Chain[] = [];
// favChainsQuery.data.forEach((chainId) => {
// const chain = allChains.find((c) => String(c.chainId) === chainId);
// if (chain) {
// _chains.push(chain);
// }
// });

// return _chains;
// }
// }, [favChainsQuery.data, allChains]);

const allChains = useMemo(() => {
return allv4Chains.map((c) => defineDashboardChain(c.chainId, c));
}, [allv4Chains]);

return (
<ConnectWallet
auth={auth}
<ConnectButton
auth={
noAuth
? undefined
: {
getLoginPayload: async (params) => {
const res = await fetch(
`${THIRDWEB_API_HOST}/v1/auth/payload`,
{
method: "POST",
body: JSON.stringify({
address: params.address,
chainId: params.chainId.toString(),
}),
headers: {
"Content-Type": "application/json",
},
},
);
if (!res.ok) {
throw new Error("Failed to fetch login payload");
}
return (await res.json()).payload;
},
doLogin: async (payload) => {
const res = await fetch(`${THIRDWEB_API_HOST}/v1/auth/login`, {
method: "POST",
body: JSON.stringify({ payload }),
credentials: "include",
headers: {
"Content-Type": "application/json",
},
});
if (!res.ok) {
throw new Error("Failed to login");
}
const json = await res.json();

if (json.token) {
(window as any)[GLOBAL_AUTH_TOKEN_KEY] = json.token;
}
return json;
},
doLogout: async () => {
// reset the token ASAP
(window as any)[GLOBAL_AUTH_TOKEN_KEY] = undefined;
const res = await fetch(`${THIRDWEB_API_HOST}/v1/auth/logout`, {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
});
if (!res.ok) {
throw new Error("Failed to logout");
}
return res.json();
},
isLoggedIn: async (address) => {
const res = await fetch(`${THIRDWEB_API_HOST}/v1/auth/user`, {
method: "GET",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
});
if (!res.ok) {
throw new Error("Failed to fetch user");
}
const user = await res.json();

const { jwt } = await fetchAuthToken(address);
if (jwt) {
(window as any)[GLOBAL_AUTH_TOKEN_KEY] = jwt;
}

return user;
},
}
}
theme={t}
welcomeScreen={() => {
return <ConnectWalletWelcomeScreen theme={t} />;
client={thirdwebClient}
connectModal={{
privacyPolicyUrl: "/privacy",
termsOfServiceUrl: "/tos",
showThirdwebBranding: false,
welcomeScreen: () => <ConnectWalletWelcomeScreen theme={t} />,
}}
termsOfServiceUrl="/tos"
privacyPolicyUrl="/privacy"
hideTestnetFaucet={false}
networkSelector={{
sections: [
{
label: "Recently used",
chains: recentChains,
},
{
label: "Favorites",
chains: favChainsQuery.data ?? [],
},
{
label: "Popular",
chains: popularChains,
appMetadata={{
name: "thirdweb",
logoUrl: "https://thirdweb.com/favicon.ico",
url: "https://thirdweb.com",
}}
chains={allChains}
detailsModal={{
networkSelector: {
popularChainIds: popularChains.map((c) => c.chainId),
recentChainIds: recentChainsv4.map((c) => c.chainId),
onSwitch(chain) {
addRecentlyUsedChainId(chain.id);
},
],
onSwitch(chain) {
addRecentlyUsedChainId(chain.chainId);
},
onCustomClick: disableAddCustomNetwork
? undefined
: () => {
setIsNetworkConfigModalOpen(true);
},

renderChain(props) {
return (
<CustomChainRenderer
{...props}
disableChainConfig={disableChainConfig}
/>
);
// TODO: re-visit this
// onCustomClick: disableAddCustomNetwork
// ? undefined
// : () => {
// setIsNetworkConfigModalOpen(true);
// },

// TODO: re-visit this
// renderChain(props) {
// return (
// <CustomChainRenderer
// {...props}
// disableChainConfig={disableChainConfig}
// />
// );
// },
},
}}
showThirdwebBranding={false}
/>
);
};
Expand Down
2 changes: 1 addition & 1 deletion src/@3rdweb-sdk/react/hooks/useApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1041,7 +1041,7 @@ type FetchAuthTokenResponse = {

const TOKEN_PROMISE_MAP = new Map<string, Promise<FetchAuthTokenResponse>>();

async function fetchAuthToken(
export async function fetchAuthToken(
address: string,
abortController?: AbortController,
): Promise<FetchAuthTokenResponse> {
Expand Down
10 changes: 5 additions & 5 deletions src/@3rdweb-sdk/react/hooks/useContractRoles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import {
ContractWithRoles,
RequiredParam,
RolesForContract,
useAddress,
useContractType,
useRoleMembers,
} from "@thirdweb-dev/react";
import { ValidContractInstance } from "@thirdweb-dev/sdk";
import { constants } from "ethers";
import { useActiveAccount } from "thirdweb/react";

function isContractWithRoles(
contract: RequiredParam<ValidContractInstance>,
Expand Down Expand Up @@ -40,7 +40,7 @@ function useIsAccountRole<TContract extends ContractWithRoles>(
export function useIsAdmin<TContract extends ValidContractInstance>(
contract: RequiredParam<TContract>,
) {
const address = useAddress();
const address = useActiveAccount()?.address;
const { data: contractType } = useContractType(contract?.getAddress());

const contractHasRoles = isContractWithRoles(contract);
Expand All @@ -60,7 +60,7 @@ export function useIsAdminOrSelf<TContract extends ValidContractInstance>(
contract: RequiredParam<TContract>,
self: RequiredParam<string>,
) {
const address = useAddress();
const address = useActiveAccount()?.address;
const { data: contractType } = useContractType(contract?.getAddress());
const isAdmin = useIsAdmin(contract);

Expand All @@ -76,7 +76,7 @@ export function useIsAdminOrSelf<TContract extends ValidContractInstance>(
export function useIsMinter<TContract extends ValidContractInstance>(
contract: RequiredParam<TContract>,
) {
const address = useAddress();
const address = useActiveAccount()?.address;
const { data: contractType } = useContractType(contract?.getAddress());
const contractHasRoles = isContractWithRoles(contract);
const isAccountRole = useIsAccountRole(
Expand All @@ -94,7 +94,7 @@ export function useIsMinter<TContract extends ValidContractInstance>(
export function useIsLister<TContract extends ValidContractInstance>(
contract: RequiredParam<TContract>,
) {
const address = useAddress();
const address = useActiveAccount()?.address;
const { data: contractType } = useContractType(contract?.getAddress());
const contractHasRoles = isContractWithRoles(contract);
const isAccountRole = useIsAccountRole(
Expand Down
6 changes: 3 additions & 3 deletions src/@3rdweb-sdk/react/hooks/useEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { engineKeys } from "../cache-keys";
import { useMutationWithInvalidate } from "./query/useQueryWithNetwork";
import invariant from "tiny-invariant";
import { useApiAuthToken } from "./useApi";
import { useAddress, useChainId } from "@thirdweb-dev/react";
import { THIRDWEB_API_HOST } from "constants/urls";
import { useLoggedInUser } from "./useLoggedInUser";
import { useState } from "react";
import { useActiveAccount, useActiveWalletChain } from "thirdweb/react";

export function useEngineConnectedInstance() {
const [instance, setInstance] = useState<EngineInstance | null>(null);
Expand Down Expand Up @@ -414,7 +414,7 @@ export function useEngineBackendWalletBalance(
address: string,
) {
const { token } = useApiAuthToken();
const chainId = useChainId();
const chainId = useActiveWalletChain()?.id;

invariant(chainId, "chainId is required");

Expand Down Expand Up @@ -445,7 +445,7 @@ export type EngineAdmin = {

export function useEnginePermissions(instance: string) {
const { token } = useApiAuthToken();
const address = useAddress();
const address = useActiveAccount()?.address;

return useQuery(
engineKeys.permissions(instance),
Expand Down
5 changes: 3 additions & 2 deletions src/@3rdweb-sdk/react/hooks/useLoggedInUser.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { useAddress, useUser } from "@thirdweb-dev/react";
import { useUser } from "@thirdweb-dev/react";
import { useActiveAccount } from "thirdweb/react";

export function useLoggedInUser(): ReturnType<typeof useUser> {
const connectedAddress = useAddress();
const connectedAddress = useActiveAccount()?.address;
const userQuery = useUser();

// user is not considered logged in if the connected address does not match the user's address
Expand Down
Loading

0 comments on commit 5322112

Please sign in to comment.