diff --git a/apps/example/cfg/auth.ts b/apps/example/cfg/auth.ts new file mode 100644 index 0000000..2d14510 --- /dev/null +++ b/apps/example/cfg/auth.ts @@ -0,0 +1,9 @@ +import { ThirdwebAuth } from "@thirdweb-dev/auth/next"; +import { ethers } from "ethers"; + +const privateKey = ethers.Wallet.createRandom().privateKey; + +export const { ThirdwebAuthHandler, getUser } = ThirdwebAuth({ + domain: "example.com", + privateKey, +}); diff --git a/apps/example/package.json b/apps/example/package.json index acf56d9..4cdde65 100644 --- a/apps/example/package.json +++ b/apps/example/package.json @@ -9,6 +9,7 @@ "lint": "next lint" }, "dependencies": { + "@thirdweb-dev/auth": "^0.2.0", "@thirdweb-dev/react": "*", "@thirdweb-dev/sdk": "^2", "ethers": "^5.6.8", diff --git a/apps/example/pages/_app.tsx b/apps/example/pages/_app.tsx index d00a28f..2306b7f 100644 --- a/apps/example/pages/_app.tsx +++ b/apps/example/pages/_app.tsx @@ -6,7 +6,10 @@ const activeChainId = ChainId.Rinkeby; function MyApp({ Component, pageProps }: AppProps) { return ( - + ); diff --git a/apps/example/pages/api/auth/[...thirdweb].tsx b/apps/example/pages/api/auth/[...thirdweb].tsx new file mode 100644 index 0000000..e31d2c8 --- /dev/null +++ b/apps/example/pages/api/auth/[...thirdweb].tsx @@ -0,0 +1,3 @@ +import { ThirdwebAuthHandler } from "../../../cfg/auth"; + +export default ThirdwebAuthHandler(); diff --git a/packages/thirdweb-react/docs/react.md b/packages/thirdweb-react/docs/react.md index 27173d4..82c560b 100644 --- a/packages/thirdweb-react/docs/react.md +++ b/packages/thirdweb-react/docs/react.md @@ -147,6 +147,7 @@ import { useWalletConnect } from "@thirdweb-dev/react" | [MediaType](./react.mediatype.md) | | | [SharedMediaProps](./react.sharedmediaprops.md) | | | [ThirdwebAuthConfig](./react.thirdwebauthconfig.md) | (BETA) The configuration to use the react SDK with an \[auth\](https://portal.thirdweb.com/auth) server. | +| [ThirdwebAuthUser](./react.thirdwebauthuser.md) | | | [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/packages/thirdweb-react/docs/react.thirdwebauthuser.address.md b/packages/thirdweb-react/docs/react.thirdwebauthuser.address.md new file mode 100644 index 0000000..c2c3143 --- /dev/null +++ b/packages/thirdweb-react/docs/react.thirdwebauthuser.address.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [@thirdweb-dev/react](./react.md) > [ThirdwebAuthUser](./react.thirdwebauthuser.md) > [address](./react.thirdwebauthuser.address.md) + +## ThirdwebAuthUser.address property + +Signature: + +```typescript +address: string; +``` diff --git a/packages/thirdweb-react/docs/react.thirdwebauthuser.md b/packages/thirdweb-react/docs/react.thirdwebauthuser.md new file mode 100644 index 0000000..275586a --- /dev/null +++ b/packages/thirdweb-react/docs/react.thirdwebauthuser.md @@ -0,0 +1,18 @@ + + +[Home](./index.md) > [@thirdweb-dev/react](./react.md) > [ThirdwebAuthUser](./react.thirdwebauthuser.md) + +## ThirdwebAuthUser interface + +Signature: + +```typescript +export interface ThirdwebAuthUser +``` + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [address](./react.thirdwebauthuser.address.md) | | string | | + diff --git a/packages/thirdweb-react/docs/react.useuser.md b/packages/thirdweb-react/docs/react.useuser.md index a7c4370..1f22cde 100644 --- a/packages/thirdweb-react/docs/react.useuser.md +++ b/packages/thirdweb-react/docs/react.useuser.md @@ -19,7 +19,7 @@ export declare function useUser(): { ``` Returns: -{ user: ThirdwebAuthUser \| undefined; isLoading: boolean; } +{ user: [ThirdwebAuthUser](./react.thirdwebauthuser.md) \| undefined; isLoading: boolean; } - The currently logged in user or null if not logged in, as well as a loading state. diff --git a/packages/thirdweb-react/etc/react.api.md b/packages/thirdweb-react/etc/react.api.md index 9c59d7c..850caa0 100644 --- a/packages/thirdweb-react/etc/react.api.md +++ b/packages/thirdweb-react/etc/react.api.md @@ -42,6 +42,7 @@ import { IStorage } from '@thirdweb-dev/sdk/dist/browser'; import { Json } from '@thirdweb-dev/sdk/dist/browser'; import { ListingType } from '@thirdweb-dev/sdk/dist/browser'; import { LoginOptions } from '@thirdweb-dev/sdk/dist/src/schema'; +import { LoginOptions as LoginOptions_2 } from '@thirdweb-dev/sdk'; import { LoginWithMagicLinkConfiguration } from 'magic-sdk'; import type { MagicSDKAdditionalConfiguration } from 'magic-sdk'; import { Marketplace } from '@thirdweb-dev/sdk/dist/browser'; @@ -318,6 +319,12 @@ export interface ThirdwebAuthConfig { loginRedirect?: string; } +// @public (undocumented) +export interface ThirdwebAuthUser { + // (undocumented) + address: string; +} + // @beta (undocumented) export const ThirdwebNftMedia: React_2.ForwardRefExoticComponent>; @@ -447,6 +454,20 @@ export function useAllRoleMembers(contract: // @beta export function useAuctionWinner(contract: RequiredParam, listingId: RequiredParam): UseQueryResult; +// Warning: (ae-internal-missing-underscore) The name "useAuth" should be prefixed with an underscore because the declaration is marked as @internal +// +// @internal (undocumented) +export function useAuth(loginConfig?: LoginConfig): { + login: (cfg?: { + chainId?: number | undefined; + nonce?: string | undefined; + expirationTime?: Date | undefined; + } | undefined) => Promise; + logout: () => void; + user: ThirdwebAuthUser | undefined; + isLoading: boolean; +}; + // @beta export function useBalance(tokenAddress?: ContractAddress): UseQueryResult< { symbol: string; @@ -1859,7 +1880,6 @@ export const Web3Button: React.FC>; // dist/declarations/dist/Provider.d.ts:45:5 - (ae-forgotten-export) The symbol "GnosisConnectorArguments" needs to be exported by the entry point thirdweb-dev-react.cjs.d.ts // dist/declarations/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/declarations/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/declarations/dist/hooks/auth/useUser.d.ts:12:5 - (ae-forgotten-export) The symbol "ThirdwebAuthUser" needs to be exported by the entry point thirdweb-dev-react.cjs.d.ts // dist/declarations/dist/hooks/useNetwork.d.ts:48:5 - (ae-forgotten-export) The symbol "SwitchChainError" needs to be exported by the entry point thirdweb-dev-react.cjs.d.ts // dist/declarations/dist/types.d.ts:215:5 - (ae-incompatible-release-tags) The symbol "buyForWallet" is marked as @public, but its signature references "WalletAddress" which is marked as @beta // dist/declarations/dist/types.d.ts:221:5 - (ae-incompatible-release-tags) The symbol "to" is marked as @public, but its signature references "WalletAddress" which is marked as @beta diff --git a/packages/thirdweb-react/package.json b/packages/thirdweb-react/package.json index ab675a2..7070ffc 100644 --- a/packages/thirdweb-react/package.json +++ b/packages/thirdweb-react/package.json @@ -1,6 +1,6 @@ { "name": "@thirdweb-dev/react", - "version": "2.7.0", + "version": "2.7.1-2", "repository": { "type": "git", "url": "git+https://github.com:thirdweb-dev/react.git" diff --git a/packages/thirdweb-react/src/components/ConnectWallet/index.tsx b/packages/thirdweb-react/src/components/ConnectWallet/index.tsx index f7018e4..389021f 100644 --- a/packages/thirdweb-react/src/components/ConnectWallet/index.tsx +++ b/packages/thirdweb-react/src/components/ConnectWallet/index.tsx @@ -1,4 +1,6 @@ +import { useThirdwebAuthConfig } from "../../contexts/thirdweb-auth"; import { useBalance } from "../../hooks/async/wallet"; +import { LoginConfig, useAuth } from "../../hooks/auth"; import { useMetamask } from "../../hooks/connectors/useMetamask"; import { useAddress } from "../../hooks/useAddress"; import { useChainId } from "../../hooks/useChainId"; @@ -18,7 +20,7 @@ import { ThemeProvider, ThemeProviderProps } from "../shared/ThemeProvider"; import { fontFamily } from "../theme"; import { SupportedNetworkSelect } from "./NetworkSelect"; import { Portal } from "@reach/portal"; -import { ChainId, SUPPORTED_CHAIN_ID } from "@thirdweb-dev/sdk"; +import { ChainId, LoginOptions, SUPPORTED_CHAIN_ID } from "@thirdweb-dev/sdk"; import * as menu from "@zag-js/menu"; import { normalizeProps, useMachine } from "@zag-js/react"; import React, { useId, useMemo } from "react"; @@ -26,6 +28,8 @@ import { FiCheck, FiChevronDown, FiCopy, + FiLock, + FiShuffle, FiWifi, FiXCircle, } from "react-icons/fi"; @@ -57,10 +61,18 @@ function getIconForConnector(connector: Connector) { } } -interface ConnectWalletProps extends ThemeProviderProps {} +interface ConnectWalletProps extends ThemeProviderProps { + auth?: { + loginOptions?: LoginOptions; + loginConfig?: LoginConfig; + loginOptional?: boolean; + }; +} let connecting = false; let switchingNetwork = false; +let authing = false; +let switchingWallet = false; const chainIdToCurrencyMap: Record< SUPPORTED_CHAIN_ID, @@ -108,6 +120,7 @@ const chainIdToCurrencyMap: Record< * @beta */ export const ConnectWallet: React.FC = ({ + auth, ...themeProps }) => { const id = useId(); @@ -151,6 +164,13 @@ export const ConnectWallet: React.FC = ({ const { onCopy, hasCopied } = useClipboard(mountedAddress || ""); + const authConfig = useThirdwebAuthConfig(); + const { user, isLoading, login, logout } = useAuth(auth?.loginConfig); + + const requiresSignIn = auth?.loginOptional + ? false + : !!authConfig?.authUrl && !!mountedAddress && !user?.address; + return (
= ({ }} >