diff --git a/packages/keychain/src/components/purchasenew/checkout/onchain/index.tsx b/packages/keychain/src/components/purchasenew/checkout/onchain/index.tsx index 95afb53d87..2e612619a5 100644 --- a/packages/keychain/src/components/purchasenew/checkout/onchain/index.tsx +++ b/packages/keychain/src/components/purchasenew/checkout/onchain/index.tsx @@ -9,6 +9,7 @@ import { LayoutFooter, } from "@cartridge/ui"; import { useMeQuery } from "@cartridge/ui/utils/api/cartridge"; +import { useAccountPrivateQuery } from "@/utils/api"; import { useNavigation, useStarterpackContext, @@ -69,6 +70,9 @@ export function OnchainCheckout() { const { onCreditCardPurchase, isStripeLoading } = useCreditPurchaseContext(); const { refetch: refetchMe } = useMeQuery(undefined, { enabled: false }); + const { refetch: refetchAccountPrivate } = useAccountPrivateQuery(undefined, { + enabled: false, + }); const { enableFeature } = useFeatures(); const [isLoading, setIsLoading] = useState(false); @@ -222,10 +226,14 @@ export function OnchainCheckout() { await onCreditCardPurchase(); navigate("/purchase/checkout/stripe"); } else if (isApplePaySelected) { - const { data } = await refetchMe(); - const me = data?.me; + const [{ data: meData }, { data: accountPrivateData }] = + await Promise.all([refetchMe(), refetchAccountPrivate()]); + const me = meData?.me; + const accountPrivate = accountPrivateData?.accountPrivate; const needsVerification = - !me?.email || !me?.phoneNumber || !me?.phoneNumberVerifiedAt; + !me?.email || + !accountPrivate?.phoneNumber || + !accountPrivate?.phoneNumberVerifiedAt; if (needsVerification) { navigate("/purchase/verification?method=apple-pay", { @@ -253,6 +261,7 @@ export function OnchainCheckout() { isApplePaySelected, onCreditCardPurchase, refetchMe, + refetchAccountPrivate, onCreateCoinbaseOrder, onOnchainPurchase, navigate, diff --git a/packages/keychain/src/components/purchasenew/verification/index.tsx b/packages/keychain/src/components/purchasenew/verification/index.tsx index b2c3c1feaa..128aa97265 100644 --- a/packages/keychain/src/components/purchasenew/verification/index.tsx +++ b/packages/keychain/src/components/purchasenew/verification/index.tsx @@ -7,6 +7,7 @@ import { useSendPhoneVerificationMutation, useVerifyPhoneMutation, } from "@cartridge/ui/utils/api/cartridge"; +import { useAccountPrivateQuery } from "@/utils/api"; import { Button, Input, @@ -180,6 +181,11 @@ export function Verification() { isLoading: isMeLoading, refetch: refetchMe, } = useMeQuery(); + const { + data: accountPrivateData, + isLoading: isAccountPrivateLoading, + refetch: refetchAccountPrivate, + } = useAccountPrivateQuery(); const [step, setStep] = useState(null); const [email, setEmail] = useState(""); @@ -196,17 +202,22 @@ export function Verification() { const verifyPhoneMutation = useVerifyPhoneMutation(); useEffect(() => { - if (meData?.me && step === null) { + if (meData?.me && accountPrivateData && step === null) { + const accountPrivate = accountPrivateData.accountPrivate; + if (!meData.me.email) { setStep("EMAIL_INPUT"); - } else if (!meData.me.phoneNumber || !meData.me.phoneNumberVerifiedAt) { + } else if ( + !accountPrivate?.phoneNumber || + !accountPrivate?.phoneNumberVerifiedAt + ) { setStep("PHONE_INPUT"); - setPhone(meData.me.phoneNumber || ""); + setPhone(accountPrivate?.phoneNumber || ""); } else { setStep("SUCCESS"); } } - }, [meData, step]); + }, [meData, accountPrivateData, step]); useEffect(() => { if (resendCooldown > 0) { @@ -221,8 +232,8 @@ export function Verification() { useEffect(() => { const isVerified = meData?.me?.email && - meData?.me?.phoneNumber && - meData?.me?.phoneNumberVerifiedAt; + accountPrivateData?.accountPrivate?.phoneNumber && + accountPrivateData?.accountPrivate?.phoneNumberVerifiedAt; if (step === "SUCCESS" && method && isVerified && !isTransientSuccess) { const timer = setTimeout(() => { @@ -236,7 +247,7 @@ export function Verification() { }, 1500); return () => clearTimeout(timer); } - }, [step, method, navigate, meData, isTransientSuccess]); + }, [step, method, navigate, meData, accountPrivateData, isTransientSuccess]); const handleSendEmail = async () => { setError(null); @@ -271,14 +282,19 @@ export function Verification() { setIsTransientSuccess(true); setStep("SUCCESS"); setTimeout(async () => { - const { data: updatedMe } = await refetchMe(); + const [, { data: updatedAccountPrivate }] = await Promise.all([ + refetchMe(), + refetchAccountPrivate(), + ]); + if ( - !updatedMe?.me?.phoneNumber || - !updatedMe?.me?.phoneNumberVerifiedAt + !updatedAccountPrivate?.accountPrivate?.phoneNumber || + !updatedAccountPrivate?.accountPrivate?.phoneNumberVerifiedAt ) { setStep("PHONE_INPUT"); - setPhone(updatedMe?.me?.phoneNumber || ""); + setPhone(updatedAccountPrivate?.accountPrivate?.phoneNumber || ""); } + setIsTransientSuccess(false); }, 1500); } else { @@ -335,7 +351,7 @@ export function Verification() { input: { phoneNumber: formattedPhone, code }, }); if (res.verifyPhone.success) { - await refetchMe(); + await Promise.all([refetchMe(), refetchAccountPrivate()]); setStep("SUCCESS"); } else { setError(res.verifyPhone.message); @@ -357,7 +373,7 @@ export function Verification() { } }; - if (isMeLoading && step === null) { + if ((isMeLoading || isAccountPrivateLoading) && step === null) { return (
@@ -462,7 +478,8 @@ export function Verification() {

Success!

- {email || meData?.me?.phoneNumber} Connected + {email || accountPrivateData?.accountPrivate?.phoneNumber}{" "} + Connected

diff --git a/packages/keychain/src/utils/api/account.graphql b/packages/keychain/src/utils/api/account.graphql index f74f60516e..021fee07be 100644 --- a/packages/keychain/src/utils/api/account.graphql +++ b/packages/keychain/src/utils/api/account.graphql @@ -69,6 +69,17 @@ query AddressByUsername($username: String!) { } } +query AccountPrivate { + accountPrivate { + phoneNumber + phoneNumberVerifiedAt + firstName + lastName + proveVerifiedAt + verificationStatus + } +} + query AccountSearch($query: String!, $limit: Int = 5) { searchAccounts(query: $query, limit: $limit) { username diff --git a/packages/keychain/src/utils/api/generated.ts b/packages/keychain/src/utils/api/generated.ts index 6cb789e746..c6f3e30757 100644 --- a/packages/keychain/src/utils/api/generated.ts +++ b/packages/keychain/src/utils/api/generated.ts @@ -46,8 +46,6 @@ export type Account = Node & { membership: AccountTeamConnection; name?: Maybe; oauthConnections?: Maybe>; - phoneNumber?: Maybe; - phoneNumberVerifiedAt?: Maybe; /** If true, the account is billed for paid slot deployments */ slotBilling: Scalars["Boolean"]; starterpackMint: StarterpackMintConnection; @@ -141,6 +139,16 @@ export enum AccountOrderField { CreatedAt = "CREATED_AT", } +export type AccountPrivate = { + __typename?: "AccountPrivate"; + firstName?: Maybe; + lastName?: Maybe; + phoneNumber?: Maybe; + phoneNumberVerifiedAt?: Maybe; + proveVerifiedAt?: Maybe; + verificationStatus?: Maybe; +}; + export type AccountTeam = Node & { __typename?: "AccountTeam"; account: Account; @@ -4443,6 +4451,7 @@ export enum PurchaseFulfillmentStatus { export type Query = { __typename?: "Query"; account?: Maybe; + accountPrivate?: Maybe; accounts?: Maybe; achievements: AchievementResult; activities: ActivityResult; @@ -7156,6 +7165,21 @@ export type AddressByUsernameQuery = { } | null; }; +export type AccountPrivateQueryVariables = Exact<{ [key: string]: never }>; + +export type AccountPrivateQuery = { + __typename?: "Query"; + accountPrivate?: { + __typename?: "AccountPrivate"; + phoneNumber?: string | null; + phoneNumberVerifiedAt?: string | null; + firstName?: string | null; + lastName?: string | null; + proveVerifiedAt?: string | null; + verificationStatus?: string | null; + } | null; +}; + export type AccountSearchQueryVariables = Exact<{ query: Scalars["String"]; limit?: InputMaybe; @@ -7793,6 +7817,34 @@ export const useAddressByUsernameQuery = < ).bind(null, variables), options, ); +export const AccountPrivateDocument = ` + query AccountPrivate { + accountPrivate { + phoneNumber + phoneNumberVerifiedAt + firstName + lastName + proveVerifiedAt + verificationStatus + } +} + `; +export const useAccountPrivateQuery = < + TData = AccountPrivateQuery, + TError = unknown, +>( + variables?: AccountPrivateQueryVariables, + options?: UseQueryOptions, +) => + useQuery( + variables === undefined + ? ["AccountPrivate"] + : ["AccountPrivate", variables], + useFetchData( + AccountPrivateDocument, + ).bind(null, variables), + options, + ); export const AccountSearchDocument = ` query AccountSearch($query: String!, $limit: Int = 5) { searchAccounts(query: $query, limit: $limit) {