diff --git a/docs/react.md b/docs/react.md index 20c78bf..15b729e 100644 --- a/docs/react.md +++ b/docs/react.md @@ -66,8 +66,8 @@ import { useGnosis } from "@thirdweb-dev/react" | [useLazyMint(contract, onProgress)](./react.uselazymint.md) | (BETA) Use this to lazy mint a batch of NFTs on your [DropContract](./react.dropcontract.md) | | [useListing(contract, listingId)](./react.uselisting.md) | (BETA) Use this to get a specific listing from the marketplace. | | [useListings(contract, filter)](./react.uselistings.md) | (BETA) Use this to get a list all listings from your marketplace contract. | -| [useLogin(config)](./react.uselogin.md) | Hook to securely login to a backend with the connected wallet. The backend authentication URL must be configured on the ThirdwebProvider. | -| [useLogout()](./react.uselogout.md) | Hook to logout the connected wallet from the backend. The backend logout URL must be configured on the ThirdwebProvider. | +| [useLogin(config)](./react.uselogin.md) | (BETA) Hook to securely login to a backend with the connected wallet. The backend authentication URL must be configured on the ThirdwebProvider. | +| [useLogout()](./react.uselogout.md) | (BETA) Hook to logout the connected wallet from the backend. The backend logout URL must be configured on the ThirdwebProvider. | | [useMagic()](./react.usemagic.md) |

Hook for connecting to an email wallet using magic link. This enables users without their own wallets to connect to your application and sign transactions securely using their email.

