diff --git a/.husky/pre-commit b/.husky/pre-commit deleted file mode 100755 index 44d21ba..0000000 --- a/.husky/pre-commit +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - -yarn lint-staged --verbose \ No newline at end of file diff --git a/packages/hardhat/hardhat.config.ts b/packages/hardhat/hardhat.config.ts index d165b65..45e74db 100644 --- a/packages/hardhat/hardhat.config.ts +++ b/packages/hardhat/hardhat.config.ts @@ -30,7 +30,7 @@ const config: HardhatUserConfig = { }, }, }, - defaultNetwork: "localhost", + defaultNetwork: "sepolia", namedAccounts: { deployer: { // By default, it will take the first Hardhat account as the deployer diff --git a/packages/nextjs/@/components/ui/avatar.tsx b/packages/nextjs/@/components/ui/avatar.tsx new file mode 100644 index 0000000..9122baa --- /dev/null +++ b/packages/nextjs/@/components/ui/avatar.tsx @@ -0,0 +1,50 @@ +"use client" + +import * as React from "react" +import * as AvatarPrimitive from "@radix-ui/react-avatar" + +import { cn } from "../../lib/utils" + +const Avatar = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +Avatar.displayName = AvatarPrimitive.Root.displayName + +const AvatarImage = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AvatarImage.displayName = AvatarPrimitive.Image.displayName + +const AvatarFallback = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName + +export { Avatar, AvatarImage, AvatarFallback } diff --git a/packages/nextjs/@/components/ui/button.tsx b/packages/nextjs/@/components/ui/button.tsx new file mode 100644 index 0000000..027eb74 --- /dev/null +++ b/packages/nextjs/@/components/ui/button.tsx @@ -0,0 +1,58 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva, type VariantProps } from "class-variance-authority" +import { twMerge } from "tailwind-merge"; +import { type ClassValue, clsx } from "clsx"; + +import { cn } from "../../lib/utils" + +const buttonVariants = cva( + "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: + "bg-destructive text-destructive-foreground hover:bg-destructive/90", + outline: + "border border-input bg-background hover:bg-accent hover:text-accent-foreground", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: "hover:bg-accent hover:text-accent-foreground", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-10 px-4 py-2", + sm: "h-9 rounded-md px-3", + lg: "h-11 rounded-md px-8", + icon: "h-10 w-10", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +) + +export interface ButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean +} + +const Button = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button" + return ( + + ) + } +) +Button.displayName = "Button" + +export { Button, buttonVariants } diff --git a/packages/nextjs/@/components/ui/card.tsx b/packages/nextjs/@/components/ui/card.tsx new file mode 100644 index 0000000..c1b6fbb --- /dev/null +++ b/packages/nextjs/@/components/ui/card.tsx @@ -0,0 +1,79 @@ +import * as React from "react" + +import { cn } from "../../lib/utils" + +const Card = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +Card.displayName = "Card" + +const CardHeader = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardHeader.displayName = "CardHeader" + +const CardTitle = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardTitle.displayName = "CardTitle" + +const CardDescription = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardDescription.displayName = "CardDescription" + +const CardContent = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardContent.displayName = "CardContent" + +const CardFooter = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardFooter.displayName = "CardFooter" + +export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } diff --git a/packages/nextjs/@/components/ui/form.tsx b/packages/nextjs/@/components/ui/form.tsx new file mode 100644 index 0000000..aebe0f9 --- /dev/null +++ b/packages/nextjs/@/components/ui/form.tsx @@ -0,0 +1,178 @@ +"use client" + +import * as React from "react" +import * as LabelPrimitive from "@radix-ui/react-label" +import { Slot } from "@radix-ui/react-slot" +import { + Controller, + ControllerProps, + FieldPath, + FieldValues, + FormProvider, + useFormContext, +} from "react-hook-form" + +import { cn } from "../../lib/utils" +import { Label } from "./label" + +const Form = FormProvider + +type FormFieldContextValue< + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath +> = { + name: TName +} + +const FormFieldContext = React.createContext( + {} as FormFieldContextValue +) + +const FormField = < + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath +>({ + ...props +}: ControllerProps) => { + return ( + + + + ) +} + +const useFormField = () => { + const fieldContext = React.useContext(FormFieldContext) + const itemContext = React.useContext(FormItemContext) + const { getFieldState, formState } = useFormContext() + + const fieldState = getFieldState(fieldContext.name, formState) + + if (!fieldContext) { + throw new Error("useFormField should be used within ") + } + + const { id } = itemContext + + return { + id, + name: fieldContext.name, + formItemId: `${id}-form-item`, + formDescriptionId: `${id}-form-item-description`, + formMessageId: `${id}-form-item-message`, + ...fieldState, + } +} + +type FormItemContextValue = { + id: string +} + +const FormItemContext = React.createContext( + {} as FormItemContextValue +) + +const FormItem = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + const id = React.useId() + + return ( + +
+ + ) +}) +FormItem.displayName = "FormItem" + +const FormLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => { + const { error, formItemId } = useFormField() + + return ( +
+ +

Get started by editing{" "} diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json index eeea141..a088a82 100644 --- a/packages/nextjs/package.json +++ b/packages/nextjs/package.json @@ -15,6 +15,10 @@ }, "dependencies": { "@heroicons/react": "^2.0.11", + "@hookform/resolvers": "^3.9.0", + "@radix-ui/react-avatar": "^1.1.0", + "@radix-ui/react-label": "^2.1.0", + "@radix-ui/react-slot": "^1.1.0", "@rainbow-me/rainbowkit": "2.1.2", "@tanstack/react-query": "^5.28.6", "@uniswap/sdk-core": "^4.0.1", @@ -28,10 +32,12 @@ "next": "^14.0.4", "next-themes": "^0.2.1", "nprogress": "^0.2.0", + "path": "^0.12.7", "qrcode.react": "^3.1.0", "react": "^18.2.0", "react-copy-to-clipboard": "^5.1.0", "react-dom": "^18.2.0", + "react-hook-form": "^7.52.1", "react-hot-toast": "^2.4.0", "tailwind-merge": "^2.4.0", "tailwindcss-animate": "^1.0.7", @@ -39,6 +45,7 @@ "usehooks-ts": "^2.13.0", "viem": "2.13.6", "wagmi": "2.9.8", + "zod": "^3.23.8", "zustand": "^4.1.2" }, "devDependencies": { diff --git a/packages/nextjs/scaffold.config.ts b/packages/nextjs/scaffold.config.ts index 86c737a..b00a22e 100644 --- a/packages/nextjs/scaffold.config.ts +++ b/packages/nextjs/scaffold.config.ts @@ -10,7 +10,7 @@ export type ScaffoldConfig = { const scaffoldConfig = { // The networks on which your DApp is live - targetNetworks: [chains.hardhat], + targetNetworks: [chains.sepolia], // The interval at which your front-end polls the RPC servers for new data // it has no effect if you only target the local network (default is 4000) diff --git a/yarn.lock b/yarn.lock index 572aacd..21dd539 100644 --- a/yarn.lock +++ b/yarn.lock @@ -880,6 +880,15 @@ __metadata: languageName: node linkType: hard +"@hookform/resolvers@npm:^3.9.0": + version: 3.9.0 + resolution: "@hookform/resolvers@npm:3.9.0" + peerDependencies: + react-hook-form: ^7.0.0 + checksum: 64a1e77ea2eeeba521ec624f2cea33ec2d20c60de12847b59520393780a9c8b92b3d76b7b3eeabadef85e8c776826f7bc9016fa90a890580c4ed75503c060dd1 + languageName: node + linkType: hard + "@humanwhocodes/config-array@npm:^0.11.11": version: 0.11.11 resolution: "@humanwhocodes/config-array@npm:0.11.11" @@ -2036,6 +2045,133 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-avatar@npm:^1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-avatar@npm:1.1.0" + dependencies: + "@radix-ui/react-context": 1.1.0 + "@radix-ui/react-primitive": 2.0.0 + "@radix-ui/react-use-callback-ref": 1.1.0 + "@radix-ui/react-use-layout-effect": 1.1.0 + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 9f704dee499d34edcc66dca393568518b18d80cb63572291055f5137dc603f4c150bb02ed4799d3c35b8c614cdbb23be533a0f6cfcaefdb626fb4b31edc3fdd1 + languageName: node + linkType: hard + +"@radix-ui/react-compose-refs@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-compose-refs@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 047a4ed5f87cb848be475507cd62836cf5af5761484681f521ea543ea7c9d59d61d42806d6208863d5e2380bf38cdf4cff73c2bbe5f52dbbe50fb04e1a13ac72 + languageName: node + linkType: hard + +"@radix-ui/react-context@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-context@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: d48df5e5193a1d963a1ff7a58f08497c60ddc364216c59090c8267985bd478447dd617847ea277afe10e67c4e0c528894c8d7407082325e0650038625140558a + languageName: node + linkType: hard + +"@radix-ui/react-label@npm:^2.1.0": + version: 2.1.0 + resolution: "@radix-ui/react-label@npm:2.1.0" + dependencies: + "@radix-ui/react-primitive": 2.0.0 + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 462f3b47f43bd69c937e660dee229eb05990441e1b214923cdcf848aea62226e9f1c4673de6664bb4ad66f8a480acdb0f5d2ce4c88c425652b47432876b3f32f + languageName: node + linkType: hard + +"@radix-ui/react-primitive@npm:2.0.0": + version: 2.0.0 + resolution: "@radix-ui/react-primitive@npm:2.0.0" + dependencies: + "@radix-ui/react-slot": 1.1.0 + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 04afc0f3a5ccf1de6e4861f755a89f31640d5a07237c5ac5bffe47bcd8fdf318257961fa56fedc823af49281800ee755752a371561c36fd92f008536a0553748 + languageName: node + linkType: hard + +"@radix-ui/react-slot@npm:1.1.0, @radix-ui/react-slot@npm:^1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-slot@npm:1.1.0" + dependencies: + "@radix-ui/react-compose-refs": 1.1.0 + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 3c9cd90aabf08f541e20dbecb581744be01c552a0cd16e90d7c218381bcc5307aa8a6013d045864e692ba89d3d8c17bfae08df18ed18be6d223d9330ab0302fa + languageName: node + linkType: hard + +"@radix-ui/react-use-callback-ref@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-use-callback-ref@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 2ec7903c67e3034b646005556f44fd975dc5204db6885fc58403e3584f27d95f0b573bc161de3d14fab9fda25150bf3b91f718d299fdfc701c736bd0bd2281fa + languageName: node + linkType: hard + +"@radix-ui/react-use-layout-effect@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-use-layout-effect@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 271ea0bf1cd74718895a68414a6e95537737f36e02ad08eeb61a82b229d6abda9cff3135a479e134e1f0ce2c3ff97bb85babbdce751985fb755a39b231d7ccf2 + languageName: node + linkType: hard + "@rainbow-me/rainbowkit@npm:2.1.0": version: 2.1.0 resolution: "@rainbow-me/rainbowkit@npm:2.1.0" @@ -2234,6 +2370,10 @@ __metadata: resolution: "@se-2/nextjs@workspace:packages/nextjs" dependencies: "@heroicons/react": ^2.0.11 + "@hookform/resolvers": ^3.9.0 + "@radix-ui/react-avatar": ^1.1.0 + "@radix-ui/react-label": ^2.1.0 + "@radix-ui/react-slot": ^1.1.0 "@rainbow-me/rainbowkit": 2.1.2 "@tanstack/react-query": ^5.28.6 "@trivago/prettier-plugin-sort-imports": ^4.3.0 @@ -2259,12 +2399,14 @@ __metadata: next: ^14.0.4 next-themes: ^0.2.1 nprogress: ^0.2.0 + path: ^0.12.7 postcss: ^8.4.16 prettier: ^3.3.2 qrcode.react: ^3.1.0 react: ^18.2.0 react-copy-to-clipboard: ^5.1.0 react-dom: ^18.2.0 + react-hook-form: ^7.52.1 react-hot-toast: ^2.4.0 tailwind-merge: ^2.4.0 tailwindcss: ^3.4.3 @@ -2276,6 +2418,7 @@ __metadata: vercel: ^32.4.1 viem: 2.13.6 wagmi: 2.9.8 + zod: ^3.23.8 zustand: ^4.1.2 languageName: unknown linkType: soft @@ -8804,6 +8947,13 @@ __metadata: languageName: node linkType: hard +"inherits@npm:2.0.3": + version: 2.0.3 + resolution: "inherits@npm:2.0.3" + checksum: 78cb8d7d850d20a5e9a7f3620db31483aa00ad5f722ce03a55b110e5a723539b3716a3b463e2b96ce3fe286f33afc7c131fa2f91407528ba80cea98a7545d4c0 + languageName: node + linkType: hard + "ini@npm:^1.3.5": version: 1.3.8 resolution: "ini@npm:1.3.8" @@ -11412,6 +11562,16 @@ __metadata: languageName: node linkType: hard +"path@npm:^0.12.7": + version: 0.12.7 + resolution: "path@npm:0.12.7" + dependencies: + process: ^0.11.1 + util: ^0.10.3 + checksum: 5dedb71e78fc008fcba797defc0b4e1cf06c1f18e0a631e03ba5bb505136f587ff017afc14f9a3d481cbe77aeedff7dc0c1d2ce4d820c1ebf3c4281ca49423a1 + languageName: node + linkType: hard + "pathe@npm:^1.1.0, pathe@npm:^1.1.1": version: 1.1.1 resolution: "pathe@npm:1.1.1" @@ -11744,7 +11904,7 @@ __metadata: languageName: node linkType: hard -"process@npm:^0.11.10": +"process@npm:^0.11.1, process@npm:^0.11.10": version: 0.11.10 resolution: "process@npm:0.11.10" checksum: bfcce49814f7d172a6e6a14d5fa3ac92cc3d0c3b9feb1279774708a719e19acd673995226351a082a9ae99978254e320ccda4240ddc474ba31a76c79491ca7c3 @@ -11973,6 +12133,15 @@ __metadata: languageName: node linkType: hard +"react-hook-form@npm:^7.52.1": + version: 7.52.1 + resolution: "react-hook-form@npm:7.52.1" + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 + checksum: 224fec214c5c7093b6949bc0a4fce3cf9b7a567a2f36dc3c7feeb1e721c5cccbd21f0f0ab19aa1f5f912014264f9c2224181370007609693b6c5ef6778f59ca5 + languageName: node + linkType: hard + "react-hot-toast@npm:^2.4.0": version: 2.4.1 resolution: "react-hot-toast@npm:2.4.1" @@ -14492,6 +14661,15 @@ __metadata: languageName: node linkType: hard +"util@npm:^0.10.3": + version: 0.10.4 + resolution: "util@npm:0.10.4" + dependencies: + inherits: 2.0.3 + checksum: 913f9a90d05a60e91f91af01b8bd37e06bca4cc02d7b49e01089f9d5b78be2fffd61fb1a41b517de7238c5fc7337fa939c62d1fb4eb82e014894c7bee6637aaf + languageName: node + linkType: hard + "util@npm:^0.12.4": version: 0.12.5 resolution: "util@npm:0.12.5" @@ -15294,6 +15472,13 @@ __metadata: languageName: node linkType: hard +"zod@npm:^3.23.8": + version: 3.23.8 + resolution: "zod@npm:3.23.8" + checksum: 15949ff82118f59c893dacd9d3c766d02b6fa2e71cf474d5aa888570c469dbf5446ac5ad562bb035bf7ac9650da94f290655c194f4a6de3e766f43febd432c5c + languageName: node + linkType: hard + "zustand@npm:4.4.1, zustand@npm:^4.1.2": version: 4.4.1 resolution: "zustand@npm:4.4.1"