-
Notifications
You must be signed in to change notification settings - Fork 328
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Winston/add embedded wallet export for react (#1622)
Co-authored-by: Manan Tank <[email protected]>
- Loading branch information
1 parent
710739c
commit 4268775
Showing
14 changed files
with
749 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@thirdweb-dev/react": minor | ||
--- | ||
|
||
feat(react): add `embeddedWallet` wallet type |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
116 changes: 116 additions & 0 deletions
116
packages/react/src/wallet/wallets/embeddedWallet/EmbeddedWalletFormUI.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import styled from "@emotion/styled"; | ||
import { Spacer } from "../../../components/Spacer"; | ||
import { Container, ModalHeader } from "../../../components/basic"; | ||
import { Button } from "../../../components/buttons"; | ||
import { Theme, iconSize, spacing } from "../../../design-system"; | ||
import { GoogleIcon } from "../../ConnectWallet/icons/GoogleIcon"; | ||
import { InputSelectionUI } from "../InputSelectionUI"; | ||
import type { EmbeddedWalletLoginType } from "./types"; | ||
import { | ||
WalletConfig, | ||
useCreateWalletInstance, | ||
useSetConnectedWallet, | ||
useSetConnectionStatus, | ||
} from "@thirdweb-dev/react-core"; | ||
import { EmbeddedWallet } from "@thirdweb-dev/wallets"; | ||
|
||
export const EmbeddedWalletFormUI = (props: { | ||
onSelect: (loginType: EmbeddedWalletLoginType) => void; | ||
showOrSeparator?: boolean; | ||
walletConfig: WalletConfig<EmbeddedWallet>; | ||
}) => { | ||
const createWalletInstance = useCreateWalletInstance(); | ||
const setConnectionStatus = useSetConnectionStatus(); | ||
const setConnectedWallet = useSetConnectedWallet(); | ||
|
||
// Need to trigger google login on button click to avoid popup from being blocked | ||
const googleLogin = async () => { | ||
try { | ||
const embeddedWallet = createWalletInstance(props.walletConfig); | ||
setConnectionStatus("connecting"); | ||
await embeddedWallet.connect({ googleLogin: true }); | ||
setConnectedWallet(embeddedWallet); | ||
close(); | ||
} catch (e) { | ||
setConnectionStatus("disconnected"); | ||
console.error(e); | ||
} | ||
}; | ||
|
||
return ( | ||
<div> | ||
<SocialButton | ||
variant="secondary" | ||
fullWidth | ||
onClick={() => { | ||
googleLogin(); | ||
props.onSelect({ google: true }); | ||
}} | ||
> | ||
<GoogleIcon size={iconSize.md} /> | ||
Sign in with Google | ||
</SocialButton> | ||
|
||
<Spacer y="lg" /> | ||
|
||
<InputSelectionUI | ||
onSelect={(email) => props.onSelect({ email })} | ||
placeholder="Enter your email address" | ||
name="email" | ||
type="email" | ||
errorMessage={(_input) => { | ||
const input = _input.replace(/\+/g, ""); | ||
const emailRegex = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,})$/g; | ||
const isValidEmail = emailRegex.test(input); | ||
if (!isValidEmail) { | ||
return "Invalid email address"; | ||
} | ||
}} | ||
emptyErrorMessage="email address is required" | ||
showOrSeparator={props.showOrSeparator} | ||
/> | ||
</div> | ||
); | ||
}; | ||
|
||
export const EmbeddedWalletFormUIScreen: React.FC<{ | ||
onSelect: (loginType: EmbeddedWalletLoginType) => void; | ||
onBack: () => void; | ||
modalSize: "compact" | "wide"; | ||
walletConfig: WalletConfig<EmbeddedWallet>; | ||
}> = (props) => { | ||
const isCompact = props.modalSize === "compact"; | ||
return ( | ||
<Container | ||
fullHeight | ||
flex="column" | ||
p="lg" | ||
animate="fadein" | ||
style={{ | ||
minHeight: "250px", | ||
}} | ||
> | ||
<ModalHeader onBack={props.onBack} title="Sign in" /> | ||
{isCompact ? <Spacer y="xl" /> : null} | ||
|
||
<Container | ||
expand | ||
flex="column" | ||
center="y" | ||
p={isCompact ? undefined : "lg"} | ||
> | ||
<EmbeddedWalletFormUI | ||
walletConfig={props.walletConfig} | ||
onSelect={props.onSelect} | ||
showOrSeparator={false} | ||
/> | ||
</Container> | ||
</Container> | ||
); | ||
}; | ||
|
||
const SocialButton = /* @__PURE__ */ styled(Button)<{ theme?: Theme }>` | ||
display: flex; | ||
justify-content: center; | ||
gap: ${spacing.sm}; | ||
`; |
106 changes: 106 additions & 0 deletions
106
packages/react/src/wallet/wallets/embeddedWallet/EmbeddedWalletGoogleLogin.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import { | ||
ConnectUIProps, | ||
useConnectionStatus, | ||
useCreateWalletInstance, | ||
useSetConnectedWallet, | ||
useSetConnectionStatus, | ||
} from "@thirdweb-dev/react-core"; | ||
import { EmbeddedWallet } from "@thirdweb-dev/wallets"; | ||
import { Spacer } from "../../../components/Spacer"; | ||
import { Spinner } from "../../../components/Spinner"; | ||
import { Container, ModalHeader } from "../../../components/basic"; | ||
import { Button } from "../../../components/buttons"; | ||
import { ModalTitle } from "../../../components/modalElements"; | ||
import { Text } from "../../../components/text"; | ||
import { iconSize } from "../../../design-system"; | ||
import { GoogleIcon } from "../../ConnectWallet/icons/GoogleIcon"; | ||
|
||
export const EmbeddedWalletGoogleLogin = ( | ||
props: ConnectUIProps<EmbeddedWallet>, | ||
) => { | ||
const { goBack, modalSize } = props; | ||
const createWalletInstance = useCreateWalletInstance(); | ||
const setConnectionStatus = useSetConnectionStatus(); | ||
const setConnectedWallet = useSetConnectedWallet(); | ||
const connectionStatus = useConnectionStatus(); | ||
|
||
const googleLogin = async () => { | ||
try { | ||
const embeddedWallet = createWalletInstance(props.walletConfig); | ||
setConnectionStatus("connecting"); | ||
await embeddedWallet.connect({ googleLogin: true }); | ||
setConnectedWallet(embeddedWallet); | ||
props.close(); | ||
} catch (e) { | ||
setConnectionStatus("disconnected"); | ||
console.error(e); | ||
} | ||
}; | ||
|
||
return ( | ||
<Container animate="fadein" flex="column" fullHeight> | ||
<Container | ||
flex="column" | ||
expand | ||
p="lg" | ||
style={{ | ||
paddingBottom: 0, | ||
}} | ||
> | ||
<ModalHeader | ||
title={ | ||
<Container flex="row" center="both" gap="xs"> | ||
<GoogleIcon size={iconSize.md} /> | ||
<ModalTitle> Sign in </ModalTitle> | ||
</Container> | ||
} | ||
onBack={goBack} | ||
/> | ||
|
||
{modalSize === "compact" ? <Spacer y="xl" /> : null} | ||
|
||
<Container | ||
flex="column" | ||
center="both" | ||
expand | ||
style={{ | ||
textAlign: "center", | ||
minHeight: "250px", | ||
}} | ||
> | ||
{connectionStatus === "connecting" && ( | ||
<Container animate="fadein"> | ||
<Text | ||
color="primaryText" | ||
multiline | ||
style={{ | ||
maxWidth: "250px", | ||
}} | ||
> | ||
Select your Google account in the pop-up | ||
</Text> | ||
<Spacer y="xl" /> | ||
<Container center="x" flex="row"> | ||
<Spinner size="lg" color="accentText" /> | ||
</Container> | ||
|
||
<Spacer y="xxl" /> | ||
</Container> | ||
)} | ||
|
||
{connectionStatus === "disconnected" && ( | ||
<Container animate="fadein"> | ||
<Text color="danger">Failed to sign in</Text> | ||
<Spacer y="lg" /> | ||
<Button variant="primary" onClick={googleLogin}> | ||
{" "} | ||
Retry{" "} | ||
</Button> | ||
<Spacer y="xxl" /> | ||
</Container> | ||
)} | ||
</Container> | ||
</Container> | ||
</Container> | ||
); | ||
}; |
Oops, something went wrong.