```javascript import { useMagic } from "@thirdweb-dev/react" @@ -122,7 +122,7 @@ import { useNetworkMistmatch } from "@thirdweb-dev/react" | [useUpdatePlatformFees(contract)](./react.useupdateplatformfees.md) | (BETA) Use this to update the platform fees settings of your | | [useUpdatePrimarySaleRecipient(contract)](./react.useupdateprimarysalerecipient.md) | (BETA) Use this to update the primary sales recipient of your | | [useUpdateRoyaltySettings(contract)](./react.useupdateroyaltysettings.md) | (BETA) Use this to update the royalty settings of your | -| [useUser()](./react.useuser.md) | Hook to get the currently logged in user. | +| [useUser()](./react.useuser.md) | (BETA) Hook to get the currently logged in user. | | [useVote(contractAddress)](./react.usevote.md) | Hook for getting an instance of an Vote contract. This contract enables fully featured voting-based decentralized governance systems. | | [useWalletConnect()](./react.usewalletconnect.md) |

Hook for connecting to a mobile wallet with Wallet Connect

```javascript @@ -140,7 +140,7 @@ import { useWalletConnect } from "@thirdweb-dev/react" | [MediaRendererProps](./react.mediarendererprops.md) | The props for the [MediaRenderer](./react.mediarenderer.md) component. | | [MediaType](./react.mediatype.md) | | | [SharedMediaProps](./react.sharedmediaprops.md) | | -| [ThirdwebAuthConfig](./react.thirdwebauthconfig.md) | | +| [ThirdwebAuthConfig](./react.thirdwebauthconfig.md) | (BETA) The configuration to use the react SDK with an \[auth\](https://portal.thirdweb.com/auth) server. | | [ThirdwebNftMediaProps](./react.thirdwebnftmediaprops.md) | The props for the [ThirdwebNftMedia](./react.thirdwebnftmedia.md) component. | | [ThirdwebProviderProps](./react.thirdwebproviderprops.md) | The possible props for the ThirdwebProvider. | | [ThirdwebSDKProviderProps](./react.thirdwebsdkproviderprops.md) | | diff --git a/docs/react.thirdwebauthconfig.authurl.md b/docs/react.thirdwebauthconfig.authurl.md index 5f80957..c936d23 100644 --- a/docs/react.thirdwebauthconfig.authurl.md +++ b/docs/react.thirdwebauthconfig.authurl.md @@ -4,7 +4,10 @@ ## ThirdwebAuthConfig.authUrl property -The backend URL of the authentication endoints. For example, if your endpoints are at /api/auth/login, /api/auth/logout, etc. then this should be set to "/api/auth". +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + +The backend URL of the authentication endoints. For example, if your endpoints are at `/api/auth/login`, `/api/auth/logout`, etc. then this should be set to `/api/auth`. Signature: diff --git a/docs/react.thirdwebauthconfig.domain.md b/docs/react.thirdwebauthconfig.domain.md index 169e1ce..caa83a4 100644 --- a/docs/react.thirdwebauthconfig.domain.md +++ b/docs/react.thirdwebauthconfig.domain.md @@ -4,6 +4,9 @@ ## ThirdwebAuthConfig.domain property +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + The frontend domain used to generate the login payload. This domain should match the domain used on your auth backend. Signature: diff --git a/docs/react.thirdwebauthconfig.loginredirect.md b/docs/react.thirdwebauthconfig.loginredirect.md index 8b41d4f..605267a 100644 --- a/docs/react.thirdwebauthconfig.loginredirect.md +++ b/docs/react.thirdwebauthconfig.loginredirect.md @@ -4,6 +4,9 @@ ## ThirdwebAuthConfig.loginRedirect property +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + The URL to redirect to after a succesful login. Signature: diff --git a/docs/react.thirdwebauthconfig.md b/docs/react.thirdwebauthconfig.md index 599c949..0972b70 100644 --- a/docs/react.thirdwebauthconfig.md +++ b/docs/react.thirdwebauthconfig.md @@ -4,6 +4,11 @@ ## ThirdwebAuthConfig interface +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + +The configuration to use the react SDK with an \[auth\](https://portal.thirdweb.com/auth) server. + Signature: ```typescript @@ -14,7 +19,7 @@ export interface ThirdwebAuthConfig | Property | Modifiers | Type | Description | | --- | --- | --- | --- | -| [authUrl](./react.thirdwebauthconfig.authurl.md) | | string | The backend URL of the authentication endoints. For example, if your endpoints are at /api/auth/login, /api/auth/logout, etc. then this should be set to "/api/auth". | -| [domain](./react.thirdwebauthconfig.domain.md) | | string | The frontend domain used to generate the login payload. This domain should match the domain used on your auth backend. | -| [loginRedirect?](./react.thirdwebauthconfig.loginredirect.md) | | string | (Optional) The URL to redirect to after a succesful login. | +| [authUrl](./react.thirdwebauthconfig.authurl.md) | | string | (BETA) The backend URL of the authentication endoints. For example, if your endpoints are at /api/auth/login, /api/auth/logout, etc. then this should be set to /api/auth. | +| [domain](./react.thirdwebauthconfig.domain.md) | | string | (BETA) The frontend domain used to generate the login payload. This domain should match the domain used on your auth backend. | +| [loginRedirect?](./react.thirdwebauthconfig.loginredirect.md) | | string | (BETA) (Optional) The URL to redirect to after a succesful login. | diff --git a/docs/react.thirdwebsdkproviderprops.md b/docs/react.thirdwebsdkproviderprops.md index 90514a9..20a072e 100644 --- a/docs/react.thirdwebsdkproviderprops.md +++ b/docs/react.thirdwebsdkproviderprops.md @@ -9,7 +9,7 @@ ```typescript export interface ThirdwebSDKProviderProps extends Omit ``` -Extends: Omit<[ThirdwebSDKProviderWagmiWrapper](./react.thirdwebsdkproviderwagmiwrapper.md) +Extends: Omit<[ThirdwebSDKProviderWagmiWrapper](./react.thirdwebsdkproviderwagmiwrapper.md), "queryClient"> ## Properties diff --git a/docs/react.thirdwebsdkproviderwagmiwrapper.md b/docs/react.thirdwebsdkproviderwagmiwrapper.md index 137c4e6..5e56590 100644 --- a/docs/react.thirdwebsdkproviderwagmiwrapper.md +++ b/docs/react.thirdwebsdkproviderwagmiwrapper.md @@ -7,9 +7,9 @@ Signature: ```typescript -export interface ThirdwebSDKProviderWagmiWrapper extends Pick +export interface ThirdwebSDKProviderWagmiWrapper extends Pick ``` -Extends: Pick<[ThirdwebProviderProps](./react.thirdwebproviderprops.md) +Extends: Pick<[ThirdwebProviderProps](./react.thirdwebproviderprops.md), "desiredChainId" \| "sdkOptions" \| "storageInterface" \| "authConfig"> ## Properties diff --git a/docs/react.uselogin.md b/docs/react.uselogin.md index e53526e..f7aaee6 100644 --- a/docs/react.uselogin.md +++ b/docs/react.uselogin.md @@ -4,6 +4,9 @@ ## useLogin() function +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Hook to securely login to a backend with the connected wallet. The backend authentication URL must be configured on the ThirdwebProvider. Signature: diff --git a/docs/react.uselogout.md b/docs/react.uselogout.md index 2107aa8..38ea3da 100644 --- a/docs/react.uselogout.md +++ b/docs/react.uselogout.md @@ -4,6 +4,9 @@ ## useLogout() function +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Hook to logout the connected wallet from the backend. The backend logout URL must be configured on the ThirdwebProvider. Signature: diff --git a/docs/react.useuser.md b/docs/react.useuser.md index 0aef5b8..a7c4370 100644 --- a/docs/react.useuser.md +++ b/docs/react.useuser.md @@ -4,6 +4,9 @@ ## useUser() function +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Hook to get the currently logged in user. Signature: diff --git a/etc/react.api.md b/etc/react.api.md index 5aabb3a..2b3f283 100644 --- a/etc/react.api.md +++ b/etc/react.api.md @@ -281,7 +281,7 @@ export interface SharedMediaProps { width?: HTMLIFrameElement["width"]; } -// @public (undocumented) +// @beta export interface ThirdwebAuthConfig { authUrl: string; domain: string; @@ -327,7 +327,7 @@ export interface ThirdwebSDKProviderProps extends Omit { +export interface ThirdwebSDKProviderWagmiWrapper extends Pick { // (undocumented) provider: ChainOrRpc | SignerOrProvider; // (undocumented) @@ -1442,10 +1442,10 @@ export function useListing(contract: RequiredParam, listingId: Requ // @beta export function useListings(contract: RequiredParam, filter?: MarketplaceFilter): UseQueryResult<(AuctionListing | DirectListing)[], unknown>; -// @public +// @beta export function useLogin(config?: LoginConfig): (cfg?: LoginOptions) => Promise; -// @public +// @beta export function useLogout(): () => void; // @public @@ -1740,7 +1740,7 @@ seller_fee_basis_points?: number | undefined; fee_recipient?: string | undefined; }, unknown>; -// @public +// @beta export function useUser(): { user: ThirdwebAuthUser | undefined; isLoading: boolean; @@ -1792,8 +1792,8 @@ export type WalletLinkConnectorType = "walletLink" | "coinbase" | { // Warnings were encountered during analysis: // -// dist/Provider.d.ts:37:5 - (ae-forgotten-export) The symbol "MagicConnectorArguments" needs to be exported by the entry point index.d.ts -// dist/Provider.d.ts:44:5 - (ae-forgotten-export) The symbol "GnosisConnectorArguments" needs to be exported by the entry point index.d.ts +// dist/Provider.d.ts:38:5 - (ae-forgotten-export) The symbol "MagicConnectorArguments" needs to be exported by the entry point index.d.ts +// dist/Provider.d.ts:45:5 - (ae-forgotten-export) The symbol "GnosisConnectorArguments" needs to be exported by the entry point index.d.ts // dist/hooks/async/roles.d.ts:126:5 - (ae-incompatible-release-tags) The symbol "role" is marked as @beta, but its signature references "RolesForContract" which is marked as @internal // dist/hooks/async/roles.d.ts:161:5 - (ae-incompatible-release-tags) The symbol "role" is marked as @beta, but its signature references "RolesForContract" which is marked as @internal // dist/hooks/auth/useUser.d.ts:12:5 - (ae-forgotten-export) The symbol "ThirdwebAuthUser" needs to be exported by the entry point index.d.ts diff --git a/src/Provider.tsx b/src/Provider.tsx index aa7c2b2..27daae1 100644 --- a/src/Provider.tsx +++ b/src/Provider.tsx @@ -8,6 +8,10 @@ import { SupportedChain, defaultSupportedChains, } from "./constants/chain"; +import { + ThirdwebAuthConfig, + ThirdwebAuthConfigProvider, +} from "./contexts/thirdweb-auth"; import { ThirdwebConfigProvider, defaultChainRpc, @@ -99,26 +103,6 @@ export type ChainRpc = Record< TSupportedChain extends Chain ? TSupportedChain["id"] : TSupportedChain, string >; - -export interface ThirdwebAuthConfig { - /** - * The backend URL of the authentication endoints. For example, if your endpoints are - * at /api/auth/login, /api/auth/logout, etc. then this should be set to "/api/auth". - */ - authUrl: string; - - /** - * The frontend domain used to generate the login payload. - * This domain should match the domain used on your auth backend. - */ - domain: string; - - /** - * The URL to redirect to after a succesful login. - */ - loginRedirect?: string; -} - /** * the metadata to pass to wallet connection dialog (may show up during the wallet-connection process) * @remarks this is only used for wallet connect and wallet link, metamask does not support it @@ -286,14 +270,6 @@ export const ThirdwebProvider = < }, {} as Record); }, [chainRpc, _supporrtedChains]); - // Remove trailing slash from URL if present - const _authConfig = authConfig - ? { - ...authConfig, - authUrl: authConfig.authUrl.replace(/\/$/, ""), - } - : undefined; - const wagmiProps: WagmiproviderProps = useMemo(() => { const walletConnectClientMeta = { name: dAppMeta.name, @@ -443,7 +419,6 @@ export const ThirdwebProvider = < value={{ rpcUrlMap: _rpcUrlMap, supportedChains: _supporrtedChains, - authConfig: _authConfig, }} > @@ -452,6 +427,7 @@ export const ThirdwebProvider = < desiredChainId={desiredChainId} sdkOptions={sdkOptionsWithDefaults} storageInterface={storageInterface} + authConfig={authConfig} > {children} @@ -463,7 +439,7 @@ export const ThirdwebProvider = < export interface ThirdwebSDKProviderWagmiWrapper extends Pick< ThirdwebProviderProps, - "desiredChainId" | "sdkOptions" | "storageInterface" + "desiredChainId" | "sdkOptions" | "storageInterface" | "authConfig" > { signer?: Signer; provider: ChainOrRpc | SignerOrProvider; @@ -515,6 +491,7 @@ export const ThirdwebSDKProvider: React.FC< provider, signer, queryClient, + authConfig, children, }) => { const queryClientWithDefault: QueryClient = useMemo(() => { @@ -546,11 +523,13 @@ export const ThirdwebSDKProvider: React.FC< ); return ( - - - {children} - - + + + + {children} + + + ); }; diff --git a/src/contexts/thirdweb-auth.tsx b/src/contexts/thirdweb-auth.tsx new file mode 100644 index 0000000..b3944b7 --- /dev/null +++ b/src/contexts/thirdweb-auth.tsx @@ -0,0 +1,54 @@ +import { PropsWithChildren, createContext, useContext, useMemo } from "react"; + +/** + * The configuration to use the react SDK with an [auth](https://portal.thirdweb.com/auth) server. + * + * @beta + */ +export interface ThirdwebAuthConfig { + /** + * The backend URL of the authentication endoints. For example, if your endpoints are + * at `/api/auth/login`, `/api/auth/logout`, etc. then this should be set to `/api/auth`. + */ + authUrl: string; + + /** + * The frontend domain used to generate the login payload. + * This domain should match the domain used on your auth backend. + */ + domain: string; + + /** + * The URL to redirect to after a succesful login. + */ + loginRedirect?: string; +} + +const ThirdwebAuthConfigContext = createContext( + undefined, +); + +export const ThirdwebAuthConfigProvider: React.FC< + PropsWithChildren<{ value?: ThirdwebAuthConfig }> +> = ({ value, children }) => { + // Remove trailing slash from URL if present + const authConfig = useMemo( + () => + value + ? { + ...value, + authUrl: value.authUrl.replace(/\/$/, ""), + } + : undefined, + [value], + ); + return ( + + {children} + + ); +}; + +export function useThirdwebAuthConfig() { + return useContext(ThirdwebAuthConfigContext); +} diff --git a/src/contexts/thirdweb-config.tsx b/src/contexts/thirdweb-config.tsx index a280e24..d20389b 100644 --- a/src/contexts/thirdweb-config.tsx +++ b/src/contexts/thirdweb-config.tsx @@ -1,4 +1,3 @@ -import { ThirdwebAuthConfig } from "../Provider"; import { Chain, SupportedChainId, @@ -10,7 +9,6 @@ import React, { PropsWithChildren, createContext, useContext } from "react"; interface ThirdwebConfigContext { rpcUrlMap: Record; supportedChains: Chain[]; - authConfig?: ThirdwebAuthConfig; } export const defaultChainRpc: Record = { @@ -23,7 +21,7 @@ export const defaultChainRpc: Record = { [ChainId.Avalanche]: "avalanche", }; -export const ThirdwebConfigContext = createContext({ +const ThirdwebConfigContext = createContext({ rpcUrlMap: defaultChainRpc, supportedChains: defaultSupportedChains, }); diff --git a/src/hooks/auth/useLogin.ts b/src/hooks/auth/useLogin.ts index 88cd6a4..c9b7e6b 100644 --- a/src/hooks/auth/useLogin.ts +++ b/src/hooks/auth/useLogin.ts @@ -1,5 +1,5 @@ import { useSDK } from "../../Provider"; -import { useThirdwebConfigContext } from "../../contexts/thirdweb-config"; +import { useThirdwebAuthConfig } from "../../contexts/thirdweb-auth"; import { cacheKeys } from "../../utils/cache-keys"; import { useQueryClient } from "@tanstack/react-query"; import { LoginOptions } from "@thirdweb-dev/sdk/dist/src/schema"; @@ -24,12 +24,12 @@ export interface LoginConfig { * @param config - Configuration for the login. * @returns - A function to invoke to login with the connected wallet. * - * @public + * @beta */ export function useLogin(config?: LoginConfig) { const sdk = useSDK(); const queryClient = useQueryClient(); - const { authConfig } = useThirdwebConfigContext(); + const authConfig = useThirdwebAuthConfig(); React.useEffect(() => { const queryParams = new URLSearchParams(window.location.search); @@ -50,7 +50,9 @@ export function useLogin(config?: LoginConfig) { const encodedPayload = encodeURIComponent(btoa(JSON.stringify(payload))); const encodedRedirectTo = encodeURIComponent( - config?.redirectTo || authConfig.loginRedirect || window.location.href, + config?.redirectTo || + authConfig.loginRedirect || + window.location.toString(), ); queryClient.invalidateQueries(cacheKeys.auth.user()); diff --git a/src/hooks/auth/useLogout.ts b/src/hooks/auth/useLogout.ts index 69af49c..980df11 100644 --- a/src/hooks/auth/useLogout.ts +++ b/src/hooks/auth/useLogout.ts @@ -1,4 +1,4 @@ -import { useThirdwebConfigContext } from "../../contexts/thirdweb-config"; +import { useThirdwebAuthConfig } from "../../contexts/thirdweb-auth"; import { cacheKeys } from "../../utils/cache-keys"; import { useQueryClient } from "@tanstack/react-query"; import invariant from "tiny-invariant"; @@ -9,11 +9,11 @@ import invariant from "tiny-invariant"; * * @returns - A function to invoke to logout. * - * @public + * @beta */ export function useLogout() { const queryClient = useQueryClient(); - const { authConfig } = useThirdwebConfigContext(); + const authConfig = useThirdwebAuthConfig(); function logout() { invariant( diff --git a/src/hooks/auth/useUser.ts b/src/hooks/auth/useUser.ts index 0bd4b7f..7611ba2 100644 --- a/src/hooks/auth/useUser.ts +++ b/src/hooks/auth/useUser.ts @@ -1,4 +1,4 @@ -import { useThirdwebConfigContext } from "../../contexts/thirdweb-config"; +import { useThirdwebAuthConfig } from "../../contexts/thirdweb-auth"; import { cacheKeys } from "../../utils/cache-keys"; import { useQuery } from "@tanstack/react-query"; import invariant from "tiny-invariant"; @@ -12,10 +12,10 @@ interface ThirdwebAuthUser { * * @returns - The currently logged in user or null if not logged in, as well as a loading state. * - * @public + * @beta */ export function useUser() { - const { authConfig } = useThirdwebConfigContext(); + const authConfig = useThirdwebAuthConfig(); const { data: user, isLoading } = useQuery( cacheKeys.auth.user(), diff --git a/src/index.ts b/src/index.ts index 7455185..9668e80 100644 --- a/src/index.ts +++ b/src/index.ts @@ -36,3 +36,4 @@ export * from "./hooks/async/roles"; // types export * from "./types"; +export type { ThirdwebAuthConfig } from "./contexts/thirdweb-auth";