Skip to content

[SDK] feat: support object auth option with default value #7292

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions packages/thirdweb/src/react/native/ui/connect/ConnectModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,7 @@ function WalletLoadingView({
authProvider?: InAppWalletAuth;
}) {
const walletInfo = useWalletInfo(wallet.id);
const authProviderName = typeof authProvider === 'string' ? authProvider : authProvider?.type;
return (
<View
style={{
Expand All @@ -491,7 +492,7 @@ function WalletLoadingView({
animate={true}
roundLoader={authProvider === "passkey"}
>
{authProvider ? (
{authProviderName ? (
<View
style={{
borderRadius: spacing.md,
Expand All @@ -501,7 +502,7 @@ function WalletLoadingView({
<RNImage
theme={theme}
size={80}
data={getAuthProviderImage(authProvider)}
data={getAuthProviderImage(authProviderName)}
color={theme.colors.accentButtonBg}
/>
</View>
Expand All @@ -516,14 +517,14 @@ function WalletLoadingView({
</WalletLoadingThumbnail>
<Spacer size="xl" />
<ThemedText theme={theme} type="subtitle">
{authProvider
? `Connecting with ${capitalizeFirstLetter(authProvider)}`
{authProviderName
? `Connecting with ${capitalizeFirstLetter(authProviderName)}`
: "Awaiting confirmation"}
</ThemedText>
<Spacer size="sm" />
<ThemedText theme={theme} type="subtext">
{authProvider
? `Signing into your ${capitalizeFirstLetter(authProvider)} account`
{authProviderName
? `Signing into your ${capitalizeFirstLetter(authProviderName)} account`
: `Accept the connection request in ${walletInfo.data?.name}`}
</ThemedText>
</View>
Expand Down
28 changes: 20 additions & 8 deletions packages/thirdweb/src/react/native/ui/connect/InAppWalletUI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import type {
PreAuthArgsType,
} from "../../../../wallets/in-app/core/authentication/types.js";
import type {
AuthOption,
InAppWalletAuth,
InAppWalletSocialAuth,
AuthOptionWithOptions,
} from "../../../../wallets/in-app/core/wallet/types.js";
import { preAuthenticate } from "../../../../wallets/in-app/native/auth/index.js";
import { hasStoredPasskey } from "../../../../wallets/in-app/native/auth/passkeys.js";
Expand Down Expand Up @@ -91,16 +93,25 @@ export function InAppWalletUI(props: InAppWalletFormUIProps) {

const [inputMode, setInputMode] = useState<"email" | "phone">("email");

const hasAuthOption = useCallback((key: AuthOption) => {
return authOptions.find((opt) => typeof opt === 'string' ? opt === key : opt.type === key);
}, [authOptions]);

const getAuthOptionDefaultValue = useCallback((key: AuthOption) => {
const option = authOptions.find((opt) => typeof opt === 'object' && opt.type === key) as AuthOptionWithOptions | undefined;
return option?.defaultValue;
}, [authOptions]);

return (
<View style={styles.container}>
<View style={styles.row}>
{socialLogins.map((auth) => (
<SocialLogin key={auth} auth={auth} {...props} />
))}
</View>
{authOptions.includes("email") ? (
{hasAuthOption("email") ? (
inputMode === "email" ? (
<PreOtpLogin auth="email" {...props} />
<PreOtpLogin auth="email" defaultValue={getAuthOptionDefaultValue('email')} {...props} />
) : (
<ThemedButtonWithIcon
theme={theme}
Expand All @@ -110,9 +121,9 @@ export function InAppWalletUI(props: InAppWalletFormUIProps) {
/>
)
) : null}
{authOptions.includes("phone") ? (
{hasAuthOption("phone") ? (
inputMode === "phone" ? (
<PreOtpLogin auth="phone" {...props} />
<PreOtpLogin auth="phone" defaultValue={getAuthOptionDefaultValue('phone')} {...props} />
) : (
<ThemedButtonWithIcon
theme={theme}
Expand All @@ -122,7 +133,7 @@ export function InAppWalletUI(props: InAppWalletFormUIProps) {
/>
)
) : null}
{authOptions.includes("passkey") ? (
{hasAuthOption("passkey") ? (
<ThemedButtonWithIcon
theme={theme}
title="Passkey"
Expand All @@ -132,7 +143,7 @@ export function InAppWalletUI(props: InAppWalletFormUIProps) {
}}
/>
) : null}
{authOptions.includes("guest") ? <GuestLogin {...props} /> : null}
{hasAuthOption("guest") ? <GuestLogin {...props} /> : null}
</View>
);
}
Expand Down Expand Up @@ -205,10 +216,11 @@ function SocialLogin(
function PreOtpLogin(
props: InAppWalletFormUIProps & {
auth: PreAuthArgsType["strategy"];
defaultValue?: string;
},
) {
const { theme, auth, client, setScreen, wallet } = props;
const [phoneOrEmail, setPhoneNumberOrEmail] = useState("");
const { theme, auth, client, setScreen, wallet, defaultValue = ''} = props;
const [phoneOrEmail, setPhoneNumberOrEmail] = useState(defaultValue);

const sendCode = useMutation({
mutationFn: async (options: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export function InputSelectionUI(props: {
disabled?: boolean;
defaultSmsCountryCode?: SupportedSmsCountry;
allowedSmsCountryCodes?: SupportedSmsCountry[];
defaultValue?: string;
}) {
const [countryCodeInfo, setCountryCodeInfo] = useState(
props.defaultSmsCountryCode
Expand All @@ -35,7 +36,7 @@ export function InputSelectionUI(props: {
? getCountrySelector(props.allowedSmsCountryCodes[0])
: "US +1",
);
const [input, setInput] = useState("");
const [input, setInput] = useState(props.defaultValue || "");
const [error, setError] = useState<string | undefined>();
const [showError, setShowError] = useState(false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,9 @@ export const ConnectWalletSocialOptions = (
? (ecosystemAuthOptions ?? defaultAuthOptions)
: (wallet.getConfig()?.auth?.options ?? defaultAuthOptions);

const emailIndex = authOptions.indexOf("email");
const emailIndex = authOptions.findIndex((o) => typeof o === 'string' ? o === 'email' : o.type === 'email');
const isEmailEnabled = emailIndex !== -1;
const phoneIndex = authOptions.indexOf("phone");
const phoneIndex = authOptions.findIndex((o) => typeof o === "string" ? o === "phone" : o.type === "phone");
const isPhoneEnabled = phoneIndex !== -1;
const socialLogins: SocialAuthOption[] = authOptions.filter((o) =>
socialAuthOptions.includes(o as SocialAuthOption),
Expand Down Expand Up @@ -410,6 +410,7 @@ export const ConnectWalletSocialOptions = (
disabled={props.disabled}
emptyErrorMessage={emptyErrorMessage}
submitButtonText={locale.submitEmail}
defaultValue={typeof authOptions[emailIndex] === 'object' ? authOptions[emailIndex].defaultValue : undefined}
/>
) : (
<WalletTypeRowButton
Expand Down Expand Up @@ -454,6 +455,7 @@ export const ConnectWalletSocialOptions = (
allowedSmsCountryCodes={
wallet.getConfig()?.auth?.allowedSmsCountryCodes
}
defaultValue={typeof authOptions[phoneIndex] === 'object' ? authOptions[phoneIndex].defaultValue : undefined}
/>
) : (
<WalletTypeRowButton
Expand Down
4 changes: 3 additions & 1 deletion packages/thirdweb/src/wallets/in-app/core/wallet/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ export type WalletUser = UserStatus;

export type InAppWalletSocialAuth = SocialAuthOption;
export type InAppWalletOAuth = OAuthOption;
export type InAppWalletAuth = AuthOption;
export type AuthOptionWithOptions = {type: 'email' | 'phone', defaultValue: string };
export type InAppWalletAuth = AuthOption | AuthOptionWithOptions;
export type { AuthOption };

export type ExecutionModeOptions =
| {
Expand Down
16 changes: 16 additions & 0 deletions packages/thirdweb/src/wallets/in-app/web/in-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,22 @@ import type { InAppWalletCreationOptions } from "../core/wallet/types.js";
* });
* ```
*
* ### Set the default value for the email and phone auth options
*
* By default,the email and phone auth options will be empty. You can change this behavior by passing the auth option for phone or email as an object with the `defaultValue` property.
*
* ```ts
* import { inAppWallet } from "thirdweb/wallets";
* const wallet = inAppWallet({
* auth: {
* options: [
* { type: "email", defaultValue: "[email protected]" },
* { type: "phone", defaultValue: "+5555555555" },
* ]
* }
* });
* ```
*
* @returns The created in-app wallet.
* @wallet
*/
Expand Down