feat: add email-only sign-in option with dynamic wallet ordering#308
feat: add email-only sign-in option with dynamic wallet ordering#308
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…for mobile compatibility
LautaroPetaccio
left a comment
There was a problem hiding this comment.
Great work! 👍 I've left a couple of comments to review
| ? connectionOptions?.extraOptions?.[0] | ||
| : connectionOptions?.secondary | ||
| const filteredExtraOptions = connectionOptions?.extraOptions?.filter(opt => opt !== ConnectionOptionType.EMAIL) | ||
| const { firstWalletOption, secondWalletOption, remainingWalletOptions } = useWalletOptions({ |
There was a problem hiding this comment.
Be aware that the changes in ConnectionSecondaryButton and in Connection do impact the mobile site for Regenesis. Please check with them before merging.
| const isMetamask = option === ConnectionOptionType.METAMASK | ||
| const shouldDisableMetamask = isMetamask && !isMetamaskAvailable |
There was a problem hiding this comment.
This function seems to be the same as the one used in the ConnectionPrimaryButton, what do you think about abstracting it?
| const isOnlyEmailOption = flags[FeatureFlagsKeys.SIGN_IN_PRIMARY_OPTION] | ||
| const isSignInWithTwoOptions = variants[FeatureFlagsKeys.SIGN_IN_PRIMARY_OPTION]?.name === SignInPrimaryOption.TWO_OPTIONS |
There was a problem hiding this comment.
What if we have a signIgnOptions variable that has the values of one or two, for the options instead of two variables that get passed to the component?
There was a problem hiding this comment.
I'mm make a refactor
| ) | ||
|
|
||
| // Current/Old behavior: show all options normally (when isOnlyEmailOption is disabled) | ||
| if (!isOnlyEmailOption) { |
There was a problem hiding this comment.
Is this correct? We're not using this logic in production, we're always showing the Metamask login as the primary action or am I missing something?
* fix: Incorrect handling of callback and magic re-log in * fix: Ignore error * Ignore MISSING_PKCE_METADATA error
…in the wallet (#321) * fix: prevent reporting to Sentry an error when the user rejects a tx in the wallet * fix: user rejected_action report to Sentry * refactor: PR feedback * chore: indent comment
…to extract params (#329) * fix: SSO log-in with Magic by waiting for redirect url before trying to extract params * fix: apply PR feedback --------- Co-authored-by: Lautaro Petaccio <1120791+LautaroPetaccio@users.noreply.github.com>
* feat: Asynchronously load OTP to reduce start time * fix: Linting * fix: Thirdweb fixed version
regenesis-claw
left a comment
There was a problem hiding this comment.
🚨 Breaking change for /auth/mobile route
The new useWalletOptions hook in Connection.tsx replaces the old inline wallet-filtering logic, but it drops the primary field entirely — it only considers secondary and extraOptions. This works for the desktop LoginPage (which always sets primary: EMAIL), but breaks all mobile configs where primary is a non-EMAIL option.
How it breaks
MobileProviderSelection renders <Connection> without passing signInOptionsMode, so the hook defaults to FULL mode:
// FULL mode in useWalletOptions:
firstWalletOption: connectionOptions?.secondary,
secondWalletOption: connectionOptions?.extraOptions?.[0],
remainingWalletOptions: connectionOptions?.extraOptions?.slice(1)The primary field is completely ignored.
Affected mobile configs (targetConfig.ts):
| Config | primary |
Before | After |
|---|---|---|---|
| iOS | APPLE |
APPLE shown as first button | ❌ APPLE gone — shows WALLET_CONNECT instead |
| Android | GOOGLE |
GOOGLE shown as first button | ❌ GOOGLE dropped — shows WALLET_CONNECT instead |
| androidWeb3 | WALLET_CONNECT (no secondary) |
WALLET_CONNECT shown | ❌ Nothing shown (secondary is undefined) |
| androidSocial | EMAIL |
Works | ✅ OK (primary is EMAIL) |
Old logic (worked correctly for mobile):
const filteredPrimary =
connectionOptions?.primary === ConnectionOptionType.EMAIL
? connectionOptions?.secondary
: connectionOptions?.primary // <-- kept non-EMAIL primaryThe old code correctly fell through to use primary when it wasn't EMAIL. The new hook assumes primary is always EMAIL and discards it.
Suggested fix
The useWalletOptions hook needs to handle the case where primary is not EMAIL. In FULL mode (which is what mobile uses), if primary !== EMAIL, it should include primary in the wallet options — matching the old behavior. Alternatively, MobileProviderSelection could pass a dedicated mode or the mobile configs could be restructured.
Minor: getSignInOptionsMode doesn't check variant.enabled
If a variant exists but is disabled (enabled: false), getSignInOptionsMode would still return ONE instead of FULL:
if (!variant) {
return SignInOptionsMode.FULL
}
// No check for variant.enabled hereMinor: Unused type addition
shouldShowGoogleOptionAsPrimary was added to ConnectionProps but doesn't appear to be used anywhere in this PR.
Requested by Gon via Slack
| if (!signInOptionsMode || signInOptionsMode === SignInOptionsMode.FULL) { | ||
| return { | ||
| firstWalletOption: connectionOptions?.secondary, | ||
| secondWalletOption: connectionOptions?.extraOptions?.[0], |
There was a problem hiding this comment.
🚨 Bug — breaks mobile auth: In FULL mode, primary is completely ignored. The old code in Connection.tsx had:
const filteredPrimary = connectionOptions?.primary === ConnectionOptionType.EMAIL
? connectionOptions?.secondary
: connectionOptions?.primary // kept non-EMAIL primary!The mobile configs (ios, android, androidWeb3) set primary to APPLE, GOOGLE, or WALLET_CONNECT respectively. With this new code, those primary login options silently disappear from the UI.
This needs to include primary in the wallet options when primary !== EMAIL.
| function getSignInOptionsMode(variants: Partial<FeatureFlagsVariants>): SignInOptionsMode { | ||
| const variant = variants[FeatureFlagsKeys.SIGN_IN_PRIMARY_OPTION] | ||
|
|
||
| // If variant doesn't exist, use full mode (legacy behavior) |
There was a problem hiding this comment.
Minor: This doesn't check variant.enabled. If a variant exists but has enabled: false, it would still fall through to return ONE instead of FULL.
Suggestion:
if (!variant || !variant.enabled) {
return SignInOptionsMode.FULL
}| type MetamaskEthereumWindow = typeof window.ethereum & { isMetaMask?: boolean } | ||
|
|
||
| type ConnectionProps = { | ||
| shouldShowGoogleOptionAsPrimary?: boolean |
There was a problem hiding this comment.
Minor: shouldShowGoogleOptionAsPrimary is added here but doesn't appear to be used anywhere in this PR. Leftover?
…ons hook and fix 'more options' visibility
This PR implements support for the email-only sign-in feature with dynamic wallet button ordering based on MetaMask
availability and user preferences.
New Features
Email-only sign-in mode (
isOnlyEmailOptionflag):isSignInWithTwoOptions: false): Shows only MetaMask if availableisSignInWithTwoOptions: true): Shows Google + MetaMask if availableDynamic wallet ordering:
useWalletOptionshook centralizes wallet ordering logicuseWalletOptionshook to encapsulate wallet ordering logicBehavior
Default (flag disabled):
Wallet options match current/legacy behavior
Email-only mode with one wallet (
isOnlyEmailOption: true,isSignInWithTwoOptions: false):Email-only mode with two wallets (
isOnlyEmailOption: true,isSignInWithTwoOptions: true):