diff --git a/backend/native/backpack-api/src/db/users.ts b/backend/native/backpack-api/src/db/users.ts index c1a1755b7..a8cdd4497 100644 --- a/backend/native/backpack-api/src/db/users.ts +++ b/backend/native/backpack-api/src/db/users.ts @@ -302,6 +302,8 @@ const transformUser = ( */ export const createUser = async ( username: string, + firstName: string, + lastName: string, blockchainPublicKeys: Array<{ blockchain: Blockchain; publicKey: string }>, waitlistId?: string | null, referrerId?: string @@ -329,6 +331,8 @@ export const createUser = async ( { object: { username: username, + firstName: firstName, + lastName: lastName, public_keys: { data: blockchainPublicKeys.map((b) => ({ blockchain: b.blockchain, diff --git a/backend/native/backpack-api/src/routes/v1/users.ts b/backend/native/backpack-api/src/routes/v1/users.ts index 9e2db77dd..a5cc7edf9 100644 --- a/backend/native/backpack-api/src/routes/v1/users.ts +++ b/backend/native/backpack-api/src/routes/v1/users.ts @@ -124,9 +124,12 @@ router.get("/jwt/xnft", extractUserId, async (req, res) => { * Create a new user. */ router.post("/", async (req, res) => { - const { username, waitlistId, blockchainPublicKeys } = + const { username, waitlistId, blockchainPublicKeys, firstName, lastName } = CreateUserWithPublicKeys.parse(req.body); + console.log(firstName); + console.log(lastName); + // Validate all the signatures for (const blockchainPublicKey of blockchainPublicKeys) { const signedMessage = getCreateMessage(blockchainPublicKey.publicKey); @@ -182,6 +185,8 @@ router.post("/", async (req, res) => { const user = await createUser( username, + firstName, + lastName, blockchainPublicKeys.map((b) => ({ ...b, // Cast blockchain to correct type diff --git a/backend/native/backpack-api/src/validation/user.ts b/backend/native/backpack-api/src/validation/user.ts index 82e4319ab..851dde6a4 100644 --- a/backend/native/backpack-api/src/validation/user.ts +++ b/backend/native/backpack-api/src/validation/user.ts @@ -9,6 +9,18 @@ export const BaseCreateUser = z.object({ /^[a-z0-9_]{3,15}$/, "should be between 3-15 characters and can only contain numbers, letters, and underscores." ), + firstName: z + .string() + .regex( + /^[a-z0-9_]{3,15}$/, + "should be between 3-15 characters and can only contain numbers, letters, and underscores." + ), + lastName: z + .string() + .regex( + /^[a-z0-9_]{3,15}$/, + "should be between 3-15 characters and can only contain numbers, letters, and underscores." + ), inviteCode: z .string() .regex( diff --git a/backend/native/zeus/package.json b/backend/native/zeus/package.json index 31fd1a7e5..9777a0ef2 100644 --- a/backend/native/zeus/package.json +++ b/backend/native/zeus/package.json @@ -14,6 +14,7 @@ "author": "", "license": "ISC", "dependencies": { + "graphql": "^16.8.1", "tsc-alias": "^1.7.1", "typescript": "~4.9.3" }, diff --git a/packages/app-extension/src/components/Onboarding/pages/OnboardAccount.tsx b/packages/app-extension/src/components/Onboarding/pages/OnboardAccount.tsx index b1564812f..e22903683 100644 --- a/packages/app-extension/src/components/Onboarding/pages/OnboardAccount.tsx +++ b/packages/app-extension/src/components/Onboarding/pages/OnboardAccount.tsx @@ -77,8 +77,8 @@ export const OnboardAccount = ({ { - setOnboardingData({ username }); + onNext={(username, firstName, lastName) => { + setOnboardingData({ username, firstName, lastName }); nextStep(); }} />, @@ -161,79 +161,80 @@ export const OnboardAccount = ({ } return ( - 0 && step !== steps.length - 1 ? ( - - ) : undefined - } - {...navProps} - // Only display the onboarding menu on the first step - navButtonRight={step === 0 ? navProps.navButtonRight : undefined} - > - {steps[step]} + // 0 && step !== steps.length - 1 ? ( + // + // ) : undefined + // } + // {...navProps} + // // Only display the onboarding menu on the first step + // navButtonRight={step === 0 ? navProps.navButtonRight : undefined} + // > + // {steps[step]} - - {keyringType === "ledger" ? ( - getCreateMessage(publicKey)} - signText="Sign the message to authenticate with Backpack." - onClose={() => setOpenDrawer(false)} - onComplete={(signedWalletDescriptor: SignedWalletDescriptor) => { - setOnboardingData({ - signedWalletDescriptors: [ - ...signedWalletDescriptors, - signedWalletDescriptor, - ], - }); - setOpenDrawer(false); - }} - /> - ) : ( - ) => { - // Should only be one public key path - const walletDescriptor = walletDescriptors[0]; - const signature = await signMessageForWallet( - walletDescriptor.blockchain, - walletDescriptor.publicKey, - getCreateMessage(walletDescriptor.publicKey), - { - mnemonic: mnemonic!, - signedWalletDescriptors: [ - { ...walletDescriptor, signature: "" }, - ], - } - ); - setOnboardingData({ - signedWalletDescriptors: [ - ...signedWalletDescriptors, - { - ...walletDescriptor, - signature, - }, - ], - }); - setOpenDrawer(false); - }} - /> - )} - - + // + // {keyringType === "ledger" ? ( + // getCreateMessage(publicKey)} + // signText="Sign the message to authenticate with Backpack." + // onClose={() => setOpenDrawer(false)} + // onComplete={(signedWalletDescriptor: SignedWalletDescriptor) => { + // setOnboardingData({ + // signedWalletDescriptors: [ + // ...signedWalletDescriptors, + // signedWalletDescriptor, + // ], + // }); + // setOpenDrawer(false); + // }} + // /> + // ) : ( + // ) => { + // // Should only be one public key path + // const walletDescriptor = walletDescriptors[0]; + // const signature = await signMessageForWallet( + // walletDescriptor.blockchain, + // walletDescriptor.publicKey, + // getCreateMessage(walletDescriptor.publicKey), + // { + // mnemonic: mnemonic!, + // signedWalletDescriptors: [ + // { ...walletDescriptor, signature: "" }, + // ], + // } + // ); + // setOnboardingData({ + // signedWalletDescriptors: [ + // ...signedWalletDescriptors, + // { + // ...walletDescriptor, + // signature, + // }, + // ], + // }); + // setOpenDrawer(false); + // }} + // /> + // )} + // + // +
{steps[step]}
); }; diff --git a/packages/app-extension/src/components/Onboarding/pages/UsernameForm.tsx b/packages/app-extension/src/components/Onboarding/pages/UsernameForm.tsx index 627494a16..e026c1a80 100644 --- a/packages/app-extension/src/components/Onboarding/pages/UsernameForm.tsx +++ b/packages/app-extension/src/components/Onboarding/pages/UsernameForm.tsx @@ -1,5 +1,5 @@ import { type FormEvent, useCallback, useEffect, useState } from "react"; -import { PrimaryButton,TextInput } from "@coral-xyz/react-common"; +import { PrimaryButton, TextInput } from "@coral-xyz/react-common"; import { useCustomTheme } from "@coral-xyz/themes"; import { AlternateEmail } from "@mui/icons-material"; import { Box, InputAdornment } from "@mui/material"; @@ -11,9 +11,11 @@ export const UsernameForm = ({ onNext, }: { inviteCode: string; - onNext: (username: string) => void; + onNext: (username: string, firstName: string, lastName: string) => void; }) => { const [username, setUsername] = useState(""); + const [firstName, setFirstName] = useState(""); + const [lastName, setLastName] = useState(""); const [error, setError] = useState(""); const theme = useCustomTheme(); @@ -31,15 +33,19 @@ export const UsernameForm = ({ "x-backpack-invite-code": String(inviteCode), }, }); + console.log("response here", res); const json = await res.json(); + console.log("json here", json); if (!res.ok) throw new Error(json.message || "There was an error"); - onNext(username); + onNext(username, firstName, lastName); } catch (err: any) { + console.log(err); + setError(err.message); } }, - [username] + [username, firstName, lastName] // this change made the lastname and firstname appear in payload of request in network tab ); return ( @@ -104,6 +110,70 @@ export const UsernameForm = ({ } /> + + {/* name */} + { + setFirstName( + e.target.value.toLowerCase().replace(/[^a-z0-9_]/g, "") + ); + }} + error={error ? true : false} + errorMessage={error} + startAdornment={ + + + + } + /> + + {/* last name */} + { + setLastName( + e.target.value.toLowerCase().replace(/[^a-z0-9_]/g, "") + ); + }} + error={error ? true : false} + errorMessage={error} + startAdornment={ + + + + } + /> diff --git a/packages/common/src/constants.ts b/packages/common/src/constants.ts index ca9e6fc80..6482a0764 100644 --- a/packages/common/src/constants.ts +++ b/packages/common/src/constants.ts @@ -579,7 +579,8 @@ export const ALCHEMY_ETHEREUM_MAINNET_API_KEY = "DlJr6QuBC2EaE-L60-iqQQGq9hi9-XSZ"; export const AVATAR_BASE_URL = "https://swr.xnfts.dev/avatars"; -export const BACKEND_API_URL = "https://backpack-api.xnfts.dev"; +// export const BACKEND_API_URL = "https://backpack-api.xnfts.dev"; +export const BACKEND_API_URL = "http://localhost:8080"; export const REALTIME_API_URL = "https://backend-ws.xnfts.dev"; export const MESSAGING_COMMUNICATION_PUSH = "MESSAGING_COMMUNICATION_PUSH"; export const MESSAGING_COMMUNICATION_FETCH = "MESSAGING_COMMUNICATION_FETCH"; diff --git a/packages/recoil/src/context/OnboardingProvider.tsx b/packages/recoil/src/context/OnboardingProvider.tsx index e9499b6a8..05aa3b287 100644 --- a/packages/recoil/src/context/OnboardingProvider.tsx +++ b/packages/recoil/src/context/OnboardingProvider.tsx @@ -81,6 +81,8 @@ export type OnboardingData = { complete: boolean; inviteCode: string | undefined; username: string | null; + firstName: string | null; + lastName: string | null; action: string; keyringType: KeyringType | null; blockchain: Blockchain | null; @@ -102,6 +104,8 @@ const defaultState = { complete: false, inviteCode: undefined, username: null, + firstName: null, + lastName: null, action: "create", keyringType: null, blockchain: null, @@ -278,7 +282,8 @@ export function OnboardingProvider({ // const createUser = useCallback( async (data: Partial) => { - const { inviteCode, userId, username, keyringType } = data; + const { inviteCode, userId, username, firstName, lastName, keyringType } = + data; // If userId is provided, then we are onboarding via the recover flow. if (userId) { @@ -312,6 +317,8 @@ export function OnboardingProvider({ // const body = JSON.stringify({ username, + firstName, + lastName, inviteCode, waitlistId: getWaitlistId?.(), blockchainPublicKeys,