Skip to content

Commit

Permalink
fix: Add social login option to onboard module
Browse files Browse the repository at this point in the history
  • Loading branch information
usame-algan committed Nov 6, 2023
1 parent 146dc8e commit 0b51955
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 31 deletions.
24 changes: 0 additions & 24 deletions src/hooks/wallets/mpc/useSocialWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,6 @@ import useMpc from './useMPC'

const { getStore, setStore, useStore } = new ExternalStore<ISocialWalletService>()

// Listen to onboard modal open and hide the social login button
const hideOnboardButton = () => {
const onboardRoot = document.querySelector('onboard-v2')?.shadowRoot
if (!onboardRoot) return

const hideSocialLoginButton = () => {
const walletButtons = onboardRoot.querySelectorAll('.wallet-button-container') || []
const socialButton = Array.from(walletButtons).find((el) => el.textContent?.includes(ONBOARD_MPC_MODULE_LABEL))
socialButton?.remove()
}

const observer = new MutationObserver(hideSocialLoginButton)
observer.observe(onboardRoot, { childList: true })

return () => observer.disconnect()
}

export const useInitSocialWallet = () => {
const mpcCoreKit = useMpc()
const onboard = useOnboard()
Expand Down Expand Up @@ -71,13 +54,6 @@ export const useInitSocialWallet = () => {
setStore(new SocialWalletService(mpcCoreKit))
}
}, [mpcCoreKit])

// Hide social login when onboard pops up
// @FIXME the button should work but atm it doesn't
useEffect(() => {
if (!onboard) return
return hideOnboardButton()
}, [onboard])
}

export const getSocialWalletService = getStore
Expand Down
3 changes: 3 additions & 0 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import PasswordRecoveryModal from '@/services/mpc/PasswordRecoveryModal'
import Sentry from '@/services/sentry' // needs to be imported first
import type { ReactNode } from 'react'
import { type ReactElement } from 'react'
Expand Down Expand Up @@ -126,6 +127,8 @@ const WebCoreApp = ({
<Notifications />

<MobilePairingModal />

<PasswordRecoveryModal />
</AppProviders>
</CacheProvider>
</StoreHydrator>
Expand Down
42 changes: 42 additions & 0 deletions src/services/mpc/PasswordRecoveryModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { PasswordRecovery } from '@/components/common/SocialSigner/PasswordRecovery'
import TxModalDialog from '@/components/common/TxModalDialog'
import useSocialWallet from '@/hooks/wallets/mpc/useSocialWallet'
import ExternalStore from '@/services/ExternalStore'

const { useStore: useCloseCallback, setStore: setCloseCallback } = new ExternalStore<() => void>()

export const open = (cb: () => void) => {
setCloseCallback(() => cb)
}

export const close = () => {
setCloseCallback(undefined)
}

const PasswordRecoveryModal = () => {
const socialWalletService = useSocialWallet()
const closeCallback = useCloseCallback()
const open = !!closeCallback

const handleClose = () => {
closeCallback?.()
setCloseCallback(undefined)
close()
}

const recoverPassword = async (password: string, storeDeviceFactor: boolean) => {
if (!socialWalletService) return

await socialWalletService.recoverAccountWithPassword(password, storeDeviceFactor)
}

if (!open) return null

return (
<TxModalDialog open={open} onClose={handleClose} fullWidth sx={{ zIndex: '10000 !important', top: '0 !important' }}>
<PasswordRecovery recoverFactorWithPassword={recoverPassword} onSuccess={handleClose} />
</TxModalDialog>
)
}

export default PasswordRecoveryModal
36 changes: 29 additions & 7 deletions src/services/mpc/SocialLoginModule.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { _getMPCCoreKitInstance } from '@/hooks/wallets/mpc/useMPC'
import { getSocialWalletService } from '@/hooks/wallets/mpc/useSocialWallet'
import { getWeb3ReadOnly } from '@/hooks/wallets/web3'
import * as PasswordRecoveryModal from '@/services/mpc/PasswordRecoveryModal'
import { type WalletInit, ProviderRpcError } from '@web3-onboard/common'
import { type EIP1193Provider } from '@web3-onboard/core'
import { COREKIT_STATUS } from '@web3auth/mpc-core-kit'

const getMPCProvider = () => _getMPCCoreKitInstance()?.provider

Expand Down Expand Up @@ -37,26 +40,44 @@ function MpcModule(): WalletInit {
web3.on(event, listener)
},
request: (request) => {
return new Promise<any>((resolve, reject) => {
return new Promise<any>(async (resolve, reject) => {
try {
const web3 = assertDefined(getMPCProvider())
const web3ReadOnly = assertDefined(getWeb3ReadOnly())
/*
* We have to fallback to web3ReadOnly for eth_estimateGas because the provider by Web3Auth does not expose / implement it.
*/
if ('eth_estimateGas' === request.method) {
const web3ReadOnly = assertDefined(getWeb3ReadOnly())

web3ReadOnly
?.send(request.method, request.params ?? [])
.then(resolve)
.catch(reject)

return
}

/*
* If the provider is defined we already have access to the accounts. So we can just reply with the current account.
*/
if ('eth_requestAccounts' === request.method) {
web3.request({ method: 'eth_accounts' }).then(resolve).catch(reject)
try {
// If the provider is defined we already have access to the accounts.
const web3 = assertDefined(getMPCProvider())
web3.request({ method: 'eth_accounts' }).then(resolve).catch(reject)
} catch (e) {
// Otherwise try to log in the user
const socialWalletService = getSocialWalletService()
if (!socialWalletService) throw Error('Social Login not ready')

const status = await socialWalletService.loginAndCreate()

if (status === COREKIT_STATUS.REQUIRED_SHARE) {
PasswordRecoveryModal.open(() => {
const web3 = assertDefined(getMPCProvider())
web3.request({ method: 'eth_accounts' }).then(resolve).catch(reject)
})
} else {
const web3 = assertDefined(getMPCProvider())
web3.request({ method: 'eth_accounts' }).then(resolve).catch(reject)
}
}
return
}

Expand All @@ -66,6 +87,7 @@ function MpcModule(): WalletInit {
return
}

const web3 = assertDefined(getMPCProvider())
// Default: we call the inner provider
web3.request(request).then(resolve).catch(reject)
return
Expand Down

0 comments on commit 0b51955

Please sign in to comment.