From c70433434279d2fb634e018df1ba81d818f5d1e8 Mon Sep 17 00:00:00 2001 From: Corban Brook Date: Tue, 23 Jul 2024 14:08:57 -0400 Subject: [PATCH] v2.10.1 (#109) * Adding getSequenceWaas function * Fix email auth * v2.10.1 --- examples/next/CHANGELOG.md | 9 + examples/next/package.json | 2 +- examples/react/CHANGELOG.md | 9 + examples/react/package.json | 2 +- packages/checkout/CHANGELOG.md | 9 + packages/checkout/package.json | 2 +- packages/kit/CHANGELOG.md | 6 + packages/kit/package.json | 2 +- .../ConnectButton/ConnectButton.tsx | 178 ++++++++++++ .../kit/src/components/ConnectButton/index.ts | 1 + .../ConnectWalletContent/index.tsx | 270 +++--------------- packages/kit/src/hooks/useWaasEmailAuth.ts | 27 +- packages/wallet/CHANGELOG.md | 9 + packages/wallet/package.json | 2 +- 14 files changed, 281 insertions(+), 247 deletions(-) create mode 100644 packages/kit/src/components/ConnectButton/ConnectButton.tsx create mode 100644 packages/kit/src/components/ConnectButton/index.ts diff --git a/examples/next/CHANGELOG.md b/examples/next/CHANGELOG.md index cd76a753..7e0beb98 100644 --- a/examples/next/CHANGELOG.md +++ b/examples/next/CHANGELOG.md @@ -1,5 +1,14 @@ # @0xsequence/kit-example-next +## 0.6.14 + +### Patch Changes + +- Updated dependencies []: + - @0xsequence/kit@2.10.1 + - @0xsequence/kit-checkout@2.10.1 + - @0xsequence/kit-wallet@2.10.1 + ## 0.6.13 ### Patch Changes diff --git a/examples/next/package.json b/examples/next/package.json index 611007da..983ded0a 100644 --- a/examples/next/package.json +++ b/examples/next/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/kit-example-next", - "version": "0.6.13", + "version": "0.6.14", "private": true, "scripts": { "dev": "next dev -p 4444", diff --git a/examples/react/CHANGELOG.md b/examples/react/CHANGELOG.md index bd1b9bd8..0e3fb8e9 100644 --- a/examples/react/CHANGELOG.md +++ b/examples/react/CHANGELOG.md @@ -1,5 +1,14 @@ # @0xsequence/kit-example-react +## 0.7.14 + +### Patch Changes + +- Updated dependencies []: + - @0xsequence/kit@2.10.1 + - @0xsequence/kit-checkout@2.10.1 + - @0xsequence/kit-wallet@2.10.1 + ## 0.7.13 ### Patch Changes diff --git a/examples/react/package.json b/examples/react/package.json index 46c05057..893201d9 100644 --- a/examples/react/package.json +++ b/examples/react/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/kit-example-react", - "version": "0.7.13", + "version": "0.7.14", "private": true, "homepage": "kit", "type": "module", diff --git a/packages/checkout/CHANGELOG.md b/packages/checkout/CHANGELOG.md index 61db3a9a..76df85c6 100644 --- a/packages/checkout/CHANGELOG.md +++ b/packages/checkout/CHANGELOG.md @@ -1,5 +1,14 @@ # @0xsequence/kit-connectors +## 2.10.1 + +### Patch Changes + +- Fixing email auth + +- Updated dependencies []: + - @0xsequence/kit@2.10.1 + ## 2.10.0 ### Minor Changes diff --git a/packages/checkout/package.json b/packages/checkout/package.json index 260b7ff2..32f5c8b3 100644 --- a/packages/checkout/package.json +++ b/packages/checkout/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/kit-checkout", - "version": "2.10.0", + "version": "2.10.1", "description": "Checkout UI for Sequence Kit", "repository": "https://github.com/0xsequence/kit/tree/master/packages/checkout", "author": "Horizon Blockchain Games", diff --git a/packages/kit/CHANGELOG.md b/packages/kit/CHANGELOG.md index e5a20638..95bf876b 100644 --- a/packages/kit/CHANGELOG.md +++ b/packages/kit/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/kit +## 2.10.1 + +### Patch Changes + +- Fixing email auth + ## 2.10.0 ### Minor Changes diff --git a/packages/kit/package.json b/packages/kit/package.json index 9f649f38..29f307f9 100644 --- a/packages/kit/package.json +++ b/packages/kit/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/kit", - "version": "2.10.0", + "version": "2.10.1", "description": "Core package for Sequence Kit", "keywords": [ "sequence", diff --git a/packages/kit/src/components/ConnectButton/ConnectButton.tsx b/packages/kit/src/components/ConnectButton/ConnectButton.tsx new file mode 100644 index 00000000..97042661 --- /dev/null +++ b/packages/kit/src/components/ConnectButton/ConnectButton.tsx @@ -0,0 +1,178 @@ +import { Box, Card, EmailIcon, Tooltip, useTheme } from '@0xsequence/design-system' +import { GoogleLogin } from '@react-oauth/google' +import { useEffect, useState } from 'react' +import { appleAuthHelpers } from 'react-apple-signin-auth' + +import { LocalStorageKey } from '../../constants' +import { useStorage, useStorageItem } from '../../hooks/useStorage' +import { ExtendedConnector, WalletProperties } from '../../types' + +const BUTTON_SIZE = '14' +const ICON_SIZE = '10' + +const getLogo = (theme: any, walletProps: WalletProperties) => + theme === 'dark' + ? walletProps.logoDark || walletProps.monochromeLogoDark + : walletProps.logoLight || walletProps.monochromeLogoLight + +interface ConnectButtonProps { + connector: ExtendedConnector + label?: string + onConnect: (connector: ExtendedConnector) => void +} + +export const ConnectButton = (props: ConnectButtonProps) => { + const { connector, label, onConnect } = props + const { theme } = useTheme() + const walletProps = connector._wallet + + const Logo = getLogo(theme, walletProps) + + return ( + + onConnect(connector)} + > + + + + ) +} + +export const GoogleWaasConnectButton = (props: ConnectButtonProps) => { + const { connector, onConnect } = props + const storage = useStorage() + const { data: sessionHash, isPending: isPendingNonce } = useStorageItem(LocalStorageKey.WaasSessionHash) + const [enableGoogleTooltip, setEnableGoogleTooltip] = useState(false) + const { theme } = useTheme() + const walletProps = connector._wallet + + const Logo = getLogo(theme, walletProps) + + useEffect(() => { + setTimeout(() => { + setEnableGoogleTooltip(true) + }, 300) + }) + + return !isPendingNonce ? ( + + + + { + if (credentialResponse.credential) { + storage?.setItem(LocalStorageKey.WaasGoogleIdToken, credentialResponse.credential) + onConnect(connector) + } + }} + onError={() => { + console.log('Login Failed') + }} + /> + + + + + + + ) : null +} + +export const AppleWaasConnectButton = (props: ConnectButtonProps) => { + const { connector, onConnect } = props + const storage = useStorage() + const { data: sessionHash, isPending: isPendingNonce } = useStorageItem(LocalStorageKey.WaasSessionHash) + const { data: appleClientId } = useStorageItem(LocalStorageKey.WaasAppleClientID) + const { data: appleRedirectUri } = useStorageItem(LocalStorageKey.WaasAppleRedirectURI) + + return !isPendingNonce && appleClientId && appleRedirectUri ? ( + { + appleAuthHelpers.signIn({ + authOptions: { + clientId: appleClientId, + redirectURI: appleRedirectUri, + nonce: sessionHash, + scope: 'openid email', + usePopup: true + }, + onSuccess: (response: any) => { + if (response.authorization?.id_token) { + storage?.setItem(LocalStorageKey.WaasAppleIdToken, response.authorization.id_token) + onConnect(connector) + } else { + console.log('Apple login error: No id_token found') + } + }, + onError: (error: any) => console.error(error) + }) + }} + /> + ) : null +} + +interface EmailConnectButtonProps { + onClick: () => void +} + +export const EmailConnectButton = (props: EmailConnectButtonProps) => { + const { onClick } = props + + return ( + + + + + + ) +} diff --git a/packages/kit/src/components/ConnectButton/index.ts b/packages/kit/src/components/ConnectButton/index.ts new file mode 100644 index 00000000..3c79452a --- /dev/null +++ b/packages/kit/src/components/ConnectButton/index.ts @@ -0,0 +1 @@ +export { ConnectButton, GoogleWaasConnectButton, AppleWaasConnectButton, EmailConnectButton } from './ConnectButton' diff --git a/packages/kit/src/components/KitProvider/ConnectWalletContent/index.tsx b/packages/kit/src/components/KitProvider/ConnectWalletContent/index.tsx index 29ce9f00..58e8f14a 100644 --- a/packages/kit/src/components/KitProvider/ConnectWalletContent/index.tsx +++ b/packages/kit/src/components/KitProvider/ConnectWalletContent/index.tsx @@ -1,30 +1,26 @@ import { Box, Button, - Card, ChevronLeftIcon, ChevronRightIcon, Divider, Text, TextInput, - useTheme, Spinner, Image, IconButton, - Tooltip, - PINCodeInput, - EmailIcon + PINCodeInput } from '@0xsequence/design-system' -import { GoogleLogin } from '@react-oauth/google' import React, { useState, useEffect } from 'react' import { appleAuthHelpers, useScript } from 'react-apple-signin-auth' import { useConnect, useAccount } from 'wagmi' import { LocalStorageKey } from '../../../constants' -import { useStorage, useStorageItem } from '../../../hooks/useStorage' +import { useStorage } from '../../../hooks/useStorage' import { useEmailAuth } from '../../../hooks/useWaasEmailAuth' -import { ExtendedConnector, KitConfig, LogoProps, WalletProperties } from '../../../types' +import { ExtendedConnector, KitConfig, LogoProps } from '../../../types' import { isEmailValid } from '../../../utils/helpers' +import { AppleWaasConnectButton, ConnectButton, EmailConnectButton, GoogleWaasConnectButton } from '../../ConnectButton' import { KitConnectProviderProps } from '../index' import { Banner } from './Banner' @@ -48,46 +44,36 @@ export const ConnectWalletContent = (props: ConnectWalletContentProps) => { const [email, setEmail] = useState('') const [showEmailInput, setShowEmailInput] = useState(false) const [showEmailWaasPinInput, setShowEmailWaasPinInput] = useState(false) + const [showExtendedList, setShowExtendedList] = useState(false) const [waasEmailPinCode, setWaasEmailPinCode] = useState([]) - const { connectors: baseConnectors, connect } = useConnect() + const { connectors, connect } = useConnect() - const injectedSequenceConnector = baseConnectors.find(c => c.id === 'app.sequence') + const hasInjectedSequenceConnector = connectors.some(c => c.id === 'app.sequence') - const baseWalletConnectors = baseConnectors - .filter(c => { - /* @ts-ignore-next-line */ - const isWalletProperties = !!c?._wallet - /* @ts-ignore-next-line */ - const isWallet = (c?._wallet?.type || 'wallet') === 'wallet' - /* @ts-ignore-next-line */ - const displayEmailConnector = c?._wallet?.id === 'email' - - return isWalletProperties && (isWallet || displayEmailConnector) + const baseWalletConnectors = (connectors as ExtendedConnector[]) + .filter(c => { + return c._wallet && (c._wallet.type === 'wallet' || c._wallet.type === undefined) }) // Remove sequence if wallet extension detected - .filter(c => { - /* @ts-ignore-next-line */ - if (c?._wallet?.id === 'sequence' && injectedSequenceConnector) { - return false - } + .filter(c => { + if (c._wallet?.id === 'sequence' && hasInjectedSequenceConnector) { + return false + } + + return true + }) - return true - }) as ExtendedConnector[] - const [showExtendedList, setShowExtendedList] = useState(false) const mockConnector = baseWalletConnectors.find(connector => { return connector._wallet.id === 'mock' }) - /* @ts-ignore-next-line */ - const emailConnector = baseConnectors.find(c => c?._wallet?.id.includes('email')) - // EIP-6963 connectors will not have the _wallet property - const injectedConnectors: ExtendedConnector[] = baseConnectors + const injectedConnectors: ExtendedConnector[] = connectors .filter(c => c.type === 'injected') // Remove the injected connectors when another connector is already in the base connectors - .filter((connector) => { + .filter(connector => { if (connector.id === 'com.coinbase.wallet') { - return !baseConnectors.find(connector => (connector as ExtendedConnector)?._wallet?.id === 'coinbase-wallet') + return !connectors.find(connector => (connector as ExtendedConnector)?._wallet?.id === 'coinbase-wallet') } return true @@ -109,20 +95,10 @@ export const ConnectWalletContent = (props: ConnectWalletContentProps) => { } }) - - const walletConnectors = [ - ...baseWalletConnectors, - ...injectedConnectors - ] - - const socialAuthConnectors = baseConnectors - /* @ts-ignore-next-line */ - .filter(c => (c?._wallet?.type === 'social')) - /* @ts-ignore-next-line */ - .filter(c => !c?._wallet?.id?.includes('email')) as ExtendedConnector[] - - const isEmailOnly = emailConnector && socialAuthConnectors.length === 0 && walletConnectors.length === 0 - + const socialAuthConnectors = (connectors as ExtendedConnector[]).filter(c => c._wallet?.type === 'social') + const walletConnectors = [...baseWalletConnectors, ...injectedConnectors] + const emailConnector = socialAuthConnectors.find(c => c._wallet.id.includes('email')) + const isEmailOnly = emailConnector && socialAuthConnectors.length === 1 && walletConnectors.length === 0 const displayExtendedListButton = walletConnectors.length > 7 const onChangeEmail: React.ChangeEventHandler = ev => { @@ -135,7 +111,7 @@ export const ConnectWalletContent = (props: ConnectWalletContentProps) => { initiateAuth: initiateEmailAuth, sendChallengeAnswer } = useEmailAuth({ - connector: baseWalletConnectors.find(c => c._wallet.id === 'email-waas'), + connector: socialAuthConnectors.find(c => c._wallet.id === 'email-waas'), onSuccess: async idToken => { storage?.setItem(LocalStorageKey.WaasEmailIdToken, idToken) if (emailConnector) { @@ -260,35 +236,29 @@ export const ConnectWalletContent = (props: ConnectWalletContentProps) => { ) : ( <> - {(emailConnector || socialAuthConnectors.length > 0) && ( + {socialAuthConnectors.length > 0 && ( {socialAuthConnectors.map(connector => { return ( - {connector._wallet.id === 'google-waas' && ( + {connector._wallet.id === 'google-waas' ? ( - )} - - {connector._wallet.id === 'apple-waas' && ( + ) : connector._wallet.id === 'apple-waas' ? ( + ) : connector._wallet.id.includes('email') ? ( + setShowEmailInput(true)} /> + ) : ( + )} - - {!connector._wallet.id.includes('waas') && } ) })} - - {emailConnector && ( - - setShowEmailInput(true)} /> - - )} )} {walletConnectors.length > 0 && ( <> - {(emailConnector || socialAuthConnectors.length > 0) && ( + {socialAuthConnectors.length > 0 && ( <> @@ -300,10 +270,6 @@ export const ConnectWalletContent = (props: ConnectWalletContentProps) => { )} {walletConnectors.slice(0, 7).map(connector => { - if (connector._wallet.id === 'email' || connector._wallet.id === 'email-waas') { - return null - } - return })} @@ -327,173 +293,3 @@ export const ConnectWalletContent = (props: ConnectWalletContentProps) => { ) } - -const BUTTON_SIZE = '14' -const ICON_SIZE = '10' - -interface ConnectButtonProps { - connector: ExtendedConnector - label?: string - onConnect: (connector: ExtendedConnector) => void -} - -const ConnectButton = (props: ConnectButtonProps) => { - const { connector, label, onConnect } = props - const { theme } = useTheme() - const walletProps = connector._wallet - - const Logo = getLogo(theme, walletProps) - - return ( - - onConnect(connector)} - > - - - - ) -} - -const GoogleWaasConnectButton = (props: ConnectButtonProps) => { - const { connector, onConnect } = props - const storage = useStorage() - const { data: sessionHash, isPending: isPendingNonce } = useStorageItem(LocalStorageKey.WaasSessionHash) - const [enableGoogleTooltip, setEnableGoogleTooltip] = useState(false) - const { theme } = useTheme() - const walletProps = connector._wallet - - const Logo = getLogo(theme, walletProps) - - useEffect(() => { - setTimeout(() => { - setEnableGoogleTooltip(true) - }, 300) - }) - - return !isPendingNonce ? ( - - - - { - if (credentialResponse.credential) { - storage?.setItem(LocalStorageKey.WaasGoogleIdToken, credentialResponse.credential) - onConnect(connector) - } - }} - onError={() => { - console.log('Login Failed') - }} - /> - - - - - - - ) : null -} - -export const AppleWaasConnectButton = (props: ConnectButtonProps) => { - const { connector, onConnect } = props - const storage = useStorage() - const { data: sessionHash, isPending: isPendingNonce } = useStorageItem(LocalStorageKey.WaasSessionHash) - const { data: appleClientId } = useStorageItem(LocalStorageKey.WaasAppleClientID) - const { data: appleRedirectUri } = useStorageItem(LocalStorageKey.WaasAppleRedirectURI) - - return !isPendingNonce && appleClientId && appleRedirectUri ? ( - { - appleAuthHelpers.signIn({ - authOptions: { - clientId: appleClientId, - redirectURI: appleRedirectUri, - nonce: sessionHash, - scope: 'openid email', - usePopup: true - }, - onSuccess: (response: any) => { - if (response.authorization?.id_token) { - storage?.setItem(LocalStorageKey.WaasAppleIdToken, response.authorization.id_token) - onConnect(connector) - } else { - console.log('Apple login error: No id_token found') - } - }, - onError: (error: any) => console.error(error) - }) - }} - /> - ) : null -} - -interface EmailConnectButtonProps { - onClick: () => void -} - -export const EmailConnectButton = (props: EmailConnectButtonProps) => { - const { onClick } = props - - return ( - - - - - - ) -} - -const getLogo = (theme: any, walletProps: WalletProperties) => - theme === 'dark' - ? walletProps.logoDark || walletProps.monochromeLogoDark - : walletProps.logoLight || walletProps.monochromeLogoLight diff --git a/packages/kit/src/hooks/useWaasEmailAuth.ts b/packages/kit/src/hooks/useWaasEmailAuth.ts index a7da7ba4..97248f68 100644 --- a/packages/kit/src/hooks/useWaasEmailAuth.ts +++ b/packages/kit/src/hooks/useWaasEmailAuth.ts @@ -1,3 +1,4 @@ +import { SequenceWaaS } from '@0xsequence/waas' import { useState } from 'react' import { ExtendedConnector } from '../types' @@ -18,12 +19,27 @@ export function useEmailAuth({ connector, onSuccess }: { connector?: ExtendedCon const [loading, setLoading] = useState(false) const [instance, setInstance] = useState('') + const getSequenceWaas = () => { + if (!connector) { + throw new Error('Connector is not defined') + } + + const sequenceWaas: SequenceWaaS | undefined = (connector as any).sequenceWaas + + if (!sequenceWaas) { + throw new Error('Connector does not support SequenceWaaS') + } + + return sequenceWaas + } + const initiateAuth = async (email: string) => { + const waas = getSequenceWaas() + setLoading(true) try { - const connectorAny: any = connector - const { instance } = await connectorAny.sequenceWaas?.email.initiateAuth({ email }) + const { instance } = await waas.email.initiateAuth({ email }) setInstance(instance) setEmail(email) } catch (e: any) { @@ -34,12 +50,13 @@ export function useEmailAuth({ connector, onSuccess }: { connector?: ExtendedCon } const sendChallengeAnswer = async (answer: string) => { + const waas = getSequenceWaas() + setLoading(true) try { - const connectorAny: any = connector - const sessionHash = await connectorAny.sequenceWaas?.getSessionHash() - const { idToken } = await connectorAny.sequenceWaas?.email.finalizeAuth({ instance, answer, email, sessionHash }) + const sessionHash = await waas.getSessionHash() + const { idToken } = await waas.email.finalizeAuth({ instance, answer, email, sessionHash }) onSuccess(idToken) } catch (e: any) { setError(e.message || 'Unknown error') diff --git a/packages/wallet/CHANGELOG.md b/packages/wallet/CHANGELOG.md index 701eb2e0..bc222546 100644 --- a/packages/wallet/CHANGELOG.md +++ b/packages/wallet/CHANGELOG.md @@ -1,5 +1,14 @@ # @0xsequence/kit-wallet +## 2.10.1 + +### Patch Changes + +- Fixing email auth + +- Updated dependencies []: + - @0xsequence/kit@2.10.1 + ## 2.10.0 ### Minor Changes diff --git a/packages/wallet/package.json b/packages/wallet/package.json index 8818c593..7d81133d 100644 --- a/packages/wallet/package.json +++ b/packages/wallet/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/kit-wallet", - "version": "2.10.0", + "version": "2.10.1", "description": "Wallet UI for Sequence Kit", "repository": "https://github.com/0xsequence/kit/tree/master/packages/wallet", "author": "Horizon Blockchain Games",