From cf6ba321974d4585f9689c7aab522ebb1aae037e Mon Sep 17 00:00:00 2001 From: Antoine Estienne Date: Fri, 12 Sep 2025 15:03:18 +0200 Subject: [PATCH 01/18] create hook and components to create a user profile --- frontend/package-lock.json | 97 +++++++++- frontend/package.json | 9 +- frontend/src/components/Header.tsx | 23 --- .../components/{ => badges}/BadgesList.tsx | 0 frontend/src/components/pages/BadgesPage.tsx | 21 +++ .../src/components/pages/ProfilesPage.tsx | 20 +++ .../profiles/CreateProfileButton.tsx | 124 +++++++++++++ .../components/{ => profiles}/ProfileCard.tsx | 0 .../{ => profiles}/ProfilesList.tsx | 11 +- frontend/src/components/ui/dialog.tsx | 141 +++++++++++++++ frontend/src/components/ui/form.tsx | 167 ++++++++++++++++++ frontend/src/components/ui/label.tsx | 22 +++ frontend/src/hooks/use-create-profile.ts | 67 +++++++ frontend/src/pages/badges.astro | 11 +- frontend/src/pages/profiles.astro | 14 +- frontend/src/test/ProfileCard.test.tsx | 2 +- 16 files changed, 668 insertions(+), 61 deletions(-) delete mode 100644 frontend/src/components/Header.tsx rename frontend/src/components/{ => badges}/BadgesList.tsx (100%) create mode 100644 frontend/src/components/pages/BadgesPage.tsx create mode 100644 frontend/src/components/pages/ProfilesPage.tsx create mode 100644 frontend/src/components/profiles/CreateProfileButton.tsx rename frontend/src/components/{ => profiles}/ProfileCard.tsx (100%) rename frontend/src/components/{ => profiles}/ProfilesList.tsx (88%) create mode 100644 frontend/src/components/ui/dialog.tsx create mode 100644 frontend/src/components/ui/form.tsx create mode 100644 frontend/src/components/ui/label.tsx create mode 100644 frontend/src/hooks/use-create-profile.ts diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 098af81..5495f7d 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -9,13 +9,15 @@ "version": "0.0.1", "dependencies": { "@astrojs/react": "^4.3.1", + "@hookform/resolvers": "^5.2.1", "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-label": "^2.1.7", "@radix-ui/react-separator": "^1.1.7", "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-tooltip": "^1.2.8", "@rainbow-me/rainbowkit": "^2.2.8", "@tailwindcss/vite": "^4.1.13", - "@tanstack/react-query": "^5.87.1", + "@tanstack/react-query": "^5.87.4", "@tanstack/react-router": "^1.131.36", "@types/react": "^19.1.12", "@types/react-dom": "^19.1.9", @@ -26,12 +28,15 @@ "lucide-react": "^0.543.0", "react": "^19.1.1", "react-dom": "^19.1.1", + "react-hook-form": "^7.62.0", "tailwind-merge": "^3.3.1", "tailwindcss": "^4.1.13", "viem": "^2.37.5", - "wagmi": "^2.16.9" + "wagmi": "^2.16.9", + "zod": "^3.25.76" }, "devDependencies": { + "@tanstack/eslint-plugin-query": "^5.86.0", "@testing-library/jest-dom": "^6.8.0", "@testing-library/react": "^16.3.0", "@testing-library/user-event": "^14.6.1", @@ -1559,6 +1564,18 @@ "viem": ">=2.0.0" } }, + "node_modules/@hookform/resolvers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.2.1.tgz", + "integrity": "sha512-u0+6X58gkjMcxur1wRWokA7XsiiBJ6aK17aPZxhkoYiK5J+HcTx0Vhu9ovXe6H+dVpO6cjrn2FkJTryXEMlryQ==", + "license": "MIT", + "dependencies": { + "@standard-schema/utils": "^0.3.0" + }, + "peerDependencies": { + "react-hook-form": "^7.55.0" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -2888,6 +2905,29 @@ } } }, + "node_modules/@radix-ui/react-label": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.7.tgz", + "integrity": "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "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 + } + } + }, "node_modules/@radix-ui/react-popper": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz", @@ -4679,6 +4719,12 @@ "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", "license": "MIT" }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "license": "MIT" + }, "node_modules/@swc/helpers": { "version": "0.5.17", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", @@ -4950,6 +4996,23 @@ "vite": "^5.2.0 || ^6 || ^7" } }, + "node_modules/@tanstack/eslint-plugin-query": { + "version": "5.86.0", + "resolved": "https://registry.npmjs.org/@tanstack/eslint-plugin-query/-/eslint-plugin-query-5.86.0.tgz", + "integrity": "sha512-tmXdnx/fF3yY5G5jpzrJQbASY3PNzsKF0gq9IsZVqz3LJ4sExgdUFGQ305nao0wTMBOclyrSC13v/VQ3yOXu/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.37.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + } + }, "node_modules/@tanstack/history": { "version": "1.131.2", "resolved": "https://registry.npmjs.org/@tanstack/history/-/history-1.131.2.tgz", @@ -4964,9 +5027,9 @@ } }, "node_modules/@tanstack/query-core": { - "version": "5.87.1", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.87.1.tgz", - "integrity": "sha512-HOFHVvhOCprrWvtccSzc7+RNqpnLlZ5R6lTmngb8aq7b4rc2/jDT0w+vLdQ4lD9bNtQ+/A4GsFXy030Gk4ollA==", + "version": "5.87.4", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.87.4.tgz", + "integrity": "sha512-uNsg6zMxraEPDVO2Bn+F3/ctHi+Zsk+MMpcN8h6P7ozqD088F6mFY5TfGM7zuyIrL7HKpDyu6QHfLWiDxh3cuw==", "license": "MIT", "funding": { "type": "github", @@ -4974,12 +5037,12 @@ } }, "node_modules/@tanstack/react-query": { - "version": "5.87.1", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.87.1.tgz", - "integrity": "sha512-YKauf8jfMowgAqcxj96AHs+Ux3m3bWT1oSVKamaRPXSnW2HqSznnTCEkAVqctF1e/W9R/mPcyzzINIgpOH94qg==", + "version": "5.87.4", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.87.4.tgz", + "integrity": "sha512-T5GT/1ZaNsUXf5I3RhcYuT17I4CPlbZgyLxc/ZGv7ciS6esytlbjb3DgUFO6c8JWYMDpdjSWInyGZUErgzqhcA==", "license": "MIT", "dependencies": { - "@tanstack/query-core": "5.87.1" + "@tanstack/query-core": "5.87.4" }, "funding": { "type": "github", @@ -12259,6 +12322,22 @@ "react": "^19.1.1" } }, + "node_modules/react-hook-form": { + "version": "7.62.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.62.0.tgz", + "integrity": "sha512-7KWFejc98xqG/F4bAxpL41NB3o1nnvQO1RWZT3TqRZYL8RryQETGfEdVnJN2fy1crCiBLLjkRBVK05j24FxJGA==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18 || ^19" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", diff --git a/frontend/package.json b/frontend/package.json index e98a094..8c2e01a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -16,13 +16,15 @@ }, "dependencies": { "@astrojs/react": "^4.3.1", + "@hookform/resolvers": "^5.2.1", "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-label": "^2.1.7", "@radix-ui/react-separator": "^1.1.7", "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-tooltip": "^1.2.8", "@rainbow-me/rainbowkit": "^2.2.8", "@tailwindcss/vite": "^4.1.13", - "@tanstack/react-query": "^5.87.1", + "@tanstack/react-query": "^5.87.4", "@tanstack/react-router": "^1.131.36", "@types/react": "^19.1.12", "@types/react-dom": "^19.1.9", @@ -33,12 +35,15 @@ "lucide-react": "^0.543.0", "react": "^19.1.1", "react-dom": "^19.1.1", + "react-hook-form": "^7.62.0", "tailwind-merge": "^3.3.1", "tailwindcss": "^4.1.13", "viem": "^2.37.5", - "wagmi": "^2.16.9" + "wagmi": "^2.16.9", + "zod": "^3.25.76" }, "devDependencies": { + "@tanstack/eslint-plugin-query": "^5.86.0", "@testing-library/jest-dom": "^6.8.0", "@testing-library/react": "^16.3.0", "@testing-library/user-event": "^14.6.1", diff --git a/frontend/src/components/Header.tsx b/frontend/src/components/Header.tsx deleted file mode 100644 index fa5bf9e..0000000 --- a/frontend/src/components/Header.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { ConnectButton } from "@rainbow-me/rainbowkit"; - -export function Header() { - // Render ConnectButton directly; this component only runs client-side within Web3Provider - - return ( -
-
-
-
-

- The Guild Genesis -

-
- -
- -
-
-
-
- ); -} diff --git a/frontend/src/components/BadgesList.tsx b/frontend/src/components/badges/BadgesList.tsx similarity index 100% rename from frontend/src/components/BadgesList.tsx rename to frontend/src/components/badges/BadgesList.tsx diff --git a/frontend/src/components/pages/BadgesPage.tsx b/frontend/src/components/pages/BadgesPage.tsx new file mode 100644 index 0000000..9aa02ea --- /dev/null +++ b/frontend/src/components/pages/BadgesPage.tsx @@ -0,0 +1,21 @@ +import { AppWrapper } from "@/components/AppWrapper"; +import BadgesList from "@/components/badges/BadgesList"; + +export function BadgesPage() { + return ( + +
+

+ Badges +

+

+ Explore community badges. These are separate from profile badges and + represent different achievements within The Guild Genesis. +

+ +
+
+ ); +} + +export default BadgesPage; diff --git a/frontend/src/components/pages/ProfilesPage.tsx b/frontend/src/components/pages/ProfilesPage.tsx new file mode 100644 index 0000000..3a8a5b7 --- /dev/null +++ b/frontend/src/components/pages/ProfilesPage.tsx @@ -0,0 +1,20 @@ +import { AppWrapper } from "@/components/AppWrapper"; +import ProfilesList from "@/components/profiles/ProfilesList"; + +export function ProfilesPage() { + return ( + +
+

+ Profiles +

+

+ Discover and certify fellow developers in our peer-to-peer network +

+ +
+
+ ); +} + +export default ProfilesPage; diff --git a/frontend/src/components/profiles/CreateProfileButton.tsx b/frontend/src/components/profiles/CreateProfileButton.tsx new file mode 100644 index 0000000..893b1e7 --- /dev/null +++ b/frontend/src/components/profiles/CreateProfileButton.tsx @@ -0,0 +1,124 @@ +import { Plus } from "lucide-react"; +import { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; +import { useState } from "react"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { useCreateProfile } from "@/hooks/use-create-profile"; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { useForm } from "react-hook-form"; +import { z } from "zod"; +import { zodResolver } from "@hookform/resolvers/zod"; + +const formSchema = z.object({ + name: z.string().min(2, { message: "Name must be at least 2 characters." }), + description: z.string().optional(), +}); + +type FormValues = z.infer; + +export function CreateProfileButton() { + const [open, setOpen] = useState(false); + const createProfile = useCreateProfile(); + + const form = useForm({ + resolver: zodResolver(formSchema), + defaultValues: { name: "", description: "" }, + }); + + const onSubmit = async (values: FormValues) => { + await createProfile.mutateAsync({ + input: { + name: values.name, + description: values.description || "", + }, + headers: { + ethAddress: "0x2581aAa94299787a8A588B2Fceb161A302939E28", + ethSignature: "0x00000000000000", + siweMessage: "LOGIN_NONCE", + }, + }); + setOpen(false); + form.reset(); + }; + + return ( + + + + + + + Create Profile + + Provide a name and an optional description for your profile. + + +
+ + ( + + Name + + + + + + )} + /> + ( + + Description + + + + + + )} + /> +
+ + + + +
+ {createProfile.isError ? ( +

+ {(createProfile.error as Error).message} +

+ ) : null} + + +
+
+ ); +} + +export default CreateProfileButton; diff --git a/frontend/src/components/ProfileCard.tsx b/frontend/src/components/profiles/ProfileCard.tsx similarity index 100% rename from frontend/src/components/ProfileCard.tsx rename to frontend/src/components/profiles/ProfileCard.tsx diff --git a/frontend/src/components/ProfilesList.tsx b/frontend/src/components/profiles/ProfilesList.tsx similarity index 88% rename from frontend/src/components/ProfilesList.tsx rename to frontend/src/components/profiles/ProfilesList.tsx index 6f7fc5f..5deee0e 100644 --- a/frontend/src/components/ProfilesList.tsx +++ b/frontend/src/components/profiles/ProfilesList.tsx @@ -1,5 +1,7 @@ -import { ProfileCard } from "../components/ProfileCard"; -import { Search, Plus } from "lucide-react"; +import { ProfileCard } from "./ProfileCard"; +import { Search } from "lucide-react"; +import { Input } from "@/components/ui/input"; +import { CreateProfileButton } from "./CreateProfileButton"; type ProfileBadge = { id: string; @@ -90,10 +92,7 @@ export function ProfilesList() { /> - +
diff --git a/frontend/src/components/ui/dialog.tsx b/frontend/src/components/ui/dialog.tsx new file mode 100644 index 0000000..bd0cd89 --- /dev/null +++ b/frontend/src/components/ui/dialog.tsx @@ -0,0 +1,141 @@ +import * as React from "react"; +import * as DialogPrimitive from "@radix-ui/react-dialog"; +import { XIcon } from "lucide-react"; + +import { cn } from "@/lib/utils"; + +function Dialog({ + ...props +}: React.ComponentProps) { + return ; +} + +function DialogTrigger({ + ...props +}: React.ComponentProps) { + return ; +} + +function DialogPortal({ + ...props +}: React.ComponentProps) { + return ; +} + +function DialogClose({ + ...props +}: React.ComponentProps) { + return ; +} + +function DialogOverlay({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function DialogContent({ + className, + children, + showCloseButton = true, + ...props +}: React.ComponentProps & { + showCloseButton?: boolean; +}) { + return ( + + + + {children} + {showCloseButton && ( + + + Close + + )} + + + ); +} + +function DialogHeader({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function DialogFooter({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function DialogTitle({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function DialogDescription({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +export { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogOverlay, + DialogPortal, + DialogTitle, + DialogTrigger, +}; diff --git a/frontend/src/components/ui/form.tsx b/frontend/src/components/ui/form.tsx new file mode 100644 index 0000000..524b986 --- /dev/null +++ b/frontend/src/components/ui/form.tsx @@ -0,0 +1,167 @@ +"use client" + +import * as React from "react" +import * as LabelPrimitive from "@radix-ui/react-label" +import { Slot } from "@radix-ui/react-slot" +import { + Controller, + FormProvider, + useFormContext, + useFormState, + type ControllerProps, + type FieldPath, + type FieldValues, +} from "react-hook-form" + +import { cn } from "@/lib/utils" +import { Label } from "@/components/ui/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 } = useFormContext() + const formState = useFormState({ name: fieldContext.name }) + 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 +) + +function FormItem({ className, ...props }: React.ComponentProps<"div">) { + const id = React.useId() + + return ( + +
+ + ) +} + +function FormLabel({ + className, + ...props +}: React.ComponentProps) { + const { error, formItemId } = useFormField() + + return ( +
diff --git a/frontend/src/test/ProfileCard.test.tsx b/frontend/src/test/ProfileCard.test.tsx index db4c753..5c73def 100644 --- a/frontend/src/test/ProfileCard.test.tsx +++ b/frontend/src/test/ProfileCard.test.tsx @@ -1,6 +1,6 @@ import { render, screen } from "@testing-library/react"; import { describe, it, expect } from "vitest"; -import { ProfileCard } from "../components/ProfileCard"; +import { ProfileCard } from "../components/profiles/ProfileCard"; describe("ProfileCard", () => { it("renders minimal profile and badge count", () => { From f5fc3f262b6e0bda728be9f1a275cbc307b36aff Mon Sep 17 00:00:00 2001 From: Antoine Estienne Date: Fri, 12 Sep 2025 15:13:31 +0200 Subject: [PATCH 02/18] add readme to backend --- backend/README.md | 114 ++++++++++++++++++++++++++++++++++++++++++++ backend/src/main.rs | 4 +- 2 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 backend/README.md diff --git a/backend/README.md b/backend/README.md new file mode 100644 index 0000000..b0509e2 --- /dev/null +++ b/backend/README.md @@ -0,0 +1,114 @@ +# Guild Backend (Rust + Axum + SQLx) + +This service exposes a REST API for managing profiles, backed by PostgreSQL. + +- HTTP: 0.0.0.0:3001 +- DB: PostgreSQL (SQLx) +- Migrations: SQLx migrator (on startup and via `bin/migrate`) + +## 1) Prerequisites +- Rust (latest stable recommended) +- PostgreSQL 14+ (`initdb`, `pg_ctl`, `psql` available) + +## 2) Environment +Create `backend/.env`: +``` +DATABASE_URL=postgresql://guild_user:guild_password@localhost:5432/guild_genesis +RUST_LOG=guild_backend=debug,tower_http=debug +``` +The server requires `DATABASE_URL` at runtime. + +## 3) Start local Postgres +From the repo root, using Just: +``` +just db-setup +``` +This will: +- init `.postgres/` if missing +- start Postgres on localhost:5432 +- create DB `guild_genesis` and user `guild_user/guild_password` +- run backend migrations + +Manual alternative (repo root): +``` +initdb -D .postgres +pg_ctl -D .postgres -l .postgres/postgres.log start + +createdb guild_genesis || true +psql -d guild_genesis -c "CREATE USER guild_user WITH PASSWORD 'guild_password';" || true +psql -d guild_genesis -c "GRANT ALL PRIVILEGES ON DATABASE guild_genesis TO guild_user;" || true +``` +Stop Postgres: +``` +pg_ctl -D .postgres stop +``` + +## 4) Run migrations (optional) +Migrations run on server startup. To run explicitly: +``` +cd backend +cargo run --bin guild-backend +``` + +## 5) Launch the API +``` +cd backend +cargo run +``` +The server listens on `http://0.0.0.0:3001`. + +## 6) API quickstart +All endpoints require Ethereum header-based auth. + +Create profile: +``` +curl -X POST \ + -H 'Content-Type: application/json' \ + -H 'x-eth-address: 0x2581aAa94299787a8A588B2Fceb161A302939E28' \ + -H 'x-eth-signature: 0x00000000000000' \ + -H 'x-siwe-message: LOGIN_NONCE' \ + -d '{ + "name": "My profile", + "description": "Hello world", + "avatar_url": "https://example.com/avatar.png" + }' \ + http://0.0.0.0:3001/profiles/ +``` +Get profile: +``` +curl -H 'x-eth-address: 0x2581aAa94299787a8A588B2Fceb161A302939E28' \ + -H 'x-eth-signature: 0x00000000000000' \ + -H 'x-siwe-message: LOGIN_NONCE' \ + http://0.0.0.0:3001/profiles/0x2581aAa94299787a8A588B2Fceb161A302939E28 +``` +Update profile: +``` +curl -X PUT \ + -H 'Content-Type: application/json' \ + -H 'x-eth-address: 0x2581aAa94299787a8A588B2Fceb161A302939E28' \ + -H 'x-eth-signature: 0x00000000000000' \ + -H 'x-siwe-message: LOGIN_NONCE' \ + -d '{ "name": "New name", "description": "New desc" }' \ + http://0.0.0.0:3001/profiles/0x2581aAa94299787a8A588B2Fceb161A302939E28 +``` + +## 7) Troubleshooting +- initdb locale error: +``` +LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 initdb --locale=en_US.UTF-8 --encoding=UTF8 -D .postgres +``` +- Permission denied on schema `public`: +``` +psql -U postgres -d guild_genesis -c "ALTER SCHEMA public OWNER TO guild_user;" +psql -U postgres -d guild_genesis -c "GRANT USAGE, CREATE ON SCHEMA public TO guild_user;" +``` +- Rust edition 2024 error: repo pins `base64ct = 1.7.3`. If still present, `rustup update` or `rustup override set nightly` in `backend/`. + +## 8) Structure +- `src/main.rs`: boot server, run migrations +- `src/bin/migrate.rs`: standalone migrator +- `src/presentation`: routes, handlers, middlewares +- `src/infrastructure`: Postgres repository, Ethereum verification +- `src/domain`: entities, repository traits, services +- `src/application`: commands and DTOs +- `migrations/`: SQLx migrations diff --git a/backend/src/main.rs b/backend/src/main.rs index fc6012e..da514ff 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -9,6 +9,8 @@ pub mod presentation; #[tokio::main] async fn main() -> anyhow::Result<()> { + // Load env before reading variables + dotenvy::dotenv().ok(); let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); tracing_subscriber::registry() @@ -19,8 +21,6 @@ async fn main() -> anyhow::Result<()> { .with(tracing_subscriber::fmt::layer()) .init(); - dotenvy::dotenv().ok(); - let pool = sqlx::PgPool::connect(&database_url) .await .unwrap_or_else(|_| { From c15d83778f76ce5332ad9533b88f7334f36b7f68 Mon Sep 17 00:00:00 2001 From: Antoine Estienne Date: Fri, 12 Sep 2025 15:19:09 +0200 Subject: [PATCH 03/18] use wagmi to sign message and create profile --- .../profiles/CreateProfileButton.tsx | 7 ++--- frontend/src/hooks/use-create-profile.ts | 29 +++++++++++-------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/frontend/src/components/profiles/CreateProfileButton.tsx b/frontend/src/components/profiles/CreateProfileButton.tsx index 893b1e7..6aaa9d1 100644 --- a/frontend/src/components/profiles/CreateProfileButton.tsx +++ b/frontend/src/components/profiles/CreateProfileButton.tsx @@ -27,6 +27,7 @@ import { zodResolver } from "@hookform/resolvers/zod"; const formSchema = z.object({ name: z.string().min(2, { message: "Name must be at least 2 characters." }), description: z.string().optional(), + siweMessage: z.string().min(1, { message: "Message to sign is required." }), }); type FormValues = z.infer; @@ -37,7 +38,7 @@ export function CreateProfileButton() { const form = useForm({ resolver: zodResolver(formSchema), - defaultValues: { name: "", description: "" }, + defaultValues: { name: "", description: "", siweMessage: "LOGIN_NONCE" }, }); const onSubmit = async (values: FormValues) => { @@ -45,10 +46,6 @@ export function CreateProfileButton() { input: { name: values.name, description: values.description || "", - }, - headers: { - ethAddress: "0x2581aAa94299787a8A588B2Fceb161A302939E28", - ethSignature: "0x00000000000000", siweMessage: "LOGIN_NONCE", }, }); diff --git a/frontend/src/hooks/use-create-profile.ts b/frontend/src/hooks/use-create-profile.ts index c778830..aab4155 100644 --- a/frontend/src/hooks/use-create-profile.ts +++ b/frontend/src/hooks/use-create-profile.ts @@ -1,15 +1,11 @@ import { useMutation, type UseMutationResult } from "@tanstack/react-query"; +import { useAccount, useSignMessage } from "wagmi"; export type CreateProfileInput = { name: string; description?: string; avatar_url?: string; -}; - -export type CreateProfileHeaders = { - ethAddress: string; // 0x... - ethSignature: string; // signature hex string - siweMessage: string; // SIWE message or nonce + siweMessage: string; // message to sign for auth }; // Unknown response shape from backend; expose as unknown for consumers to refine @@ -20,15 +16,16 @@ const API_BASE_URL: string = async function postCreateProfile( input: CreateProfileInput, - headers: CreateProfileHeaders + address: string, + signature: string ): Promise { const response = await fetch(`${API_BASE_URL}/profiles/`, { method: "POST", headers: { "Content-Type": "application/json", - "x-eth-address": headers.ethAddress, - "x-eth-signature": headers.ethSignature, - "x-siwe-message": headers.siweMessage, + "x-eth-address": address, + "x-eth-signature": signature, + "x-siwe-message": input.siweMessage, }, body: JSON.stringify(input), }); @@ -52,7 +49,6 @@ async function postCreateProfile( type MutationVariables = { input: CreateProfileInput; - headers: CreateProfileHeaders; }; export function useCreateProfile(): UseMutationResult< @@ -60,8 +56,17 @@ export function useCreateProfile(): UseMutationResult< Error, MutationVariables > { + const { address } = useAccount(); + const { signMessageAsync } = useSignMessage(); + return useMutation({ mutationKey: ["create-profile"], - mutationFn: async ({ input, headers }) => postCreateProfile(input, headers), + mutationFn: async ({ input }) => { + if (!address) { + throw new Error("Wallet not connected"); + } + const signature = await signMessageAsync({ message: input.siweMessage }); + return postCreateProfile(input, address, signature); + }, }); } From d9cbe3dac0969491a6e6294623a5be7d2a1e89cc Mon Sep 17 00:00:00 2001 From: Antoine Estienne Date: Fri, 12 Sep 2025 15:51:12 +0200 Subject: [PATCH 04/18] add get all profiles to backend --- .../application/commands/get_all_profiles.rs | 22 +++++++++++++++++++ backend/src/application/commands/mod.rs | 1 + .../domain/repositories/profile_repository.rs | 1 + .../postgres_profile_repository.rs | 21 ++++++++++++++++++ backend/src/presentation/api.rs | 14 ++++++++---- backend/src/presentation/handlers.rs | 7 ++++++ 6 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 backend/src/application/commands/get_all_profiles.rs diff --git a/backend/src/application/commands/get_all_profiles.rs b/backend/src/application/commands/get_all_profiles.rs new file mode 100644 index 0000000..13f5bb2 --- /dev/null +++ b/backend/src/application/commands/get_all_profiles.rs @@ -0,0 +1,22 @@ +use crate::application::dtos::profile_dtos::ProfileResponse; +use crate::domain::repositories::profile_repository::ProfileRepository; +use std::sync::Arc; + +pub async fn get_all_profiles( + profile_repository: Arc, +) -> Result, String> { + let profiles = profile_repository + .find_all() + .await + .map_err(|e| e.to_string())?; + + + Ok(profiles.into_iter().map(|profile| ProfileResponse { + address: profile.address, + name: profile.name.unwrap_or_default(), + description: profile.description, + avatar_url: profile.avatar_url, + created_at: profile.created_at, + updated_at: profile.updated_at, + }).collect()) +} diff --git a/backend/src/application/commands/mod.rs b/backend/src/application/commands/mod.rs index aeaf30b..4c7c884 100644 --- a/backend/src/application/commands/mod.rs +++ b/backend/src/application/commands/mod.rs @@ -1,3 +1,4 @@ pub mod create_profile; pub mod get_profile; +pub mod get_all_profiles; pub mod update_profile; diff --git a/backend/src/domain/repositories/profile_repository.rs b/backend/src/domain/repositories/profile_repository.rs index a8c3bc0..26acdf7 100644 --- a/backend/src/domain/repositories/profile_repository.rs +++ b/backend/src/domain/repositories/profile_repository.rs @@ -8,6 +8,7 @@ pub trait ProfileRepository: Send + Sync { &self, address: &WalletAddress, ) -> Result, Box>; + async fn find_all(&self) -> Result, Box>; async fn create(&self, profile: &Profile) -> Result<(), Box>; async fn update(&self, profile: &Profile) -> Result<(), Box>; async fn delete(&self, address: &WalletAddress) -> Result<(), Box>; diff --git a/backend/src/infrastructure/repositories/postgres_profile_repository.rs b/backend/src/infrastructure/repositories/postgres_profile_repository.rs index ffac975..55abc65 100644 --- a/backend/src/infrastructure/repositories/postgres_profile_repository.rs +++ b/backend/src/infrastructure/repositories/postgres_profile_repository.rs @@ -44,6 +44,27 @@ impl ProfileRepository for PostgresProfileRepository { })) } + async fn find_all(&self) -> Result, Box> { + let rows = sqlx::query!( + r#" + SELECT address, name, description, avatar_url, created_at, updated_at + FROM profiles + "#, + ) + .fetch_all(&self.pool) + .await + .map_err(|e| Box::new(e) as Box)?; + + Ok(rows.into_iter().map(|r| Profile { + address: WalletAddress(r.address), + name: r.name, + description: r.description, + avatar_url: r.avatar_url, + created_at: r.created_at.unwrap(), + updated_at: r.updated_at.unwrap(), + }).collect()) + } + async fn create(&self, profile: &Profile) -> Result<(), Box> { sqlx::query!( r#" diff --git a/backend/src/presentation/api.rs b/backend/src/presentation/api.rs index ea83aa2..66d4dcb 100644 --- a/backend/src/presentation/api.rs +++ b/backend/src/presentation/api.rs @@ -19,7 +19,7 @@ use tower_http::{ trace::TraceLayer, }; -use super::handlers::{create_profile_handler, get_profile_handler, update_profile_handler}; +use super::handlers::{create_profile_handler, get_profile_handler, get_all_profiles_handler, update_profile_handler}; use super::middlewares::eth_auth_layer; pub async fn create_app(pool: sqlx::PgPool) -> Router { @@ -33,11 +33,18 @@ pub async fn create_app(pool: sqlx::PgPool) -> Router { let protected = Router::new() .route("/profiles/", post(create_profile_handler)) + .route("/profiles/:address", put(update_profile_handler)) + .with_state(state.clone()) + .layer(from_fn_with_state(state.clone(), eth_auth_layer)); + + let public = Router::new() .route("/profiles/:address", get(get_profile_handler)) - .route("/profiles/:address", put(update_profile_handler)); + .route("/profiles/", get(get_all_profiles_handler)) + .with_state(state.clone()); Router::new() .nest("/", protected) + .merge(public) .with_state(state.clone()) .layer( ServiceBuilder::new() @@ -48,8 +55,7 @@ pub async fn create_app(pool: sqlx::PgPool) -> Router { .allow_methods([Method::GET, Method::POST, Method::PUT, Method::DELETE]) .allow_headers(Any), ) - .layer(DefaultBodyLimit::max(1024 * 1024)) - .layer(from_fn_with_state(state, eth_auth_layer)), + .layer(DefaultBodyLimit::max(1024 * 1024)), ) } diff --git a/backend/src/presentation/handlers.rs b/backend/src/presentation/handlers.rs index 68760bf..ddd39c1 100644 --- a/backend/src/presentation/handlers.rs +++ b/backend/src/presentation/handlers.rs @@ -4,6 +4,7 @@ use crate::{ application::{ commands::{ create_profile::create_profile, get_profile::get_profile, + get_all_profiles::get_all_profiles, update_profile::update_profile, }, dtos::{CreateProfileRequest, ProfileResponse, UpdateProfileRequest}, @@ -31,6 +32,12 @@ pub async fn get_profile_handler( Json(get_profile(state.profile_repository, wallet).await.unwrap()) } +pub async fn get_all_profiles_handler( + State(state): State, +) -> Json> { + Json(get_all_profiles(state.profile_repository).await.unwrap()) +} + pub async fn update_profile_handler( State(state): State, Extension(VerifiedWallet(wallet)): Extension, From 5b2b836eed266db3bf13ba4a795bba9dbe8a3db6 Mon Sep 17 00:00:00 2001 From: Antoine Estienne Date: Fri, 12 Sep 2025 17:36:29 +0200 Subject: [PATCH 05/18] add edit profile logic --- .../profiles/CreateProfileButton.tsx | 3 + .../components/profiles/EditProfileDialog.tsx | 131 ++++++++++++++++++ .../src/components/profiles/ProfileCard.tsx | 40 +++++- .../src/components/profiles/ProfilesList.tsx | 23 ++- frontend/src/hooks/use-get-profiles.ts | 40 ++++++ frontend/src/hooks/use-update-profile.ts | 71 ++++++++++ 6 files changed, 304 insertions(+), 4 deletions(-) create mode 100644 frontend/src/components/profiles/EditProfileDialog.tsx create mode 100644 frontend/src/hooks/use-get-profiles.ts create mode 100644 frontend/src/hooks/use-update-profile.ts diff --git a/frontend/src/components/profiles/CreateProfileButton.tsx b/frontend/src/components/profiles/CreateProfileButton.tsx index 6aaa9d1..b602cb4 100644 --- a/frontend/src/components/profiles/CreateProfileButton.tsx +++ b/frontend/src/components/profiles/CreateProfileButton.tsx @@ -23,6 +23,7 @@ import { import { useForm } from "react-hook-form"; import { z } from "zod"; import { zodResolver } from "@hookform/resolvers/zod"; +import { useQueryClient } from "@tanstack/react-query"; const formSchema = z.object({ name: z.string().min(2, { message: "Name must be at least 2 characters." }), @@ -35,6 +36,7 @@ type FormValues = z.infer; export function CreateProfileButton() { const [open, setOpen] = useState(false); const createProfile = useCreateProfile(); + const queryClient = useQueryClient(); const form = useForm({ resolver: zodResolver(formSchema), @@ -49,6 +51,7 @@ export function CreateProfileButton() { siweMessage: "LOGIN_NONCE", }, }); + await queryClient.invalidateQueries({ queryKey: ["profiles"] }); setOpen(false); form.reset(); }; diff --git a/frontend/src/components/profiles/EditProfileDialog.tsx b/frontend/src/components/profiles/EditProfileDialog.tsx new file mode 100644 index 0000000..0e04f00 --- /dev/null +++ b/frontend/src/components/profiles/EditProfileDialog.tsx @@ -0,0 +1,131 @@ +import { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { useForm } from "react-hook-form"; +import { z } from "zod"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useUpdateProfile } from "@/hooks/use-update-profile"; +import { useQueryClient } from "@tanstack/react-query"; +import { useState } from "react"; + +interface EditProfileDialogProps { + address: string; + name?: string; + description?: string; + children: React.ReactNode; +} + +export function EditProfileDialog({ + address, + name, + description, + children, +}: EditProfileDialogProps) { + const [open, setOpen] = useState(false); + const updateProfile = useUpdateProfile(); + const queryClient = useQueryClient(); + + const form = useForm<{ + name: string; + description?: string; + }>({ + resolver: zodResolver( + z.object({ + name: z + .string() + .min(2, { message: "Name must be at least 2 characters." }), + description: z.string().optional(), + }) + ), + defaultValues: { name: name || "", description: description || "" }, + }); + + const onSubmit = async (values: { name: string; description?: string }) => { + await updateProfile.mutateAsync({ + input: { + name: values.name, + description: values.description || "", + siweMessage: "LOGIN_NONCE", + }, + }); + await queryClient.invalidateQueries({ queryKey: ["profiles"] }); + setOpen(false); + }; + + return ( + + {children} + + + Edit Profile + + Update your profile information. + + +
+ + ( + + Name + + + + + + )} + /> + ( + + Description + + + + + + )} + /> +
+ + + + +
+ {updateProfile.isError ? ( +

+ {(updateProfile.error as Error).message} +

+ ) : null} + + +
+
+ ); +} + +export default EditProfileDialog; diff --git a/frontend/src/components/profiles/ProfileCard.tsx b/frontend/src/components/profiles/ProfileCard.tsx index d2d1664..f8398d6 100644 --- a/frontend/src/components/profiles/ProfileCard.tsx +++ b/frontend/src/components/profiles/ProfileCard.tsx @@ -1,4 +1,4 @@ -import { Badge, Award, User } from "lucide-react"; +import { Badge, Award, User, Edit } from "lucide-react"; import { Card, CardContent, @@ -6,6 +6,9 @@ import { CardHeader, CardTitle, } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { EditProfileDialog } from "./EditProfileDialog"; +import { useAccount } from "wagmi"; interface ProfileCardProps { address: string; @@ -29,11 +32,18 @@ export function ProfileCard({ badgeCount, badges, }: ProfileCardProps) { + const { address: connectedAddress } = useAccount(); + const isOwner = connectedAddress?.toLowerCase() === address.toLowerCase(); + const displayName = name || `${address.slice(0, 6)}...${address.slice(-4)}`; const displayAddress = `${address.slice(0, 6)}...${address.slice(-4)}`; return ( - + {avatar ? ( )}
- {displayName} + + {displayName} + {isOwner && ( + + You + + )} + {displayAddress}
+ {isOwner && ( + + + + )}
{description && ( @@ -87,3 +119,5 @@ export function ProfileCard({
); } + +export default ProfileCard; diff --git a/frontend/src/components/profiles/ProfilesList.tsx b/frontend/src/components/profiles/ProfilesList.tsx index 5deee0e..40aa061 100644 --- a/frontend/src/components/profiles/ProfilesList.tsx +++ b/frontend/src/components/profiles/ProfilesList.tsx @@ -2,6 +2,7 @@ import { ProfileCard } from "./ProfileCard"; import { Search } from "lucide-react"; import { Input } from "@/components/ui/input"; import { CreateProfileButton } from "./CreateProfileButton"; +import { useGetProfiles } from "@/hooks/use-get-profiles"; type ProfileBadge = { id: string; @@ -80,6 +81,19 @@ const PROFILES: Profile[] = [ ]; export function ProfilesList() { + const { data, isLoading, error } = useGetProfiles(); + + const profiles: Profile[] = + data && data.length > 0 + ? data.map((p) => ({ + address: p.address, + name: p.name, + description: p.description, + badgeCount: 0, + badges: [], + })) + : PROFILES; + return (
@@ -95,8 +109,15 @@ export function ProfilesList() {
+ {isLoading ? ( +

Loading profiles...

+ ) : null} + {error ? ( +

{(error as Error).message}

+ ) : null} +
- {PROFILES.map((profile) => ( + {profiles.map((profile) => ( { + const response = await fetch(`${API_BASE_URL}/profiles/`, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }); + + if (!response.ok) { + const text = await response.text().catch(() => ""); + throw new Error( + `Failed to fetch profiles: ${response.status} ${response.statusText}${ + text ? ` - ${text}` : "" + }` + ); + } + + return (await response.json()) as Profile[]; +} + +export function useGetProfiles(): UseQueryResult { + return useQuery({ + queryKey: ["profiles"], + queryFn: fetchProfiles, + }); +} diff --git a/frontend/src/hooks/use-update-profile.ts b/frontend/src/hooks/use-update-profile.ts new file mode 100644 index 0000000..c1475a4 --- /dev/null +++ b/frontend/src/hooks/use-update-profile.ts @@ -0,0 +1,71 @@ +import { useMutation, type UseMutationResult } from "@tanstack/react-query"; +import { useAccount, useSignMessage } from "wagmi"; + +export type UpdateProfileInput = { + name?: string; + description?: string; + avatar_url?: string; + siweMessage: string; +}; + +export type UpdateProfileResponse = unknown; + +const API_BASE_URL: string = + import.meta.env.PUBLIC_API_URL || "http://0.0.0.0:3001"; + +async function putUpdateProfile( + address: string, + body: Omit, + signerAddress: string, + signature: string, + siweMessage: string +): Promise { + const response = await fetch(`${API_BASE_URL}/profiles/${address}`, { + method: "PUT", + headers: { + "Content-Type": "application/json", + "x-eth-address": signerAddress, + "x-eth-signature": signature, + "x-siwe-message": siweMessage, + }, + body: JSON.stringify(body), + }); + + if (!response.ok) { + const text = await response.text().catch(() => ""); + throw new Error( + `Failed to update profile: ${response.status} ${response.statusText}${ + text ? ` - ${text}` : "" + }` + ); + } + + try { + return (await response.json()) as UpdateProfileResponse; + } catch { + return {} as UpdateProfileResponse; + } +} + +type MutationVariables = { + input: UpdateProfileInput; +}; + +export function useUpdateProfile(): UseMutationResult< + UpdateProfileResponse, + Error, + MutationVariables +> { + const { address } = useAccount(); + const { signMessageAsync } = useSignMessage(); + + return useMutation({ + mutationKey: ["update-profile"], + mutationFn: async ({ input }) => { + if (!address) throw new Error("Wallet not connected"); + const signature = await signMessageAsync({ message: input.siweMessage }); + const { siweMessage, ...rest } = input; + return putUpdateProfile(address, rest, address, signature, siweMessage); + }, + }); +} From 946ccef0d232943658fb361c346ab062dbdb42e0 Mon Sep 17 00:00:00 2001 From: Antoine Estienne Date: Fri, 12 Sep 2025 18:08:38 +0200 Subject: [PATCH 06/18] fix tests --- frontend/package-lock.json | 1 + frontend/package.json | 1 + frontend/src/test/AppWrapper.test.tsx | 54 ++++++++++++++++++++++++++ frontend/src/test/Header.test.tsx | 16 -------- frontend/src/test/ProfileCard.test.tsx | 41 ++++++++++++++++++- frontend/tsconfig.json | 1 + 6 files changed, 97 insertions(+), 17 deletions(-) create mode 100644 frontend/src/test/AppWrapper.test.tsx delete mode 100644 frontend/src/test/Header.test.tsx diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 5495f7d..4ffed2a 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -42,6 +42,7 @@ "@testing-library/user-event": "^14.6.1", "@typescript-eslint/eslint-plugin": "^8.43.0", "@typescript-eslint/parser": "^8.43.0", + "@wagmi/core": "^2.20.3", "eslint": "^9.35.0", "eslint-formatter-table": "^7.32.1", "eslint-plugin-astro": "^1.3.1", diff --git a/frontend/package.json b/frontend/package.json index 8c2e01a..e6a8de4 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -49,6 +49,7 @@ "@testing-library/user-event": "^14.6.1", "@typescript-eslint/eslint-plugin": "^8.43.0", "@typescript-eslint/parser": "^8.43.0", + "@wagmi/core": "^2.20.3", "eslint": "^9.35.0", "eslint-formatter-table": "^7.32.1", "eslint-plugin-astro": "^1.3.1", diff --git a/frontend/src/test/AppWrapper.test.tsx b/frontend/src/test/AppWrapper.test.tsx new file mode 100644 index 0000000..1e9dddd --- /dev/null +++ b/frontend/src/test/AppWrapper.test.tsx @@ -0,0 +1,54 @@ +import { render, screen } from "@testing-library/react"; +import { describe, it, expect, vi } from "vitest"; +import { AppWrapper } from "@/components/AppWrapper"; +import React from "react"; + +// Mock window.matchMedia +Object.defineProperty(window, "matchMedia", { + writable: true, + value: vi.fn().mockImplementation((query) => ({ + matches: false, + media: query, + onchange: null, + addListener: vi.fn(), // deprecated + removeListener: vi.fn(), // deprecated + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + })), +}); + +// Mock wagmi +vi.mock("wagmi", () => ({ + WagmiProvider: ({ children }: { children: React.ReactNode }) => ( +
{children}
+ ), + useAccount: () => ({ address: undefined }), + useSignMessage: () => ({ signMessageAsync: vi.fn() }), +})); + +// Mock RainbowKit +vi.mock("@rainbow-me/rainbowkit", () => ({ + ConnectButton: () =>
Connect Wallet
, + RainbowKitProvider: ({ children }: { children: React.ReactNode }) => ( +
{children}
+ ), + getDefaultConfig: () => ({}), +})); + +// Mock the wagmi config +vi.mock("@/lib/wagmi", () => ({ + config: {}, +})); + +describe("AppWrapper", () => { + it("renders title and connect button", () => { + render( + +
Test
+
+ ); + expect(screen.getByText("The Guild Genesis")).toBeInTheDocument(); + expect(screen.getByTestId("connect-button")).toBeInTheDocument(); + }); +}); diff --git a/frontend/src/test/Header.test.tsx b/frontend/src/test/Header.test.tsx deleted file mode 100644 index 7a807e7..0000000 --- a/frontend/src/test/Header.test.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { render, screen } from "@testing-library/react"; -import { describe, it, expect, vi } from "vitest"; -import { Header } from "../components/Header"; - -// Mock RainbowKit ConnectButton (keeps test lightweight) -vi.mock("@rainbow-me/rainbowkit", () => ({ - ConnectButton: () =>
Connect Wallet
, -})); - -describe("Header", () => { - it("renders title and connect button", () => { - render(
); - expect(screen.getByText("The Guild Genesis")).toBeInTheDocument(); - expect(screen.getByTestId("connect-button")).toBeInTheDocument(); - }); -}); diff --git a/frontend/src/test/ProfileCard.test.tsx b/frontend/src/test/ProfileCard.test.tsx index 5c73def..c4fd5e1 100644 --- a/frontend/src/test/ProfileCard.test.tsx +++ b/frontend/src/test/ProfileCard.test.tsx @@ -1,6 +1,45 @@ import { render, screen } from "@testing-library/react"; -import { describe, it, expect } from "vitest"; +import { describe, it, expect, vi } from "vitest"; import { ProfileCard } from "../components/profiles/ProfileCard"; +import React from "react"; + +// Mock window.matchMedia +Object.defineProperty(window, "matchMedia", { + writable: true, + value: vi.fn().mockImplementation((query) => ({ + matches: false, + media: query, + onchange: null, + addListener: vi.fn(), // deprecated + removeListener: vi.fn(), // deprecated + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + })), +}); + +// Mock wagmi +vi.mock("wagmi", () => ({ + WagmiProvider: ({ children }: { children: React.ReactNode }) => ( +
{children}
+ ), + useAccount: () => ({ address: undefined }), + useSignMessage: () => ({ signMessageAsync: vi.fn() }), +})); + +// Mock RainbowKit +vi.mock("@rainbow-me/rainbowkit", () => ({ + ConnectButton: () =>
Connect Wallet
, + RainbowKitProvider: ({ children }: { children: React.ReactNode }) => ( +
{children}
+ ), + getDefaultConfig: () => ({}), +})); + +// Mock the wagmi config +vi.mock("@/lib/wagmi", () => ({ + config: {}, +})); describe("ProfileCard", () => { it("renders minimal profile and badge count", () => { diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index c94dcf5..525e2cc 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -6,6 +6,7 @@ "jsx": "react-jsx", "jsxImportSource": "react", "baseUrl": ".", + "esModuleInterop": true, "paths": { "@/*": ["./src/*"] } From e3cdaf6d94f7d564c1aaab396456658ce4e9edd0 Mon Sep 17 00:00:00 2001 From: Antoine Estienne Date: Mon, 15 Sep 2025 10:23:29 +0200 Subject: [PATCH 07/18] fix tests --- backend/src/presentation/api.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/presentation/api.rs b/backend/src/presentation/api.rs index cd6680d..492fcbd 100644 --- a/backend/src/presentation/api.rs +++ b/backend/src/presentation/api.rs @@ -37,7 +37,7 @@ pub async fn create_app(pool: sqlx::PgPool) -> Router { let protected = Router::new() .route("/profiles/", post(create_profile_handler)) .route("/profiles/:address", put(update_profile_handler)) - .route("/profiles/:address", delete(delete_profile_handler)); + .route("/profiles/:address", delete(delete_profile_handler)) .with_state(state.clone()) .layer(from_fn_with_state(state.clone(), eth_auth_layer)); From 6470b61227b281193bfb55e479c2a3009de8d0f3 Mon Sep 17 00:00:00 2001 From: Antoine Estienne Date: Mon, 15 Sep 2025 10:31:21 +0200 Subject: [PATCH 08/18] add delete fun in profiles --- .../profiles/CreateProfileButton.tsx | 5 +- .../profiles/DeleteProfileDialog.tsx | 65 +++++++++++++++++++ .../components/profiles/EditProfileDialog.tsx | 5 +- .../src/components/profiles/ProfileCard.tsx | 15 ++++- frontend/src/hooks/use-delete-profile.ts | 65 +++++++++++++++++++ justfile | 2 +- 6 files changed, 153 insertions(+), 4 deletions(-) create mode 100644 frontend/src/components/profiles/DeleteProfileDialog.tsx create mode 100644 frontend/src/hooks/use-delete-profile.ts diff --git a/frontend/src/components/profiles/CreateProfileButton.tsx b/frontend/src/components/profiles/CreateProfileButton.tsx index b602cb4..7d1628f 100644 --- a/frontend/src/components/profiles/CreateProfileButton.tsx +++ b/frontend/src/components/profiles/CreateProfileButton.tsx @@ -93,7 +93,10 @@ export function CreateProfileButton() { Description - + diff --git a/frontend/src/components/profiles/DeleteProfileDialog.tsx b/frontend/src/components/profiles/DeleteProfileDialog.tsx new file mode 100644 index 0000000..7e2806a --- /dev/null +++ b/frontend/src/components/profiles/DeleteProfileDialog.tsx @@ -0,0 +1,65 @@ +import { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; +import { Button } from "@/components/ui/button"; +import { useDeleteProfile } from "@/hooks/use-delete-profile"; +import { useQueryClient } from "@tanstack/react-query"; +import { useState } from "react"; + +interface DeleteProfileDialogProps { + children: React.ReactNode; +} + +export function DeleteProfileDialog({ children }: DeleteProfileDialogProps) { + const [open, setOpen] = useState(false); + const deleteProfile = useDeleteProfile(); + const queryClient = useQueryClient(); + + const onConfirm = async () => { + await deleteProfile.mutateAsync({ input: { siweMessage: "LOGIN_NONCE" } }); + await queryClient.invalidateQueries({ queryKey: ["profiles"] }); + setOpen(false); + }; + + return ( + + {children} + + + Delete Profile + + This action cannot be undone. This will permanently delete your + profile. + + +
+ + + + +
+ {deleteProfile.isError ? ( +

+ {(deleteProfile.error as Error).message} +

+ ) : null} +
+
+ ); +} + +export default DeleteProfileDialog; diff --git a/frontend/src/components/profiles/EditProfileDialog.tsx b/frontend/src/components/profiles/EditProfileDialog.tsx index 0e04f00..2b2c3ab 100644 --- a/frontend/src/components/profiles/EditProfileDialog.tsx +++ b/frontend/src/components/profiles/EditProfileDialog.tsx @@ -100,7 +100,10 @@ export function EditProfileDialog({ Description - + diff --git a/frontend/src/components/profiles/ProfileCard.tsx b/frontend/src/components/profiles/ProfileCard.tsx index f8398d6..e513978 100644 --- a/frontend/src/components/profiles/ProfileCard.tsx +++ b/frontend/src/components/profiles/ProfileCard.tsx @@ -1,4 +1,4 @@ -import { Badge, Award, User, Edit } from "lucide-react"; +import { Badge, Award, User, Edit, Trash } from "lucide-react"; import { Card, CardContent, @@ -9,6 +9,7 @@ import { import { Button } from "@/components/ui/button"; import { EditProfileDialog } from "./EditProfileDialog"; import { useAccount } from "wagmi"; +import DeleteProfileDialog from "./DeleteProfileDialog"; interface ProfileCardProps { address: string; @@ -115,6 +116,18 @@ export function ProfileCard({ )}
)} + {isOwner && ( + + + + )} ); diff --git a/frontend/src/hooks/use-delete-profile.ts b/frontend/src/hooks/use-delete-profile.ts new file mode 100644 index 0000000..b3d0a2d --- /dev/null +++ b/frontend/src/hooks/use-delete-profile.ts @@ -0,0 +1,65 @@ +import { useMutation, type UseMutationResult } from "@tanstack/react-query"; +import { useAccount, useSignMessage } from "wagmi"; + +export type DeleteProfileInput = { + siweMessage: string; +}; + +export type DeleteProfileResponse = unknown; + +const API_BASE_URL: string = + import.meta.env.PUBLIC_API_URL || "http://0.0.0.0:3001"; + +async function deleteProfile( + address: string, + signerAddress: string, + signature: string, + siweMessage: string +): Promise { + const response = await fetch(`${API_BASE_URL}/profiles/${address}`, { + method: "DELETE", + headers: { + "Content-Type": "application/json", + "x-eth-address": signerAddress, + "x-eth-signature": signature, + "x-siwe-message": siweMessage, + }, + }); + + if (!response.ok) { + const text = await response.text().catch(() => ""); + throw new Error( + `Failed to delete profile: ${response.status} ${response.statusText}${ + text ? ` - ${text}` : "" + }` + ); + } + + try { + return (await response.json()) as DeleteProfileResponse; + } catch { + return {} as DeleteProfileResponse; + } +} + +type MutationVariables = { + input: DeleteProfileInput; +}; + +export function useDeleteProfile(): UseMutationResult< + DeleteProfileResponse, + Error, + MutationVariables +> { + const { address } = useAccount(); + const { signMessageAsync } = useSignMessage(); + + return useMutation({ + mutationKey: ["delete-profile"], + mutationFn: async ({ input }) => { + if (!address) throw new Error("Wallet not connected"); + const signature = await signMessageAsync({ message: input.siweMessage }); + return deleteProfile(address, address, signature, input.siweMessage); + }, + }); +} diff --git a/justfile b/justfile index 2e42cc4..d8ac461 100644 --- a/justfile +++ b/justfile @@ -16,7 +16,7 @@ dev-frontend: # Start backend development server dev-backend: @echo "🦀 Starting Rust backend..." - cd backend && cargo run --bin guild-backend-dev + cd backend && cargo run --bin guild-backend # Install all dependencies install-all: From 4138369e97710129f439ec54d812221772770fdc Mon Sep 17 00:00:00 2001 From: Antoine Estienne Date: Mon, 15 Sep 2025 10:47:22 +0200 Subject: [PATCH 09/18] fmt backend --- .../application/commands/get_all_profiles.rs | 20 ++++++++++--------- backend/src/application/commands/mod.rs | 2 +- .../postgres_profile_repository.rs | 19 ++++++++++-------- backend/src/presentation/api.rs | 3 ++- backend/src/presentation/handlers.rs | 9 +++------ 5 files changed, 28 insertions(+), 25 deletions(-) diff --git a/backend/src/application/commands/get_all_profiles.rs b/backend/src/application/commands/get_all_profiles.rs index 13f5bb2..6c03edb 100644 --- a/backend/src/application/commands/get_all_profiles.rs +++ b/backend/src/application/commands/get_all_profiles.rs @@ -9,14 +9,16 @@ pub async fn get_all_profiles( .find_all() .await .map_err(|e| e.to_string())?; - - Ok(profiles.into_iter().map(|profile| ProfileResponse { - address: profile.address, - name: profile.name.unwrap_or_default(), - description: profile.description, - avatar_url: profile.avatar_url, - created_at: profile.created_at, - updated_at: profile.updated_at, - }).collect()) + Ok(profiles + .into_iter() + .map(|profile| ProfileResponse { + address: profile.address, + name: profile.name.unwrap_or_default(), + description: profile.description, + avatar_url: profile.avatar_url, + created_at: profile.created_at, + updated_at: profile.updated_at, + }) + .collect()) } diff --git a/backend/src/application/commands/mod.rs b/backend/src/application/commands/mod.rs index 4c7c884..ac3cc0c 100644 --- a/backend/src/application/commands/mod.rs +++ b/backend/src/application/commands/mod.rs @@ -1,4 +1,4 @@ pub mod create_profile; -pub mod get_profile; pub mod get_all_profiles; +pub mod get_profile; pub mod update_profile; diff --git a/backend/src/infrastructure/repositories/postgres_profile_repository.rs b/backend/src/infrastructure/repositories/postgres_profile_repository.rs index 55abc65..20e4bc3 100644 --- a/backend/src/infrastructure/repositories/postgres_profile_repository.rs +++ b/backend/src/infrastructure/repositories/postgres_profile_repository.rs @@ -55,14 +55,17 @@ impl ProfileRepository for PostgresProfileRepository { .await .map_err(|e| Box::new(e) as Box)?; - Ok(rows.into_iter().map(|r| Profile { - address: WalletAddress(r.address), - name: r.name, - description: r.description, - avatar_url: r.avatar_url, - created_at: r.created_at.unwrap(), - updated_at: r.updated_at.unwrap(), - }).collect()) + Ok(rows + .into_iter() + .map(|r| Profile { + address: WalletAddress(r.address), + name: r.name, + description: r.description, + avatar_url: r.avatar_url, + created_at: r.created_at.unwrap(), + updated_at: r.updated_at.unwrap(), + }) + .collect()) } async fn create(&self, profile: &Profile) -> Result<(), Box> { diff --git a/backend/src/presentation/api.rs b/backend/src/presentation/api.rs index 492fcbd..939b9a0 100644 --- a/backend/src/presentation/api.rs +++ b/backend/src/presentation/api.rs @@ -20,7 +20,8 @@ use tower_http::{ }; use super::handlers::{ - create_profile_handler, delete_profile_handler, get_profile_handler, get_all_profiles_handler, update_profile_handler, + create_profile_handler, delete_profile_handler, get_all_profiles_handler, get_profile_handler, + update_profile_handler, }; use super::middlewares::eth_auth_layer; diff --git a/backend/src/presentation/handlers.rs b/backend/src/presentation/handlers.rs index ddd39c1..11f9212 100644 --- a/backend/src/presentation/handlers.rs +++ b/backend/src/presentation/handlers.rs @@ -3,9 +3,8 @@ use axum::{extract::State, http::StatusCode, Extension, Json}; use crate::{ application::{ commands::{ - create_profile::create_profile, get_profile::get_profile, - get_all_profiles::get_all_profiles, - update_profile::update_profile, + create_profile::create_profile, get_all_profiles::get_all_profiles, + get_profile::get_profile, update_profile::update_profile, }, dtos::{CreateProfileRequest, ProfileResponse, UpdateProfileRequest}, }, @@ -32,9 +31,7 @@ pub async fn get_profile_handler( Json(get_profile(state.profile_repository, wallet).await.unwrap()) } -pub async fn get_all_profiles_handler( - State(state): State, -) -> Json> { +pub async fn get_all_profiles_handler(State(state): State) -> Json> { Json(get_all_profiles(state.profile_repository).await.unwrap()) } From 99a16058a9fe09ed067d0bd23d8f96d5a46c2dd0 Mon Sep 17 00:00:00 2001 From: Antoine Estienne Date: Mon, 15 Sep 2025 15:13:09 +0200 Subject: [PATCH 10/18] list badges in the front end --- frontend/.astro/types.d.ts | 1 + frontend/.env.example | 5 +- frontend/src/components/badges/BadgesList.tsx | 42 ++----- frontend/src/components/pages/BadgesPage.tsx | 4 +- .../profiles/CreateProfileButton.tsx | 2 +- .../profiles/DeleteProfileDialog.tsx | 2 +- .../components/profiles/EditProfileDialog.tsx | 2 +- .../src/components/profiles/ProfilesList.tsx | 80 +------------ frontend/src/hooks/badges/use-get-badges.ts | 113 ++++++++++++++++++ .../{ => profiles}/use-create-profile.ts | 0 .../{ => profiles}/use-delete-profile.ts | 0 .../hooks/{ => profiles}/use-get-profiles.ts | 0 .../{ => profiles}/use-update-profile.ts | 0 frontend/src/lib/constants/badgeConstants.ts | 28 +++++ .../src/lib/constants/profileConstants.ts | 75 ++++++++++++ frontend/src/lib/wagmi.ts | 11 +- .../deployBadgeRegistryAmoy.sh | 3 + .../src/TheGuildBadgeRegistry.sol | 10 ++ 18 files changed, 260 insertions(+), 118 deletions(-) create mode 100644 frontend/src/hooks/badges/use-get-badges.ts rename frontend/src/hooks/{ => profiles}/use-create-profile.ts (100%) rename frontend/src/hooks/{ => profiles}/use-delete-profile.ts (100%) rename frontend/src/hooks/{ => profiles}/use-get-profiles.ts (100%) rename frontend/src/hooks/{ => profiles}/use-update-profile.ts (100%) create mode 100644 frontend/src/lib/constants/badgeConstants.ts create mode 100644 frontend/src/lib/constants/profileConstants.ts create mode 100755 the-guild-smart-contracts/deployBadgeRegistryAmoy.sh diff --git a/frontend/.astro/types.d.ts b/frontend/.astro/types.d.ts index f964fe0..03d7cc4 100644 --- a/frontend/.astro/types.d.ts +++ b/frontend/.astro/types.d.ts @@ -1 +1,2 @@ /// +/// \ No newline at end of file diff --git a/frontend/.env.example b/frontend/.env.example index 475d5b4..5ce6f6d 100644 --- a/frontend/.env.example +++ b/frontend/.env.example @@ -2,4 +2,7 @@ PUBLIC_WALLET_CONNECT_PROJECT_ID=your_project_id_here # Backend API URL -PUBLIC_API_URL=http://localhost:3001 \ No newline at end of file +PUBLIC_API_URL=http://localhost:3001 + +# Guilfd Badge registry +PUBLIC_BADGE_REGISTRY_ADDRESS=0x92ba14dd11480d683958d0531606a78931ca0619 \ No newline at end of file diff --git a/frontend/src/components/badges/BadgesList.tsx b/frontend/src/components/badges/BadgesList.tsx index 7097355..3d07c32 100644 --- a/frontend/src/components/badges/BadgesList.tsx +++ b/frontend/src/components/badges/BadgesList.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { Badge, BadgeCheck } from "lucide-react"; +import { BadgeCheck } from "lucide-react"; import { Card, @@ -8,41 +8,19 @@ import { CardHeader, CardTitle, } from "@/components/ui/card"; - -type Badge = { - name: string; - description: string; -}; - -const HARD_CODED_BADGES: Badge[] = [ - { - name: "Open Source Contributor", - description: "Contributed code to The Guild Genesis repositories.", - }, - { - name: "Smart Contract Deployer", - description: - "Successfully deployed a smart contract to testnet or mainnet.", - }, - { - name: "Community Mentor", - description: "Helped onboard and mentor new members of the community.", - }, - { - name: "Bug Hunter", - description: - "Reported and helped resolve significant issues or vulnerabilities.", - }, - { - name: "Docs Champion", - description: "Improved documentation or tutorials for the project.", - }, -]; +import { useGetBadges } from "@/hooks/badges/use-get-badges"; +import { HARD_CODED_BADGES, type Badge } from "@/lib/constants/badgeConstants"; export function BadgesList(): React.ReactElement { + const { data, isLoading } = useGetBadges(); + const list = (data && data.length > 0 ? data : HARD_CODED_BADGES) as Badge[]; + + if (isLoading) { + return
Loading badges…
; + } return (
- {HARD_CODED_BADGES.map((badge) => ( + {list.map((badge) => ( diff --git a/frontend/src/components/pages/BadgesPage.tsx b/frontend/src/components/pages/BadgesPage.tsx index 9aa02ea..69d5c78 100644 --- a/frontend/src/components/pages/BadgesPage.tsx +++ b/frontend/src/components/pages/BadgesPage.tsx @@ -9,8 +9,8 @@ export function BadgesPage() { Badges

- Explore community badges. These are separate from profile badges and - represent different achievements within The Guild Genesis. + Explore community badges. These can be created by anyone. Anyone can + send you an attestation of a badge on your profile.

diff --git a/frontend/src/components/profiles/CreateProfileButton.tsx b/frontend/src/components/profiles/CreateProfileButton.tsx index 7d1628f..390266a 100644 --- a/frontend/src/components/profiles/CreateProfileButton.tsx +++ b/frontend/src/components/profiles/CreateProfileButton.tsx @@ -11,7 +11,7 @@ import { import { useState } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; -import { useCreateProfile } from "@/hooks/use-create-profile"; +import { useCreateProfile } from "@/hooks/profiles/use-create-profile"; import { Form, FormControl, diff --git a/frontend/src/components/profiles/DeleteProfileDialog.tsx b/frontend/src/components/profiles/DeleteProfileDialog.tsx index 7e2806a..b370333 100644 --- a/frontend/src/components/profiles/DeleteProfileDialog.tsx +++ b/frontend/src/components/profiles/DeleteProfileDialog.tsx @@ -8,7 +8,7 @@ import { DialogTrigger, } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; -import { useDeleteProfile } from "@/hooks/use-delete-profile"; +import { useDeleteProfile } from "@/hooks/profiles/use-delete-profile"; import { useQueryClient } from "@tanstack/react-query"; import { useState } from "react"; diff --git a/frontend/src/components/profiles/EditProfileDialog.tsx b/frontend/src/components/profiles/EditProfileDialog.tsx index 2b2c3ab..f4619c6 100644 --- a/frontend/src/components/profiles/EditProfileDialog.tsx +++ b/frontend/src/components/profiles/EditProfileDialog.tsx @@ -20,7 +20,7 @@ import { import { useForm } from "react-hook-form"; import { z } from "zod"; import { zodResolver } from "@hookform/resolvers/zod"; -import { useUpdateProfile } from "@/hooks/use-update-profile"; +import { useUpdateProfile } from "@/hooks/profiles/use-update-profile"; import { useQueryClient } from "@tanstack/react-query"; import { useState } from "react"; diff --git a/frontend/src/components/profiles/ProfilesList.tsx b/frontend/src/components/profiles/ProfilesList.tsx index 40aa061..3d23f90 100644 --- a/frontend/src/components/profiles/ProfilesList.tsx +++ b/frontend/src/components/profiles/ProfilesList.tsx @@ -1,84 +1,8 @@ import { ProfileCard } from "./ProfileCard"; import { Search } from "lucide-react"; -import { Input } from "@/components/ui/input"; import { CreateProfileButton } from "./CreateProfileButton"; -import { useGetProfiles } from "@/hooks/use-get-profiles"; - -type ProfileBadge = { - id: string; - name: string; - description: string; - issuer: string; -}; - -type Profile = { - address: string; - name?: string; - description?: string; - badgeCount: number; - badges: ProfileBadge[]; -}; - -const PROFILES: Profile[] = [ - { - address: "0x1234...5678", - name: "Alice Developer", - description: "Full-stack developer passionate about Web3 and Rust", - badgeCount: 5, - badges: [ - { - id: "1", - name: "Rust", - description: "Rust programming", - issuer: "0xabcd...1234", - }, - { - id: "2", - name: "React", - description: "React development", - issuer: "0xefgh...5678", - }, - { - id: "3", - name: "Web3", - description: "Blockchain development", - issuer: "0xijkl...9012", - }, - ], - }, - { - address: "0x9876...5432", - name: "Bob Builder", - description: "Smart contract developer and DeFi enthusiast", - badgeCount: 3, - badges: [ - { - id: "4", - name: "Solidity", - description: "Smart contract development", - issuer: "0xmnop...3456", - }, - { - id: "5", - name: "DeFi", - description: "Decentralized Finance", - issuer: "0xqrst...7890", - }, - ], - }, - { - address: "0x5555...7777", - badgeCount: 2, - badges: [ - { - id: "6", - name: "TypeScript", - description: "TypeScript development", - issuer: "0xuvwx...1234", - }, - ], - }, -]; +import { useGetProfiles } from "@/hooks/profiles/use-get-profiles"; +import { PROFILES, type Profile } from "@/lib/constants/profileConstants"; export function ProfilesList() { const { data, isLoading, error } = useGetProfiles(); diff --git a/frontend/src/hooks/badges/use-get-badges.ts b/frontend/src/hooks/badges/use-get-badges.ts new file mode 100644 index 0000000..911b1a2 --- /dev/null +++ b/frontend/src/hooks/badges/use-get-badges.ts @@ -0,0 +1,113 @@ +import { useMemo } from "react"; +import { useReadContract, useReadContracts } from "wagmi"; +import type { Address } from "viem"; + +export type Badge = { + name: string; + description: string; +}; + +const BADGE_REGISTRY_ADDRESS = (import.meta.env.PUBLIC_BADGE_REGISTRY_ADDRESS || + "") as Address; + +// ABI fragments for the required contract read methods +const badgeRegistryAbi = [ + { + type: "function", + name: "totalBadges", + stateMutability: "view", + inputs: [], + outputs: [{ name: "", type: "uint256" }], + }, + { + type: "function", + name: "getBadgeAt", + stateMutability: "view", + inputs: [{ name: "index", type: "uint256" }], + outputs: [ + { name: "", type: "bytes32" }, + { name: "", type: "bytes32" }, + { name: "", type: "address" }, + ], + }, +] as const; + +function bytes32ToString(value: `0x${string}`): string { + try { + // viem utils: to strip null bytes and decode + const bytes = new TextDecoder(); + // fallback simple decode by removing trailing zeros and interpreting as utf8 + // Convert hex to Uint8Array + const hex = value.startsWith("0x") ? value.slice(2) : value; + const arr = new Uint8Array(hex.length / 2); + for (let i = 0; i < arr.length; i++) { + arr[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16); + } + // Trim trailing zeros + let end = arr.length; + while (end > 0 && arr[end - 1] === 0) end--; + return bytes.decode(arr.subarray(0, end)); + } catch (_e) { + return ""; + } +} + +export function useGetBadges(): { + data: Badge[] | undefined; + isLoading: boolean; + error: Error | null; +} { + const address = BADGE_REGISTRY_ADDRESS; + + const totalBadgesQuery = useReadContract({ + abi: badgeRegistryAbi, + address, + functionName: "totalBadges", + query: { + enabled: Boolean(address), + }, + }); + + const count = Number((totalBadgesQuery.data as bigint | undefined) ?? 0n); + + const badgeContracts = useMemo( + () => + count > 0 + ? Array.from({ length: count }, (_, i) => ({ + abi: badgeRegistryAbi, + address, + functionName: "getBadgeAt" as const, + args: [BigInt(i)], + })) + : [], + [address, count] + ); + + const badgesQuery = useReadContracts({ + contracts: badgeContracts, + allowFailure: false, + query: { + enabled: Boolean(address) && count > 0, + }, + }); + + const data: Badge[] | undefined = useMemo(() => { + const results = badgesQuery.data as + | [`0x${string}`, `0x${string}`, `0x${string}`][] + | undefined; + if (!results) return undefined; + return results.map(([nameBytes, descriptionBytes]) => ({ + name: bytes32ToString(nameBytes), + description: bytes32ToString(descriptionBytes), + })); + }, [badgesQuery.data]); + + const isLoading = totalBadgesQuery.isLoading || badgesQuery.isLoading; + + const error = + (totalBadgesQuery.error as Error | null) || + (badgesQuery.error as Error | null) || + null; + + return { data, isLoading, error }; +} diff --git a/frontend/src/hooks/use-create-profile.ts b/frontend/src/hooks/profiles/use-create-profile.ts similarity index 100% rename from frontend/src/hooks/use-create-profile.ts rename to frontend/src/hooks/profiles/use-create-profile.ts diff --git a/frontend/src/hooks/use-delete-profile.ts b/frontend/src/hooks/profiles/use-delete-profile.ts similarity index 100% rename from frontend/src/hooks/use-delete-profile.ts rename to frontend/src/hooks/profiles/use-delete-profile.ts diff --git a/frontend/src/hooks/use-get-profiles.ts b/frontend/src/hooks/profiles/use-get-profiles.ts similarity index 100% rename from frontend/src/hooks/use-get-profiles.ts rename to frontend/src/hooks/profiles/use-get-profiles.ts diff --git a/frontend/src/hooks/use-update-profile.ts b/frontend/src/hooks/profiles/use-update-profile.ts similarity index 100% rename from frontend/src/hooks/use-update-profile.ts rename to frontend/src/hooks/profiles/use-update-profile.ts diff --git a/frontend/src/lib/constants/badgeConstants.ts b/frontend/src/lib/constants/badgeConstants.ts new file mode 100644 index 0000000..2dd7e1d --- /dev/null +++ b/frontend/src/lib/constants/badgeConstants.ts @@ -0,0 +1,28 @@ +export const HARD_CODED_BADGES: Badge[] = [ + { + name: "Open Source Contributor", + description: "Contributed code to The Guild Genesis repositories.", + }, + { + name: "Smart Contract Deployer", + description: + "Successfully deployed a smart contract to testnet or mainnet.", + }, + { + name: "Community Mentor", + description: "Helped onboard and mentor new members of the community.", + }, + { + name: "Bug Hunter", + description: + "Reported and helped resolve significant issues or vulnerabilities.", + }, + { + name: "Docs Champion", + description: "Improved documentation or tutorials for the project.", + }, +]; +export type Badge = { + name: string; + description: string; +}; diff --git a/frontend/src/lib/constants/profileConstants.ts b/frontend/src/lib/constants/profileConstants.ts new file mode 100644 index 0000000..1dc8673 --- /dev/null +++ b/frontend/src/lib/constants/profileConstants.ts @@ -0,0 +1,75 @@ +type ProfileBadge = { + id: string; + name: string; + description: string; + issuer: string; +}; + +export type Profile = { + address: string; + name?: string; + description?: string; + badgeCount: number; + badges: ProfileBadge[]; +}; + +export const PROFILES: Profile[] = [ + { + address: "0x1234...5678", + name: "Alice Developer", + description: "Full-stack developer passionate about Web3 and Rust", + badgeCount: 5, + badges: [ + { + id: "1", + name: "Rust", + description: "Rust programming", + issuer: "0xabcd...1234", + }, + { + id: "2", + name: "React", + description: "React development", + issuer: "0xefgh...5678", + }, + { + id: "3", + name: "Web3", + description: "Blockchain development", + issuer: "0xijkl...9012", + }, + ], + }, + { + address: "0x9876...5432", + name: "Bob Builder", + description: "Smart contract developer and DeFi enthusiast", + badgeCount: 3, + badges: [ + { + id: "4", + name: "Solidity", + description: "Smart contract development", + issuer: "0xmnop...3456", + }, + { + id: "5", + name: "DeFi", + description: "Decentralized Finance", + issuer: "0xqrst...7890", + }, + ], + }, + { + address: "0x5555...7777", + badgeCount: 2, + badges: [ + { + id: "6", + name: "TypeScript", + description: "TypeScript development", + issuer: "0xuvwx...1234", + }, + ], + }, +]; diff --git a/frontend/src/lib/wagmi.ts b/frontend/src/lib/wagmi.ts index 684f7b7..f5fbb4e 100644 --- a/frontend/src/lib/wagmi.ts +++ b/frontend/src/lib/wagmi.ts @@ -1,5 +1,12 @@ import { getDefaultConfig } from "@rainbow-me/rainbowkit"; -import { mainnet, sepolia, arbitrum, arbitrumSepolia } from "wagmi/chains"; +import { + mainnet, + sepolia, + arbitrum, + arbitrumSepolia, + polygon, + polygonAmoy, +} from "wagmi/chains"; const projectId = import.meta.env.PUBLIC_WALLET_CONNECT_PROJECT_ID as | string @@ -8,6 +15,6 @@ console.log(projectId); export const config = getDefaultConfig({ appName: "The Guild Genesis", projectId: projectId ?? "", - chains: [mainnet, sepolia, arbitrum, arbitrumSepolia], + chains: [mainnet, sepolia, arbitrum, arbitrumSepolia, polygon, polygonAmoy], ssr: false, }); diff --git a/the-guild-smart-contracts/deployBadgeRegistryAmoy.sh b/the-guild-smart-contracts/deployBadgeRegistryAmoy.sh new file mode 100755 index 0000000..0a15e74 --- /dev/null +++ b/the-guild-smart-contracts/deployBadgeRegistryAmoy.sh @@ -0,0 +1,3 @@ +source .env +forge script --chain amoy script/TheGuildBadgeRegistry.s.sol:TheGuildBadgeRegistryScript --rpc-url $AMOY_RPC_URL --broadcast --verify -vvvv --interactives 1 + diff --git a/the-guild-smart-contracts/src/TheGuildBadgeRegistry.sol b/the-guild-smart-contracts/src/TheGuildBadgeRegistry.sol index 0e2345f..966f902 100644 --- a/the-guild-smart-contracts/src/TheGuildBadgeRegistry.sol +++ b/the-guild-smart-contracts/src/TheGuildBadgeRegistry.sol @@ -71,4 +71,14 @@ contract TheGuildBadgeRegistry { function badgeNameAt(uint256 index) external view returns (bytes32) { return badgeNames[index]; } + + /// @notice Get a badge at a specific index for enumeration. + /// @dev Reverts if index is out of bounds. + function getBadgeAt( + uint256 index + ) external view returns (bytes32, bytes32, address) { + bytes32 name = badgeNames[index]; + Badge memory b = nameToBadge[name]; + return (b.name, b.description, b.creator); + } } From 269c3e4c859c8ccdaf7f18ac8c481712c4f41e4a Mon Sep 17 00:00:00 2001 From: Antoine Estienne Date: Mon, 15 Sep 2025 16:07:45 +0200 Subject: [PATCH 11/18] allow badge creation in the front end --- frontend/src/components/badges/BadgesList.tsx | 49 ++++--- .../components/badges/CreateBadgeButton.tsx | 135 ++++++++++++++++++ frontend/src/hooks/badges/use-create-badge.ts | 60 ++++++++ frontend/src/hooks/badges/use-get-badges.ts | 27 +--- frontend/src/lib/abis/badgeRegistryAbi.ts | 31 ++++ 5 files changed, 263 insertions(+), 39 deletions(-) create mode 100644 frontend/src/components/badges/CreateBadgeButton.tsx create mode 100644 frontend/src/hooks/badges/use-create-badge.ts create mode 100644 frontend/src/lib/abis/badgeRegistryAbi.ts diff --git a/frontend/src/components/badges/BadgesList.tsx b/frontend/src/components/badges/BadgesList.tsx index 3d07c32..499de62 100644 --- a/frontend/src/components/badges/BadgesList.tsx +++ b/frontend/src/components/badges/BadgesList.tsx @@ -10,6 +10,8 @@ import { } from "@/components/ui/card"; import { useGetBadges } from "@/hooks/badges/use-get-badges"; import { HARD_CODED_BADGES, type Badge } from "@/lib/constants/badgeConstants"; +import { Search } from "lucide-react"; +import { CreateBadgeButton } from "@/components/badges/CreateBadgeButton"; export function BadgesList(): React.ReactElement { const { data, isLoading } = useGetBadges(); @@ -19,22 +21,37 @@ export function BadgesList(): React.ReactElement { return
Loading badges…
; } return ( -
- {list.map((badge) => ( - - - -
- - {badge.name} -
-
- {badge.description} -
- -
- ))} -
+
+
+
+ + +
+ + +
+ +
+ {list.map((badge) => ( + + + +
+ + {badge.name} +
+
+ {badge.description} +
+ +
+ ))} +
+
); } diff --git a/frontend/src/components/badges/CreateBadgeButton.tsx b/frontend/src/components/badges/CreateBadgeButton.tsx new file mode 100644 index 0000000..017d2f6 --- /dev/null +++ b/frontend/src/components/badges/CreateBadgeButton.tsx @@ -0,0 +1,135 @@ +import { Plus } from "lucide-react"; +import { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; +import { useEffect, useState } from "react"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { useCreateBadge } from "@/hooks/badges/use-create-badge"; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { useForm } from "react-hook-form"; +import { z } from "zod"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useQueryClient } from "@tanstack/react-query"; +import { useGetBadges } from "@/hooks/badges/use-get-badges"; + +const formSchema = z.object({ + name: z.string().min(1, { message: "Name is required." }).max(32), + description: z.string().optional(), +}); + +type FormValues = z.infer; + +export function CreateBadgeButton() { + const [open, setOpen] = useState(false); + const { createBadge, isPending, error, reset, isConfirmed, isConfirming } = + useCreateBadge(); + const { refetch } = useGetBadges(); + + const form = useForm({ + resolver: zodResolver(formSchema), + defaultValues: { name: "", description: "" }, + }); + + const onSubmit = async (values: FormValues) => { + await createBadge(values.name, values.description || ""); + }; + + useEffect(() => { + if (isConfirmed) { + refetch(); + setOpen(false); + form.reset(); + reset(); + } + }, [isConfirmed, refetch, form, reset]); + + return ( + + + + + + + Create Badge + + Provide a name and an optional description for your badge. + + +
+ + ( + + Name + + + + + + )} + /> + ( + + Description + + + + + + )} + /> +
+ + + + +
+ {isConfirming ? ( +

+ Waiting for 6 block confirmations… +

+ ) : null} + {error ? ( +

{(error as Error).message}

+ ) : null} + + +
+
+ ); +} + +export default CreateBadgeButton; diff --git a/frontend/src/hooks/badges/use-create-badge.ts b/frontend/src/hooks/badges/use-create-badge.ts new file mode 100644 index 0000000..f5f481f --- /dev/null +++ b/frontend/src/hooks/badges/use-create-badge.ts @@ -0,0 +1,60 @@ +import { useMemo } from "react"; +import { useWriteContract, useWaitForTransactionReceipt } from "wagmi"; +import type { Address } from "viem"; +import { badgeRegistryAbi } from "@/lib/abis/badgeRegistryAbi"; + +const BADGE_REGISTRY_ADDRESS = (import.meta.env.PUBLIC_BADGE_REGISTRY_ADDRESS || + "") as Address; + +function stringToBytes32(value: string): `0x${string}` { + // Encode to utf8, pad/truncate to 32 bytes, return as hex + const encoder = new TextEncoder(); + const bytes = encoder.encode(value); + const out = new Uint8Array(32); + const len = Math.min(32, bytes.length); + for (let i = 0; i < len; i++) out[i] = bytes[i]; + // Convert to hex + let hex = "0x"; + for (let i = 0; i < out.length; i++) { + const h = out[i].toString(16).padStart(2, "0"); + hex += h; + } + return hex as `0x${string}`; +} + +export function useCreateBadge() { + const { writeContractAsync, isPending, error, data, reset } = + useWriteContract(); + + const createBadge = useMemo(() => { + return async (name: string, description: string) => { + if (!BADGE_REGISTRY_ADDRESS) throw new Error("Missing registry address"); + const nameBytes = stringToBytes32(name); + const descriptionBytes = stringToBytes32(description); + return writeContractAsync({ + abi: badgeRegistryAbi, + address: BADGE_REGISTRY_ADDRESS, + functionName: "createBadge", + args: [nameBytes, descriptionBytes], + }); + }; + }, [writeContractAsync]); + + const wait = useWaitForTransactionReceipt({ + hash: data as `0x${string}` | undefined, + confirmations: 6, + query: { enabled: Boolean(data) }, + }); + + return { + createBadge, + isPending, + error, + data, + isConfirming: wait.isLoading, + isConfirmed: wait.isSuccess, + receipt: wait.data, + waitError: wait.error as Error | null, + reset, + }; +} diff --git a/frontend/src/hooks/badges/use-get-badges.ts b/frontend/src/hooks/badges/use-get-badges.ts index 911b1a2..d60ab98 100644 --- a/frontend/src/hooks/badges/use-get-badges.ts +++ b/frontend/src/hooks/badges/use-get-badges.ts @@ -1,6 +1,7 @@ import { useMemo } from "react"; import { useReadContract, useReadContracts } from "wagmi"; import type { Address } from "viem"; +import { badgeRegistryAbi } from "@/lib/abis/badgeRegistryAbi"; export type Badge = { name: string; @@ -10,28 +11,6 @@ export type Badge = { const BADGE_REGISTRY_ADDRESS = (import.meta.env.PUBLIC_BADGE_REGISTRY_ADDRESS || "") as Address; -// ABI fragments for the required contract read methods -const badgeRegistryAbi = [ - { - type: "function", - name: "totalBadges", - stateMutability: "view", - inputs: [], - outputs: [{ name: "", type: "uint256" }], - }, - { - type: "function", - name: "getBadgeAt", - stateMutability: "view", - inputs: [{ name: "index", type: "uint256" }], - outputs: [ - { name: "", type: "bytes32" }, - { name: "", type: "bytes32" }, - { name: "", type: "address" }, - ], - }, -] as const; - function bytes32ToString(value: `0x${string}`): string { try { // viem utils: to strip null bytes and decode @@ -56,6 +35,7 @@ export function useGetBadges(): { data: Badge[] | undefined; isLoading: boolean; error: Error | null; + refetch: () => void; } { const address = BADGE_REGISTRY_ADDRESS; @@ -67,6 +47,7 @@ export function useGetBadges(): { enabled: Boolean(address), }, }); + console.log("totalBadgesQuery", totalBadgesQuery.data); const count = Number((totalBadgesQuery.data as bigint | undefined) ?? 0n); @@ -109,5 +90,5 @@ export function useGetBadges(): { (badgesQuery.error as Error | null) || null; - return { data, isLoading, error }; + return { data, isLoading, error, refetch: totalBadgesQuery.refetch }; } diff --git a/frontend/src/lib/abis/badgeRegistryAbi.ts b/frontend/src/lib/abis/badgeRegistryAbi.ts new file mode 100644 index 0000000..6e79c27 --- /dev/null +++ b/frontend/src/lib/abis/badgeRegistryAbi.ts @@ -0,0 +1,31 @@ +// ABI fragments for the required contract read methods +export const badgeRegistryAbi = [ + { + type: "function", + name: "totalBadges", + stateMutability: "view", + inputs: [], + outputs: [{ name: "", type: "uint256" }], + }, + { + type: "function", + name: "getBadgeAt", + stateMutability: "view", + inputs: [{ name: "index", type: "uint256" }], + outputs: [ + { name: "", type: "bytes32" }, + { name: "", type: "bytes32" }, + { name: "", type: "address" }, + ], + }, + { + type: "function", + name: "createBadge", + stateMutability: "nonpayable", + inputs: [ + { name: "name", type: "bytes32" }, + { name: "description", type: "bytes32" }, + ], + outputs: [], + }, +] as const; From 09599b42d379159da2c31e08f5e80597986d88ee Mon Sep 17 00:00:00 2001 From: Antoine Estienne Date: Mon, 15 Sep 2025 16:11:19 +0200 Subject: [PATCH 12/18] allow searching badges --- frontend/src/components/badges/BadgesList.tsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/badges/BadgesList.tsx b/frontend/src/components/badges/BadgesList.tsx index 499de62..ff2d4d1 100644 --- a/frontend/src/components/badges/BadgesList.tsx +++ b/frontend/src/components/badges/BadgesList.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useMemo, useState } from "react"; import { BadgeCheck } from "lucide-react"; import { @@ -15,8 +15,15 @@ import { CreateBadgeButton } from "@/components/badges/CreateBadgeButton"; export function BadgesList(): React.ReactElement { const { data, isLoading } = useGetBadges(); + const [searchQuery, setSearchQuery] = useState(""); const list = (data && data.length > 0 ? data : HARD_CODED_BADGES) as Badge[]; + const filtered = useMemo(() => { + const q = searchQuery.trim().toLowerCase(); + if (!q) return list; + return list.filter((b) => b.name.toLowerCase().includes(q)); + }, [list, searchQuery]); + if (isLoading) { return
Loading badges…
; } @@ -29,6 +36,8 @@ export function BadgesList(): React.ReactElement { type="text" placeholder="Search badges..." className="pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent" + value={searchQuery} + onChange={(e) => setSearchQuery(e.target.value)} />
@@ -36,7 +45,7 @@ export function BadgesList(): React.ReactElement {
- {list.map((badge) => ( + {filtered.map((badge) => ( From 65abfb77ad2d9a89426db778ff7f351f72e4f2c7 Mon Sep 17 00:00:00 2001 From: Antoine Estienne Date: Mon, 15 Sep 2025 16:13:05 +0200 Subject: [PATCH 13/18] allow searching profiles --- frontend/src/components/profiles/ProfilesList.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/profiles/ProfilesList.tsx b/frontend/src/components/profiles/ProfilesList.tsx index 3d23f90..916460c 100644 --- a/frontend/src/components/profiles/ProfilesList.tsx +++ b/frontend/src/components/profiles/ProfilesList.tsx @@ -3,9 +3,11 @@ import { Search } from "lucide-react"; import { CreateProfileButton } from "./CreateProfileButton"; import { useGetProfiles } from "@/hooks/profiles/use-get-profiles"; import { PROFILES, type Profile } from "@/lib/constants/profileConstants"; +import { useMemo, useState } from "react"; export function ProfilesList() { const { data, isLoading, error } = useGetProfiles(); + const [searchQuery, setSearchQuery] = useState(""); const profiles: Profile[] = data && data.length > 0 @@ -18,6 +20,12 @@ export function ProfilesList() { })) : PROFILES; + const filtered = useMemo(() => { + const q = searchQuery.trim().toLowerCase(); + if (!q) return profiles; + return profiles.filter((p) => (p.name || "").toLowerCase().includes(q)); + }, [profiles, searchQuery]); + return (
@@ -27,6 +35,8 @@ export function ProfilesList() { type="text" placeholder="Search profiles..." className="pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent" + value={searchQuery} + onChange={(e) => setSearchQuery(e.target.value)} />
@@ -41,7 +51,7 @@ export function ProfilesList() { ) : null}
- {profiles.map((profile) => ( + {filtered.map((profile) => ( Date: Tue, 16 Sep 2025 10:53:26 +0200 Subject: [PATCH 14/18] create and fetch attestations --- frontend/.env.example | 7 +- frontend/package-lock.json | 3514 ++++++++++++++++- frontend/package.json | 2 + .../profiles/AddAttestationDialog.tsx | 173 + .../src/components/profiles/ProfileCard.tsx | 42 +- .../src/components/profiles/ProfilesList.tsx | 48 +- frontend/src/components/ui/select.tsx | 183 + .../attestations/use-create-attestation.ts | 129 + .../attestations/use-get-attestations.ts | 165 + frontend/src/hooks/badges/use-get-badges.ts | 1 - .../src/lib/constants/profileConstants.ts | 46 +- .../80002/run-latest.json | 350 +- .../script/FullDeploymentScript.s.sol | 5 +- .../src/TheGuildActivityToken.sol | 21 + 14 files changed, 4327 insertions(+), 359 deletions(-) create mode 100644 frontend/src/components/profiles/AddAttestationDialog.tsx create mode 100644 frontend/src/components/ui/select.tsx create mode 100644 frontend/src/hooks/attestations/use-create-attestation.ts create mode 100644 frontend/src/hooks/attestations/use-get-attestations.ts diff --git a/frontend/.env.example b/frontend/.env.example index 5ce6f6d..fbb165e 100644 --- a/frontend/.env.example +++ b/frontend/.env.example @@ -4,5 +4,8 @@ PUBLIC_WALLET_CONNECT_PROJECT_ID=your_project_id_here # Backend API URL PUBLIC_API_URL=http://localhost:3001 -# Guilfd Badge registry -PUBLIC_BADGE_REGISTRY_ADDRESS=0x92ba14dd11480d683958d0531606a78931ca0619 \ No newline at end of file +# Contract addresses (values for amoy) +PUBLIC_BADGE_REGISTRY_ADDRESS=0x7e67100ce4bc2640f50c47d2dd3eebc749d8f52e +PUBLIC_EAS_CONTRACT_ADDRESS=0xb101275a60d8bfb14529C421899aD7CA1Ae5B5Fc +PUBLIC_ACTIVITY_TOKEN_ADDRESS=0x5f0a5293e33af3806ed34ba7dc139c8d3c39f310 +PUBLIC_SCHEMA_ID=0x7b0ac75049ac0cf0a8f6606194f9ff2b892bed81560a7d84d484f96c788042cc diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 4ffed2a..f7aaac1 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -9,9 +9,11 @@ "version": "0.0.1", "dependencies": { "@astrojs/react": "^4.3.1", + "@ethereum-attestation-service/eas-sdk": "^2.9.1-beta.1", "@hookform/resolvers": "^5.2.1", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-label": "^2.1.7", + "@radix-ui/react-select": "^2.2.6", "@radix-ui/react-separator": "^1.1.7", "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-tooltip": "^1.2.8", @@ -1463,6 +1465,38 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@ethereum-attestation-service/eas-contracts": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@ethereum-attestation-service/eas-contracts/-/eas-contracts-1.7.1.tgz", + "integrity": "sha512-z2MeCrkp4JrtOMBHQt5fcdbxryC+xxofoPzzv3wcx5GbfG27PpkXRKxlSlb1l2jIT1YfDc701rixbP6vHaEN3Q==", + "license": "MIT", + "dependencies": { + "hardhat": "2.22.4" + } + }, + "node_modules/@ethereum-attestation-service/eas-sdk": { + "version": "2.9.1-beta.1", + "resolved": "https://registry.npmjs.org/@ethereum-attestation-service/eas-sdk/-/eas-sdk-2.9.1-beta.1.tgz", + "integrity": "sha512-VjpVw7ToQbAkvG3svOr4KTdrxidpNpdd6VztP5cibccRKe+9VG73mY+Lvn88irDut+7uVOtvm6DZd/V5GUfAJg==", + "license": "MIT", + "dependencies": { + "@ethereum-attestation-service/eas-contracts": "1.7.1", + "@openzeppelin/merkle-tree": "^1.0.7", + "ethers": "^6.13.2", + "js-base64": "^3.7.7", + "lodash": "^4.17.21", + "multiformats": "9.9.0", + "pako": "^2.1.0", + "semver": "^7.6.3", + "viem": "^2.19.2" + } + }, + "node_modules/@ethereum-attestation-service/eas-sdk/node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==", + "license": "(MIT AND Zlib)" + }, "node_modules/@ethereumjs/common": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-3.2.0.tgz", @@ -1514,6 +1548,407 @@ "node": ">=14" } }, + "node_modules/@ethersproject/abi": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.8.0.tgz", + "integrity": "sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.8.0.tgz", + "integrity": "sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/networks": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/web": "^5.8.0" + } + }, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.8.0.tgz", + "integrity": "sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0" + } + }, + "node_modules/@ethersproject/address": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.8.0.tgz", + "integrity": "sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/rlp": "^5.8.0" + } + }, + "node_modules/@ethersproject/base64": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.8.0.tgz", + "integrity": "sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0" + } + }, + "node_modules/@ethersproject/bignumber": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.8.0.tgz", + "integrity": "sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/@ethersproject/bytes": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz", + "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/constants": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz", + "integrity": "sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.8.0.tgz", + "integrity": "sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.8.0.tgz", + "integrity": "sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz", + "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/@ethersproject/networks": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.8.0.tgz", + "integrity": "sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/properties": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz", + "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/rlp": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.8.0.tgz", + "integrity": "sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz", + "integrity": "sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "bn.js": "^5.2.1", + "elliptic": "6.6.1", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/strings": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.8.0.tgz", + "integrity": "sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/transactions": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", + "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/rlp": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.8.0.tgz", + "integrity": "sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/@floating-ui/core": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", @@ -2119,6 +2554,52 @@ "@lit-labs/ssr-dom-shim": "^1.4.0" } }, + "node_modules/@metamask/abi-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@metamask/abi-utils/-/abi-utils-2.0.4.tgz", + "integrity": "sha512-StnIgUB75x7a7AgUhiaUZDpCsqGp7VkNnZh2XivXkJ6mPkE83U8ARGQj5MbRis7VJY8BC5V1AbB1fjdh0hupPQ==", + "license": "(Apache-2.0 AND MIT)", + "dependencies": { + "@metamask/superstruct": "^3.1.0", + "@metamask/utils": "^9.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@metamask/abi-utils/node_modules/@metamask/utils": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@metamask/utils/-/utils-9.3.0.tgz", + "integrity": "sha512-w8CVbdkDrVXFJbfBSlDfafDR6BAkpDmv1bC1UJVCoVny5tW2RKAdn9i68Xf7asYT4TnUhl/hN4zfUiKQq9II4g==", + "license": "ISC", + "dependencies": { + "@ethereumjs/tx": "^4.2.0", + "@metamask/superstruct": "^3.1.0", + "@noble/hashes": "^1.3.1", + "@scure/base": "^1.1.3", + "@types/debug": "^4.1.7", + "debug": "^4.3.4", + "pony-cause": "^2.1.10", + "semver": "^7.5.4", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@metamask/abi-utils/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@metamask/eth-json-rpc-provider": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@metamask/eth-json-rpc-provider/-/eth-json-rpc-provider-1.0.1.tgz", @@ -2228,6 +2709,22 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/@metamask/eth-sig-util": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", + "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", + "license": "ISC", + "dependencies": { + "ethereumjs-abi": "^0.6.8", + "ethereumjs-util": "^6.2.1", + "ethjs-util": "^0.1.6", + "tweetnacl": "^1.0.3", + "tweetnacl-util": "^0.15.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/@metamask/json-rpc-engine": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@metamask/json-rpc-engine/-/json-rpc-engine-8.0.2.tgz", @@ -2634,6 +3131,18 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/@noble/secp256k1": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", + "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2672,11 +3181,333 @@ "node": ">= 8" } }, - "node_modules/@oslojs/encoding": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz", - "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", - "license": "MIT" + "node_modules/@nomicfoundation/edr": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.3.8.tgz", + "integrity": "sha512-u2UJ5QpznSHVkZRh6ePWoeVb6kmPrrqh08gCnZ9FHlJV9CITqlrTQHJkacd+INH31jx88pTAJnxePE4XAiH5qg==", + "license": "MIT", + "dependencies": { + "@nomicfoundation/edr-darwin-arm64": "0.3.8", + "@nomicfoundation/edr-darwin-x64": "0.3.8", + "@nomicfoundation/edr-linux-arm64-gnu": "0.3.8", + "@nomicfoundation/edr-linux-arm64-musl": "0.3.8", + "@nomicfoundation/edr-linux-x64-gnu": "0.3.8", + "@nomicfoundation/edr-linux-x64-musl": "0.3.8", + "@nomicfoundation/edr-win32-x64-msvc": "0.3.8" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-darwin-arm64": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.3.8.tgz", + "integrity": "sha512-eB0leCexS8sQEmfyD72cdvLj9djkBzQGP4wSQw6SNf2I4Sw4Cnzb3d45caG2FqFFjbvfqL0t+badUUIceqQuMw==", + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-darwin-x64": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.3.8.tgz", + "integrity": "sha512-JksVCS1N5ClwVF14EvO25HCQ+Laljh/KRfHERMVAC9ZwPbTuAd/9BtKvToCBi29uCHWqsXMI4lxCApYQv2nznw==", + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-arm64-gnu": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.3.8.tgz", + "integrity": "sha512-raCE+fOeNXhVBLUo87cgsHSGvYYRB6arih4eG6B9KGACWK5Veebtm9xtKeiD8YCsdUlUfat6F7ibpeNm91fpsA==", + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-arm64-musl": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.3.8.tgz", + "integrity": "sha512-PwiDp4wBZWMCIy29eKkv8moTKRrpiSDlrc+GQMSZLhOAm8T33JKKXPwD/2EbplbhCygJDGXZdtEKl9x9PaH66A==", + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-x64-gnu": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.3.8.tgz", + "integrity": "sha512-6AcvA/XKoipGap5jJmQ9Y6yT7Uf39D9lu2hBcDCXnXbMcXaDGw4mn1/L4R63D+9VGZyu1PqlcJixCUZlGGIWlg==", + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-x64-musl": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.3.8.tgz", + "integrity": "sha512-cxb0sEmZjlwhYWO28sPsV64VDx31ekskhC1IsDXU1p9ntjHSJRmW4KEIqJ2O3QwJap/kLKfMS6TckvY10gjc6w==", + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-win32-x64-msvc": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.3.8.tgz", + "integrity": "sha512-yVuVPqRRNLZk7TbBMkKw7lzCvI8XO8fNTPTYxymGadjr9rEGRuNTU1yBXjfJ59I1jJU/X2TSkRk1OFX0P5tpZQ==", + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/ethereumjs-common": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz", + "integrity": "sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==", + "license": "MIT", + "dependencies": { + "@nomicfoundation/ethereumjs-util": "9.0.4" + } + }, + "node_modules/@nomicfoundation/ethereumjs-rlp": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz", + "integrity": "sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==", + "license": "MPL-2.0", + "bin": { + "rlp": "bin/rlp.cjs" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@nomicfoundation/ethereumjs-tx": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz", + "integrity": "sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==", + "license": "MPL-2.0", + "dependencies": { + "@nomicfoundation/ethereumjs-common": "4.0.4", + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "c-kzg": "^2.1.2" + }, + "peerDependenciesMeta": { + "c-kzg": { + "optional": true + } + } + }, + "node_modules/@nomicfoundation/ethereumjs-tx/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "license": "MIT", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/ethereumjs-util": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz", + "integrity": "sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==", + "license": "MPL-2.0", + "dependencies": { + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "c-kzg": "^2.1.2" + }, + "peerDependenciesMeta": { + "c-kzg": { + "optional": true + } + } + }, + "node_modules/@nomicfoundation/ethereumjs-util/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "license": "MIT", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.2.tgz", + "integrity": "sha512-q4n32/FNKIhQ3zQGGw5CvPF6GTvDCpYwIf7bEY/dZTZbgfDsHyjJwURxUJf3VQuuJj+fDIFl4+KkBVbw4Ef6jA==", + "license": "MIT", + "engines": { + "node": ">= 12" + }, + "optionalDependencies": { + "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.2", + "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.2", + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.2" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-darwin-arm64": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.2.tgz", + "integrity": "sha512-JaqcWPDZENCvm++lFFGjrDd8mxtf+CtLd2MiXvMNTBD33dContTZ9TWETwNFwg7JTJT5Q9HEecH7FA+HTSsIUw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-darwin-x64": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.2.tgz", + "integrity": "sha512-fZNmVztrSXC03e9RONBT+CiksSeYcxI1wlzqyr0L7hsQlK1fzV+f04g2JtQ1c/Fe74ZwdV6aQBdd6Uwl1052sw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.2.tgz", + "integrity": "sha512-3d54oc+9ZVBuB6nbp8wHylk4xh0N0Gc+bk+/uJae+rUgbOBwQSfuGIbAZt1wBXs5REkSmynEGcqx6DutoK0tPA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-musl": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.2.tgz", + "integrity": "sha512-iDJfR2qf55vgsg7BtJa7iPiFAsYf2d0Tv/0B+vhtnI16+wfQeTbP7teookbGvAo0eJo7aLLm0xfS/GTkvHIucA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-gnu": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.2.tgz", + "integrity": "sha512-9dlHMAt5/2cpWyuJ9fQNOUXFB/vgSFORg1jpjX1Mh9hJ/MfZXlDdHQ+DpFCs32Zk5pxRBb07yGvSHk9/fezL+g==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-musl": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.2.tgz", + "integrity": "sha512-GzzVeeJob3lfrSlDKQw2bRJ8rBf6mEYaWY+gW0JnTDHINA0s2gPR4km5RLIj1xeZZOYz4zRw+AEeYgLRqB2NXg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.2.tgz", + "integrity": "sha512-Fdjli4DCcFHb4Zgsz0uEJXZ2K7VEO+w5KVv7HmT7WO10iODdU9csC2az4jrhEsRtiR9Gfd74FlG0NYlw1BMdyA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@openzeppelin/merkle-tree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@openzeppelin/merkle-tree/-/merkle-tree-1.0.8.tgz", + "integrity": "sha512-E2c9/Y3vjZXwVvPZKqCKUn7upnvam1P1ZhowJyZVQSkzZm5WhumtaRr+wkUXrZVfkIc7Gfrl7xzabElqDL09ow==", + "license": "MIT", + "dependencies": { + "@metamask/abi-utils": "^2.0.4", + "ethereum-cryptography": "^3.0.0" + } + }, + "node_modules/@openzeppelin/merkle-tree/node_modules/@noble/curves": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.0.tgz", + "integrity": "sha512-7YDlXiNMdO1YZeH6t/kvopHHbIZzlxrCV9WLqCY6QhcXOoXiNCMDqJIglZ9Yjx5+w7Dz30TITFrlTjnRg7sKEg==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.8.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@openzeppelin/merkle-tree/node_modules/ethereum-cryptography": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-3.2.0.tgz", + "integrity": "sha512-Urr5YVsalH+Jo0sYkTkv1MyI9bLYZwW8BENZCeE1QYaTHETEYx0Nv/SVsWkSqpYrzweg6d8KMY1wTjH/1m/BIg==", + "license": "MIT", + "dependencies": { + "@noble/ciphers": "1.3.0", + "@noble/curves": "1.9.0", + "@noble/hashes": "1.8.0", + "@scure/bip32": "1.7.0", + "@scure/bip39": "1.6.0" + }, + "engines": { + "node": "^14.21.3 || >=16", + "npm": ">=9" + } + }, + "node_modules/@oslojs/encoding": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz", + "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", + "license": "MIT" }, "node_modules/@paulmillr/qr": { "version": "0.2.1", @@ -2701,6 +3532,12 @@ "url": "https://opencollective.com/pkgr" } }, + "node_modules/@radix-ui/number": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", + "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", + "license": "MIT" + }, "node_modules/@radix-ui/primitive": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", @@ -2730,6 +3567,32 @@ } } }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", + "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3" + }, + "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 + } + } + }, "node_modules/@radix-ui/react-compose-refs": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", @@ -2821,6 +3684,21 @@ } } }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", + "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-dismissable-layer": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", @@ -3032,6 +3910,74 @@ } } }, + "node_modules/@radix-ui/react-select": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz", + "integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-visually-hidden": "1.2.3", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "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 + } + } + }, + "node_modules/@radix-ui/react-select/node_modules/react-remove-scroll": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz", + "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==", + "license": "MIT", + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-separator": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.7.tgz", @@ -3192,7 +4138,22 @@ } } }, - "node_modules/@radix-ui/react-use-rect": { + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", + "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", @@ -4647,6 +5608,178 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/@sentry/core": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", + "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", + "license": "BSD-3-Clause", + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/core/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" + }, + "node_modules/@sentry/hub": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", + "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/hub/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" + }, + "node_modules/@sentry/minimal": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", + "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", + "license": "BSD-3-Clause", + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/minimal/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" + }, + "node_modules/@sentry/node": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", + "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", + "license": "BSD-3-Clause", + "dependencies": { + "@sentry/core": "5.30.0", + "@sentry/hub": "5.30.0", + "@sentry/tracing": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "cookie": "^0.4.1", + "https-proxy-agent": "^5.0.0", + "lru_map": "^0.3.3", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/node/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/@sentry/node/node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sentry/node/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@sentry/node/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" + }, + "node_modules/@sentry/tracing": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", + "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", + "license": "MIT", + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/tracing/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" + }, + "node_modules/@sentry/types": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", + "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/utils": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", + "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", + "license": "BSD-3-Clause", + "dependencies": { + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/utils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" + }, "node_modules/@shikijs/core": { "version": "3.12.2", "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.12.2.tgz", @@ -5267,6 +6400,15 @@ "@babel/types": "^7.28.2" } }, + "node_modules/@types/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/chai": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz", @@ -5330,6 +6472,12 @@ "integrity": "sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==", "license": "MIT" }, + "node_modules/@types/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", + "license": "MIT" + }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", @@ -5363,6 +6511,15 @@ "undici-types": "~7.10.0" } }, + "node_modules/@types/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/react": { "version": "19.1.12", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.12.tgz", @@ -5381,6 +6538,15 @@ "@types/react": "^19.0.0" } }, + "node_modules/@types/secp256k1": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.6.tgz", + "integrity": "sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/trusted-types": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", @@ -6510,6 +7676,21 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/adm-zip": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", + "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", + "license": "MIT", + "engines": { + "node": ">=0.3.0" + } + }, + "node_modules/aes-js": { + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==", + "license": "MIT" + }, "node_modules/agent-base": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", @@ -6520,6 +7701,19 @@ "node": ">= 14" } }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -6578,6 +7772,42 @@ "node": ">=8" } }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -6967,7 +8197,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, "license": "MIT" }, "node_modules/base-64": { @@ -7015,6 +8244,24 @@ "url": "https://opencollective.com/bigjs" } }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", + "license": "MIT" + }, "node_modules/blob-to-buffer": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/blob-to-buffer/-/blob-to-buffer-1.2.9.tgz", @@ -7073,7 +8320,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -7083,7 +8329,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -7092,6 +8337,12 @@ "node": ">=8" } }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "license": "MIT" + }, "node_modules/brotli": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz", @@ -7101,6 +8352,26 @@ "base64-js": "^1.1.2" } }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "license": "ISC" + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "license": "MIT", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/browserslist": { "version": "4.25.4", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.4.tgz", @@ -7142,6 +8413,35 @@ "base-x": "^5.0.0" } }, + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "license": "MIT", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/bs58check/node_modules/base-x": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz", + "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/bs58check/node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "license": "MIT", + "dependencies": { + "base-x": "^3.0.2" + } + }, "node_modules/buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", @@ -7166,6 +8466,18 @@ "ieee754": "^1.2.1" } }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "license": "MIT" + }, "node_modules/bufferutil": { "version": "4.0.9", "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.9.tgz", @@ -7179,6 +8491,15 @@ "node": ">=6.14.2" } }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -7423,6 +8744,19 @@ "node": ">=8" } }, + "node_modules/cipher-base": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.6.tgz", + "integrity": "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/class-variance-authority": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", @@ -7435,6 +8769,15 @@ "url": "https://polar.sh/cva" } }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/cli-boxes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", @@ -7590,6 +8933,18 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", + "license": "MIT" + }, + "node_modules/commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "license": "MIT" + }, "node_modules/common-ancestor-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", @@ -7600,7 +8955,6 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, "license": "MIT" }, "node_modules/convert-source-map": { @@ -7642,6 +8996,33 @@ "node": ">=0.8" } }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, "node_modules/cross-fetch": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", @@ -7924,10 +9305,19 @@ "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", "license": "MIT" }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "license": "MIT", "engines": { "node": ">=6" @@ -8105,6 +9495,27 @@ "integrity": "sha512-TIvGp57UpeNetj/wV/xpFNpWGb0b/ROw372lHPx5Aafx02gjTBtWnEEcaSX3W2dLM3OSdGGyHX/cHl01JQsLaQ==", "license": "ISC" }, + "node_modules/elliptic": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", + "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "license": "MIT" + }, "node_modules/emoji-regex": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.5.0.tgz", @@ -8199,6 +9610,31 @@ "node": ">=10.13.0" } }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/enquirer/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/entities": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", @@ -8211,6 +9647,15 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -8311,7 +9756,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -8830,6 +10274,190 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/ethereumjs-abi": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", + "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", + "deprecated": "This library has been deprecated and usage is discouraged.", + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ethereumjs-abi/node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "license": "MIT" + }, + "node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ethereumjs-util/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ethereumjs-util/node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "license": "MIT" + }, + "node_modules/ethereumjs-util/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "license": "MIT", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethers": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.15.0.tgz", + "integrity": "sha512-Kf/3ZW54L4UT0pZtsY/rf+EkBU7Qi5nnhonjUb8yTXcxH3cdcWrV2cRyk0Xk/4jK6OoHhxxZHriyhje20If2hQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/ethers-io/" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@adraffy/ens-normalize": "1.10.1", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@types/node": "22.7.5", + "aes-js": "4.0.0-beta.5", + "tslib": "2.7.0", + "ws": "8.17.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/ethers/node_modules/@adraffy/ens-normalize": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", + "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==", + "license": "MIT" + }, + "node_modules/ethers/node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethers/node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethers/node_modules/@types/node": { + "version": "22.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", + "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/ethers/node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "license": "0BSD" + }, + "node_modules/ethers/node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" + }, + "node_modules/ethers/node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/ethjs-util": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", + "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", + "license": "MIT", + "dependencies": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, "node_modules/eventemitter2": { "version": "6.4.9", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", @@ -8851,6 +10479,16 @@ "node": ">=0.8.x" } }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "license": "MIT", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, "node_modules/expect-type": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", @@ -9006,7 +10644,6 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -9028,7 +10665,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, "license": "MIT", "dependencies": { "locate-path": "^6.0.0", @@ -9041,6 +10677,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, "node_modules/flat-cache": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", @@ -9071,6 +10716,26 @@ "node": ">=8" } }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/fontace": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/fontace/-/fontace-0.3.0.tgz", @@ -9113,6 +10778,32 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/fp-ts": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", + "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", + "license": "MIT" + }, + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC" + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -9132,165 +10823,774 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "license": "ISC" + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/h3": { + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/h3/-/h3-1.15.4.tgz", + "integrity": "sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==", + "license": "MIT", + "dependencies": { + "cookie-es": "^1.2.2", + "crossws": "^0.3.5", + "defu": "^6.1.4", + "destr": "^2.0.5", + "iron-webcrypto": "^1.2.1", + "node-mock-http": "^1.0.2", + "radix3": "^1.1.2", + "ufo": "^1.6.1", + "uncrypto": "^0.1.3" + } + }, + "node_modules/hardhat": { + "version": "2.22.4", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.22.4.tgz", + "integrity": "sha512-09qcXJFBHQUaraJkYNr7XlmwjOj27xBB0SL2rYS024hTj9tPMbp26AFjlf5quBMO9SR4AJFg+4qWahcYcvXBuQ==", + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "^5.1.2", + "@metamask/eth-sig-util": "^4.0.0", + "@nomicfoundation/edr": "^0.3.7", + "@nomicfoundation/ethereumjs-common": "4.0.4", + "@nomicfoundation/ethereumjs-tx": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", + "@nomicfoundation/solidity-analyzer": "^0.1.0", + "@sentry/node": "^5.18.1", + "@types/bn.js": "^5.1.0", + "@types/lru-cache": "^5.1.0", + "adm-zip": "^0.4.16", + "aggregate-error": "^3.0.0", + "ansi-escapes": "^4.3.0", + "boxen": "^5.1.2", + "chalk": "^2.4.2", + "chokidar": "^3.4.0", + "ci-info": "^2.0.0", + "debug": "^4.1.1", + "enquirer": "^2.3.0", + "env-paths": "^2.2.0", + "ethereum-cryptography": "^1.0.3", + "ethereumjs-abi": "^0.6.8", + "find-up": "^2.1.0", + "fp-ts": "1.19.3", + "fs-extra": "^7.0.1", + "glob": "7.2.0", + "immutable": "^4.0.0-rc.12", + "io-ts": "1.10.4", + "keccak": "^3.0.2", + "lodash": "^4.17.11", + "mnemonist": "^0.38.0", + "mocha": "^10.0.0", + "p-map": "^4.0.0", + "raw-body": "^2.4.1", + "resolve": "1.17.0", + "semver": "^6.3.0", + "solc": "0.7.3", + "source-map-support": "^0.5.13", + "stacktrace-parser": "^0.1.10", + "tsort": "0.0.1", + "undici": "^5.14.0", + "uuid": "^8.3.2", + "ws": "^7.4.6" + }, + "bin": { + "hardhat": "internal/cli/bootstrap.js" + }, + "peerDependencies": { + "ts-node": "*", + "typescript": "*" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/hardhat/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT" + }, + "node_modules/hardhat/node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/hardhat/node_modules/@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/hardhat/node_modules/@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/hardhat/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hardhat/node_modules/boxen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hardhat/node_modules/boxen/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/hardhat/node_modules/boxen/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/hardhat/node_modules/boxen/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/hardhat/node_modules/boxen/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/hardhat/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hardhat/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hardhat/node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hardhat/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/hardhat/node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "license": "MIT" + }, + "node_modules/hardhat/node_modules/cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hardhat/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/hardhat/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/hardhat/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/hardhat/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/hardhat/node_modules/ethereum-cryptography": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", + "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.2.0", + "@noble/secp256k1": "1.7.1", + "@scure/bip32": "1.1.5", + "@scure/bip39": "1.1.1" + } + }, + "node_modules/hardhat/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "license": "MIT", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hardhat/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/hardhat/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/hardhat/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "license": "MIT", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hardhat/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "license": "MIT", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hardhat/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "license": "MIT", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "node_modules/hardhat/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": ">=4" } }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "license": "ISC", + "node_modules/hardhat/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "license": "MIT", "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": ">=4" } }, - "node_modules/get-east-asian-width": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", - "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "node_modules/hardhat/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "license": "MIT", "engines": { - "node": ">=18" + "node": ">=8.6" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "node_modules/hardhat/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" + "picomatch": "^2.2.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8.10.0" } }, - "node_modules/get-nonce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", - "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "node_modules/hardhat/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/hardhat/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "node_modules/hardhat/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=8" } }, - "node_modules/github-slugger": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", - "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", - "license": "ISC" + "node_modules/hardhat/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", + "node_modules/hardhat/node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "license": "MIT", "dependencies": { - "is-glob": "^4.0.3" + "string-width": "^4.0.0" }, "engines": { - "node": ">=10.13.0" + "node": ">=8" } }, - "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true, + "node_modules/hardhat/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, "engines": { - "node": ">=18" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "node_modules/hardhat/node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" + "node_modules/hardhat/node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, + "node_modules/hardhat/node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, - "node_modules/h3": { - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/h3/-/h3-1.15.4.tgz", - "integrity": "sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==", + "node_modules/hardhat/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "license": "MIT", - "dependencies": { - "cookie-es": "^1.2.2", - "crossws": "^0.3.5", - "defu": "^6.1.4", - "destr": "^2.0.5", - "iron-webcrypto": "^1.2.1", - "node-mock-http": "^1.0.2", - "radix3": "^1.1.2", - "ufo": "^1.6.1", - "uncrypto": "^0.1.3" + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -9335,6 +11635,30 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -9534,6 +11858,26 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "license": "MIT", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, "node_modules/html-encoding-sniffer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", @@ -9569,6 +11913,22 @@ "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", "license": "BSD-2-Clause" }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/http-proxy-agent": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", @@ -9646,6 +12006,12 @@ "node": ">= 4" } }, + "node_modules/immutable": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", + "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", + "license": "MIT" + }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", @@ -9687,18 +12053,37 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, + "node_modules/io-ts": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", + "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", + "license": "MIT", + "dependencies": { + "fp-ts": "^1.0.0" + } + }, "node_modules/iron-webcrypto": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz", @@ -9731,6 +12116,18 @@ "license": "MIT", "optional": true }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -9762,7 +12159,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -9799,13 +12195,22 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=0.10.0" + } + }, + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", + "license": "MIT", + "engines": { + "node": ">=6.5.0", + "npm": ">=3" } }, "node_modules/is-inside-container": { @@ -9830,7 +12235,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -9900,6 +12304,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-wsl": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", @@ -9961,6 +12377,18 @@ "jiti": "lib/jiti-cli.mjs" } }, + "node_modules/js-base64": { + "version": "3.7.8", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.8.tgz", + "integrity": "sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==", + "license": "BSD-3-Clause" + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "license": "MIT" + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -10089,6 +12517,15 @@ "node": ">=6" } }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/keccak": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", @@ -10120,6 +12557,15 @@ "integrity": "sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g==", "license": "MIT" }, + "node_modules/klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.9" + } + }, "node_modules/kleur": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", @@ -10406,7 +12852,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, "license": "MIT", "dependencies": { "p-locate": "^5.0.0" @@ -10438,6 +12883,53 @@ "dev": true, "license": "MIT" }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/longest-streak": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", @@ -10455,6 +12947,12 @@ "dev": true, "license": "MIT" }, + "node_modules/lru_map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", + "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==", + "license": "MIT" + }, "node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", @@ -10520,6 +13018,17 @@ "node": ">= 0.4" } }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, "node_modules/mdast-util-definitions": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz", @@ -10772,6 +13281,14 @@ "@babel/runtime": "^7.12.5" } }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "engines": { + "node": ">= 0.10.0" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -11388,6 +13905,18 @@ "node": ">=4" } }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "license": "ISC" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "license": "MIT" + }, "node_modules/minimatch": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", @@ -11455,9 +13984,271 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mnemonist": { + "version": "0.38.5", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", + "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", + "license": "MIT", + "dependencies": { + "obliterator": "^2.0.0" + } + }, + "node_modules/mocha": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", + "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/mocha/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/mocha/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/mocha/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/mocha/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/mocha/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mocha/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/mocha/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/mocha/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/mocha/node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "license": "ISC", + "engines": { + "node": ">=10" } }, "node_modules/modern-ahocorasick": { @@ -11674,6 +14465,12 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/obliterator": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.5.tgz", + "integrity": "sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==", + "license": "MIT" + }, "node_modules/ofetch": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.4.1.tgz", @@ -11741,6 +14538,15 @@ "node": ">= 0.8.0" } }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ox": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/ox/-/ox-0.9.3.tgz", @@ -11790,7 +14596,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, "license": "MIT", "dependencies": { "p-limit": "^3.0.2" @@ -11806,7 +14611,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" @@ -11822,7 +14626,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -11831,6 +14634,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-queue": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.1.1.tgz", @@ -11932,6 +14750,15 @@ "node": ">=8" } }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -11942,6 +14769,12 @@ "node": ">=8" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", @@ -11959,6 +14792,54 @@ "node": ">= 14.16" } }, + "node_modules/pbkdf2": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.3.tgz", + "integrity": "sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA==", + "license": "MIT", + "dependencies": { + "create-hash": "~1.1.3", + "create-hmac": "^1.1.7", + "ripemd160": "=2.0.1", + "safe-buffer": "^5.2.1", + "sha.js": "^2.4.11", + "to-buffer": "^1.2.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/pbkdf2/node_modules/create-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", + "integrity": "sha512-snRpch/kwQhcdlnZKYanNF1m0RDlrCdSKQaH87w1FCFPVPNCQ/Il9QJKAX2jVBZddRdaHBMC+zXa9Gw9tmkNUA==", + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "sha.js": "^2.4.0" + } + }, + "node_modules/pbkdf2/node_modules/hash-base": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", + "integrity": "sha512-0TROgQ1/SxE6KmxWSvXHvRj90/Xo1JvZShofnYF+f6ZsGtR4eES7WfrQzPalmyagfKZCXpVnitiRebZulWsbiw==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1" + } + }, + "node_modules/pbkdf2/node_modules/ripemd160": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", + "integrity": "sha512-J7f4wutN8mdbV08MJnXibYpCOPHR+yzy+iQ/AsjMv2j8cLavQ8VGagDFUwwTAdF8FmRKVeNpbTTEwNHCW1g94w==", + "license": "MIT", + "dependencies": { + "hash-base": "^2.0.0", + "inherits": "^2.0.1" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -12302,6 +15183,42 @@ "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==", "license": "MIT" }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react": { "version": "19.1.1", "resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz", @@ -12654,7 +15571,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -12666,6 +15582,18 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "license": "ISC" }, + "node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "license": "MIT", + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -12754,6 +15682,41 @@ "node": ">=0.10.0" } }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rlp": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^5.2.0" + }, + "bin": { + "rlp": "bin/rlp" + } + }, "node_modules/rollup": { "version": "4.50.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.50.1.tgz", @@ -12875,7 +15838,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, "license": "MIT" }, "node_modules/saxes": { @@ -12897,6 +15859,33 @@ "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", "license": "MIT" }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", + "license": "MIT" + }, + "node_modules/secp256k1": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.4.tgz", + "integrity": "sha512-6JfvwvjUOn8F/jUoBY2Q1v5WY5XS+rj8qSe0v8Y4ezH4InLgTEeOOPQsRll9OV429Pvo6BCHGavIyJfr3TAhsw==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "elliptic": "^6.5.7", + "node-addon-api": "^5.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/secp256k1/node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", + "license": "MIT" + }, "node_modules/semver": { "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", @@ -12909,6 +15898,15 @@ "node": ">=10" } }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/seroval": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/seroval/-/seroval-1.3.2.tgz", @@ -12953,6 +15951,18 @@ "node": ">= 0.4" } }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "license": "MIT" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, "node_modules/sha.js": { "version": "2.4.12", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", @@ -13186,6 +16196,60 @@ } } }, + "node_modules/solc": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", + "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", + "license": "MIT", + "dependencies": { + "command-exists": "^1.2.8", + "commander": "3.0.2", + "follow-redirects": "^1.12.1", + "fs-extra": "^0.30.0", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "require-from-string": "^2.0.0", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "bin": { + "solcjs": "solcjs" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/solc/node_modules/fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "node_modules/solc/node_modules/jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/solc/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, "node_modules/sonic-boom": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-2.8.0.tgz", @@ -13195,6 +16259,15 @@ "atomic-sleep": "^1.0.0" } }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -13204,6 +16277,16 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "node_modules/space-separated-tokens": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", @@ -13239,6 +16322,36 @@ "dev": true, "license": "MIT" }, + "node_modules/stacktrace-parser": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.11.tgz", + "integrity": "sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.7.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stacktrace-parser/node_modules/type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/std-env": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", @@ -13328,6 +16441,19 @@ "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, + "node_modules/strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", + "license": "MIT", + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, "node_modules/strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", @@ -13345,7 +16471,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -13387,7 +16512,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -13647,6 +16771,18 @@ "dev": true, "license": "MIT" }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/to-buffer": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.1.tgz", @@ -13665,7 +16801,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -13674,6 +16809,15 @@ "node": ">=8.0" } }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, "node_modules/tough-cookie": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", @@ -13759,6 +16903,12 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/tsort": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", + "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", + "license": "MIT" + }, "node_modules/tw-animate-css": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.3.8.tgz", @@ -13769,6 +16919,18 @@ "url": "https://github.com/sponsors/Wombosvideo" } }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "license": "Unlicense" + }, + "node_modules/tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", + "license": "Unlicense" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -13875,6 +17037,18 @@ "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==", "license": "MIT" }, + "node_modules/undici": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz", + "integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==", + "license": "MIT", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, "node_modules/undici-types": { "version": "7.10.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", @@ -14054,6 +17228,24 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/unstorage": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/unstorage/-/unstorage-1.17.1.tgz", @@ -14783,6 +17975,12 @@ "node": ">=0.10.0" } }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "license": "Apache-2.0" + }, "node_modules/wrap-ansi": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", @@ -14925,6 +18123,54 @@ "node": ">=12" } }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "license": "MIT", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/yargs/node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index e6a8de4..b263bea 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -16,9 +16,11 @@ }, "dependencies": { "@astrojs/react": "^4.3.1", + "@ethereum-attestation-service/eas-sdk": "^2.9.1-beta.1", "@hookform/resolvers": "^5.2.1", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-label": "^2.1.7", + "@radix-ui/react-select": "^2.2.6", "@radix-ui/react-separator": "^1.1.7", "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-tooltip": "^1.2.8", diff --git a/frontend/src/components/profiles/AddAttestationDialog.tsx b/frontend/src/components/profiles/AddAttestationDialog.tsx new file mode 100644 index 0000000..86d6869 --- /dev/null +++ b/frontend/src/components/profiles/AddAttestationDialog.tsx @@ -0,0 +1,173 @@ +import { useEffect, useState } from "react"; +import { Plus } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; +import { Input } from "@/components/ui/input"; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { useForm } from "react-hook-form"; +import { z } from "zod"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useCreateAttestation } from "@/hooks/attestations/use-create-attestation"; +import { useGetBadges } from "@/hooks/badges/use-get-badges"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { useGetAttestations } from "@/hooks/attestations/use-get-attestations"; + +const formSchema = z.object({ + badgeName: z.string().min(1, { message: "Badge name is required." }), + justification: z.string().min(1, { message: "Justification is required." }), +}); + +type FormValues = z.infer; + +export function AddAttestationDialog({ + recipient, + children, +}: { + recipient: string; + children: React.ReactElement; +}) { + const [open, setOpen] = useState(false); + const { + createAttestation, + isPending, + isConfirming, + isConfirmed, + error, + reset, + } = useCreateAttestation(); + const { data: badges, isLoading: badgesLoading } = useGetBadges(); + const { refetch } = useGetAttestations(); + + const form = useForm({ + resolver: zodResolver(formSchema), + defaultValues: { badgeName: "", justification: "" }, + }); + + const onSubmit = async (values: FormValues) => { + await createAttestation( + recipient as `0x${string}`, + values.badgeName, + values.justification + ); + }; + + useEffect(() => { + if (isConfirmed) { + refetch(); + setOpen(false); + form.reset(); + reset(); + } + }, [isConfirmed, refetch, form, reset]); + + return ( + + {children} + + + Add Attestation + + Select a badge and provide a justification for this attestation. + + +
+ + ( + + Badge + + + + + + )} + /> + ( + + Justification + + + + + + )} + /> +
+ + + + +
+ {isConfirming ? ( +

+ Waiting for confirmations… +

+ ) : null} + {error ? ( +

{(error as Error).message}

+ ) : null} + + +
+
+ ); +} + +export default AddAttestationDialog; diff --git a/frontend/src/components/profiles/ProfileCard.tsx b/frontend/src/components/profiles/ProfileCard.tsx index e513978..df2e5de 100644 --- a/frontend/src/components/profiles/ProfileCard.tsx +++ b/frontend/src/components/profiles/ProfileCard.tsx @@ -1,4 +1,4 @@ -import { Badge, Award, User, Edit, Trash } from "lucide-react"; +import { Badge, Award, User, Edit, Trash, Plus } from "lucide-react"; import { Card, CardContent, @@ -10,17 +10,18 @@ import { Button } from "@/components/ui/button"; import { EditProfileDialog } from "./EditProfileDialog"; import { useAccount } from "wagmi"; import DeleteProfileDialog from "./DeleteProfileDialog"; +import { AddAttestationDialog } from "./AddAttestationDialog"; interface ProfileCardProps { address: string; name?: string; description?: string; avatar?: string; - badgeCount: number; - badges: Array<{ + attestationCount: number; + attestations: Array<{ id: string; - name: string; - description: string; + badgeName: string; + justification: string; issuer: string; }>; } @@ -30,15 +31,14 @@ export function ProfileCard({ name, description, avatar, - badgeCount, - badges, + attestationCount, + attestations, }: ProfileCardProps) { const { address: connectedAddress } = useAccount(); const isOwner = connectedAddress?.toLowerCase() === address.toLowerCase(); const displayName = name || `${address.slice(0, 6)}...${address.slice(-4)}`; const displayAddress = `${address.slice(0, 6)}...${address.slice(-4)}`; - return ( )} + {!isOwner && ( + + + + )} {description && ( @@ -94,24 +106,24 @@ export function ProfileCard({
- {badgeCount} badges + {attestationCount} attestations
- {badges.length > 0 && ( + {attestations.length > 0 && (
- {badges.slice(0, 3).map((badge) => ( + {attestations.slice(0, 3).map((attestation) => ( - {badge.name} + {attestation.badgeName} ))} - {badges.length > 3 && ( + {attestations.length > 3 && ( - +{badges.length - 3} more + +{attestations.length - 3} more )}
diff --git a/frontend/src/components/profiles/ProfilesList.tsx b/frontend/src/components/profiles/ProfilesList.tsx index 916460c..181a9f0 100644 --- a/frontend/src/components/profiles/ProfilesList.tsx +++ b/frontend/src/components/profiles/ProfilesList.tsx @@ -4,22 +4,56 @@ import { CreateProfileButton } from "./CreateProfileButton"; import { useGetProfiles } from "@/hooks/profiles/use-get-profiles"; import { PROFILES, type Profile } from "@/lib/constants/profileConstants"; import { useMemo, useState } from "react"; +import { useGetAttestations } from "@/hooks/attestations/use-get-attestations"; export function ProfilesList() { const { data, isLoading, error } = useGetProfiles(); const [searchQuery, setSearchQuery] = useState(""); + const attestations = useGetAttestations(); - const profiles: Profile[] = + const baseProfiles: Profile[] = data && data.length > 0 ? data.map((p) => ({ address: p.address, name: p.name, description: p.description, - badgeCount: 0, - badges: [], + attestationCount: 0, + attestations: [], })) : PROFILES; + const attestationsByRecipient = useMemo(() => { + const map = new Map< + string, + { id: string; badgeName: string; justification: string; issuer: string }[] + >(); + const list = attestations.data ?? []; + for (let i = 0; i < list.length; i++) { + const a = list[i]; + const arr = map.get(a.recipient.toLowerCase()) ?? []; + arr.push({ + id: String(i), + badgeName: a.badgeName, + justification: a.attestationJustification, + issuer: a.issuer, + }); + map.set(a.recipient.toLowerCase(), arr); + } + return map; + }, [attestations.data]); + + const profiles: Profile[] = useMemo(() => { + return baseProfiles.map((p) => { + const list = + attestationsByRecipient.get((p.address || "").toLowerCase()) ?? []; + return { + ...p, + attestationCount: list.length, + attestations: list, + }; + }); + }, [baseProfiles, attestationsByRecipient]); + const filtered = useMemo(() => { const q = searchQuery.trim().toLowerCase(); if (!q) return profiles; @@ -43,10 +77,10 @@ export function ProfilesList() {
- {isLoading ? ( + {isLoading || attestations.isLoading ? (

Loading profiles...

) : null} - {error ? ( + {error || attestations.error ? (

{(error as Error).message}

) : null} @@ -57,8 +91,8 @@ export function ProfilesList() { address={profile.address} name={profile.name} description={profile.description} - badgeCount={profile.badgeCount} - badges={profile.badges} + attestationCount={profile.attestationCount} + attestations={profile.attestations} /> ))}
diff --git a/frontend/src/components/ui/select.tsx b/frontend/src/components/ui/select.tsx new file mode 100644 index 0000000..51f466e --- /dev/null +++ b/frontend/src/components/ui/select.tsx @@ -0,0 +1,183 @@ +import * as React from "react" +import * as SelectPrimitive from "@radix-ui/react-select" +import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react" + +import { cn } from "@/lib/utils" + +function Select({ + ...props +}: React.ComponentProps) { + return +} + +function SelectGroup({ + ...props +}: React.ComponentProps) { + return +} + +function SelectValue({ + ...props +}: React.ComponentProps) { + return +} + +function SelectTrigger({ + className, + size = "default", + children, + ...props +}: React.ComponentProps & { + size?: "sm" | "default" +}) { + return ( + + {children} + + + + + ) +} + +function SelectContent({ + className, + children, + position = "popper", + ...props +}: React.ComponentProps) { + return ( + + + + + {children} + + + + + ) +} + +function SelectLabel({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function SelectItem({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + + + + + + + {children} + + ) +} + +function SelectSeparator({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function SelectScrollUpButton({ + className, + ...props +}: React.ComponentProps) { + return ( + + + + ) +} + +function SelectScrollDownButton({ + className, + ...props +}: React.ComponentProps) { + return ( + + + + ) +} + +export { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectLabel, + SelectScrollDownButton, + SelectScrollUpButton, + SelectSeparator, + SelectTrigger, + SelectValue, +} diff --git a/frontend/src/hooks/attestations/use-create-attestation.ts b/frontend/src/hooks/attestations/use-create-attestation.ts new file mode 100644 index 0000000..c79495d --- /dev/null +++ b/frontend/src/hooks/attestations/use-create-attestation.ts @@ -0,0 +1,129 @@ +import { useMemo } from "react"; +import { useWriteContract, useWaitForTransactionReceipt } from "wagmi"; +import { encodeAbiParameters } from "viem"; +import type { Address } from "viem"; + +const EAS_CONTRACT_ADDRESS = (import.meta.env.PUBLIC_EAS_CONTRACT_ADDRESS || + "0xC2679fBD37d54388Ce493F1DB75320D236e1815e") as Address; // Sepolia default + +const SCHEMA_ID = (import.meta.env.PUBLIC_SCHEMA_ID || + "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef") as `0x${string}`; + +// Minimal EAS ABI for `attest((bytes32,(address,uint64,uint64?,bool,bytes32,bytes,uint256)))`. +// Using the 1.4.0 signature from IEAS: attest((bytes32 schema, (address recipient, uint64 expirationTime, bool revocable, bytes32 refUID, bytes data, uint256 value) data)) +const easAbi = [ + { + type: "function", + name: "attest", + stateMutability: "payable", + inputs: [ + { + name: "request", + type: "tuple", + components: [ + { name: "schema", type: "bytes32" }, + { + name: "data", + type: "tuple", + components: [ + { name: "recipient", type: "address" }, + { name: "expirationTime", type: "uint64" }, + { name: "revocable", type: "bool" }, + { name: "refUID", type: "bytes32" }, + { name: "data", type: "bytes" }, + { name: "value", type: "uint256" }, + ], + }, + ], + }, + ], + outputs: [{ name: "uid", type: "bytes32" }], + }, +] as const; + +function stringToBytes32(value: string): `0x${string}` { + const encoder = new TextEncoder(); + const bytes = encoder.encode(value); + const out = new Uint8Array(32); + const len = Math.min(32, bytes.length); + for (let i = 0; i < len; i++) out[i] = bytes[i]; + let hex = "0x"; + for (let i = 0; i < out.length; i++) + hex += out[i].toString(16).padStart(2, "0"); + return hex as `0x${string}`; +} + +function encodeBadgeData( + badgeName: `0x${string}`, + justification: `0x${string}` +) { + // Encode according to schema: bytes32 badgeName, bytes32 justification + return encodeAbiParameters( + [{ type: "bytes32" }, { type: "bytes32" }], + [badgeName, justification] + ); +} + +export function useCreateAttestation() { + const { + writeContractAsync, + data: hash, + isPending, + error, + reset, + } = useWriteContract(); + + const createAttestation = useMemo(() => { + return async ( + recipient: `0x${string}`, + badgeName: string, + justification: string + ) => { + // Convert strings to bytes32 + const badgeNameBytes = stringToBytes32(badgeName); + const justificationBytes = stringToBytes32(justification); + + // Encode data according to schema + const encodedData = encodeBadgeData(badgeNameBytes, justificationBytes); + // Call EAS.attest via wagmi + const uid = await writeContractAsync({ + abi: easAbi, + address: EAS_CONTRACT_ADDRESS, + functionName: "attest", + args: [ + { + schema: SCHEMA_ID, + data: { + recipient, + expirationTime: 0n, + revocable: true, + refUID: + "0x0000000000000000000000000000000000000000000000000000000000000000", + data: encodedData, + value: 0n, + }, + }, + ], + // value: 0n, // no ETH + }); + + return uid; + }; + }, [writeContractAsync]); + + const wait = useWaitForTransactionReceipt({ + hash: hash as `0x${string}` | undefined, + query: { enabled: Boolean(hash) }, + }); + + return { + createAttestation, + hash, + isPending, + error, + reset, + isConfirming: wait.isLoading, + isConfirmed: wait.isSuccess, + receipt: wait.data, + }; +} diff --git a/frontend/src/hooks/attestations/use-get-attestations.ts b/frontend/src/hooks/attestations/use-get-attestations.ts new file mode 100644 index 0000000..e42336f --- /dev/null +++ b/frontend/src/hooks/attestations/use-get-attestations.ts @@ -0,0 +1,165 @@ +import { useMemo } from "react"; +import { useReadContract, useReadContracts } from "wagmi"; +import type { Address } from "viem"; +import { decodeAbiParameters } from "viem"; + +export type AttestationItem = { + issuer: string; + recipient: string; + badgeName: string; + attestationJustification: string; +}; + +const ACTIVITY_TOKEN_ADDRESS = (import.meta.env.PUBLIC_ACTIVITY_TOKEN_ADDRESS || + "") as Address; + +// Minimal ABI fragments we need from TheGuildActivityToken / EAS +const activityTokenAbi = [ + { + type: "function", + name: "getAttestationCount", + stateMutability: "view", + inputs: [], + outputs: [{ name: "", type: "uint256" }], + }, + { + type: "function", + name: "getAttestationAtIndex", + stateMutability: "view", + inputs: [{ name: "index", type: "uint256" }], + outputs: [ + { + name: "", + type: "tuple", + components: [ + { name: "uid", type: "bytes32" }, + { name: "schema", type: "bytes32" }, + { name: "time", type: "uint64" }, + { name: "expirationTime", type: "uint64" }, + { name: "revocationTime", type: "uint64" }, + { name: "refUID", type: "bytes32" }, + { name: "recipient", type: "address" }, + { name: "attester", type: "address" }, + { name: "revocable", type: "bool" }, + { name: "data", type: "bytes" }, + { name: "bump", type: "uint32" }, + ], + }, + ], + }, +] as const; + +function bytes32ToString(value: `0x${string}`): string { + try { + // viem utils: to strip null bytes and decode + const bytes = new TextDecoder(); + // fallback simple decode by removing trailing zeros and interpreting as utf8 + // Convert hex to Uint8Array + const hex = value.startsWith("0x") ? value.slice(2) : value; + const arr = new Uint8Array(hex.length / 2); + for (let i = 0; i < arr.length; i++) { + arr[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16); + } + // Trim trailing zeros + let end = arr.length; + while (end > 0 && arr[end - 1] === 0) end--; + return bytes.decode(arr.subarray(0, end)); + } catch (_e) { + return ""; + } +} + +function tryDecodeBadgeData(data: `0x${string}` | null | undefined): { + badgeName: string; + justification: string; +} { + if (!data) return { badgeName: "", justification: "" }; + try { + const [nameBytes, justificationBytes] = decodeAbiParameters( + [{ type: "bytes32" }, { type: "bytes32" }], + data + ) as [`0x${string}`, `0x${string}`]; + return { + badgeName: bytes32ToString(nameBytes), + justification: bytes32ToString(justificationBytes), + }; + } catch { + return { badgeName: "", justification: "" }; + } +} + +export function useGetAttestations(): { + data: AttestationItem[] | undefined; + isLoading: boolean; + error: Error | null; + refetch: () => void; +} { + const address = ACTIVITY_TOKEN_ADDRESS; + + const countQuery = useReadContract({ + abi: activityTokenAbi, + address, + functionName: "getAttestationCount", + query: { enabled: Boolean(address) }, + }); + + const count = Number((countQuery.data as bigint | undefined) ?? 0n); + + const attestationCalls = useMemo( + () => + count > 0 + ? Array.from({ length: count }, (_, i) => ({ + abi: activityTokenAbi, + address, + functionName: "getAttestationAtIndex" as const, + args: [BigInt(i)], + })) + : [], + [address, count] + ); + + const listQuery = useReadContracts({ + contracts: attestationCalls, + allowFailure: false, + query: { enabled: Boolean(address) && count > 0 }, + }); + + const data: AttestationItem[] | undefined = useMemo(() => { + const results = listQuery.data as + | Array<{ + attester: `0x${string}`; + bump: number; + data: `0x${string}`; + expirationTime: bigint; + recipient: `0x${string}`; + refUID: `0x${string}`; + revocable: boolean; + revocationTime: bigint; + schema: `0x${string}`; + time: bigint; + uid: `0x${string}`; + }> + | undefined; + if (!results) return undefined; + return results.map((r) => { + const recipient = r.recipient as string; + const issuer = r.attester as string; + const bytesData = r.data as `0x${string}`; + const { badgeName, justification } = tryDecodeBadgeData(bytesData); + return { + issuer, + recipient, + badgeName, + attestationJustification: justification, + }; + }); + }, [listQuery.data]); + + const isLoading = countQuery.isLoading || listQuery.isLoading; + const error = + (countQuery.error as Error | null) || + (listQuery.error as Error | null) || + null; + + return { data, isLoading, error, refetch: countQuery.refetch }; +} diff --git a/frontend/src/hooks/badges/use-get-badges.ts b/frontend/src/hooks/badges/use-get-badges.ts index d60ab98..4eda539 100644 --- a/frontend/src/hooks/badges/use-get-badges.ts +++ b/frontend/src/hooks/badges/use-get-badges.ts @@ -47,7 +47,6 @@ export function useGetBadges(): { enabled: Boolean(address), }, }); - console.log("totalBadgesQuery", totalBadgesQuery.data); const count = Number((totalBadgesQuery.data as bigint | undefined) ?? 0n); diff --git a/frontend/src/lib/constants/profileConstants.ts b/frontend/src/lib/constants/profileConstants.ts index 1dc8673..38a6ae5 100644 --- a/frontend/src/lib/constants/profileConstants.ts +++ b/frontend/src/lib/constants/profileConstants.ts @@ -1,7 +1,7 @@ -type ProfileBadge = { +type ProfileAttestation = { id: string; - name: string; - description: string; + badgeName: string; + justification: string; issuer: string; }; @@ -9,8 +9,8 @@ export type Profile = { address: string; name?: string; description?: string; - badgeCount: number; - badges: ProfileBadge[]; + attestationCount: number; + attestations: ProfileAttestation[]; }; export const PROFILES: Profile[] = [ @@ -18,24 +18,24 @@ export const PROFILES: Profile[] = [ address: "0x1234...5678", name: "Alice Developer", description: "Full-stack developer passionate about Web3 and Rust", - badgeCount: 5, - badges: [ + attestationCount: 5, + attestations: [ { id: "1", - name: "Rust", - description: "Rust programming", + badgeName: "Rust", + justification: "Rust programming", issuer: "0xabcd...1234", }, { id: "2", - name: "React", - description: "React development", + badgeName: "React", + justification: "React development", issuer: "0xefgh...5678", }, { id: "3", - name: "Web3", - description: "Blockchain development", + badgeName: "Web3", + justification: "Blockchain development", issuer: "0xijkl...9012", }, ], @@ -44,30 +44,30 @@ export const PROFILES: Profile[] = [ address: "0x9876...5432", name: "Bob Builder", description: "Smart contract developer and DeFi enthusiast", - badgeCount: 3, - badges: [ + attestationCount: 3, + attestations: [ { id: "4", - name: "Solidity", - description: "Smart contract development", + badgeName: "Solidity", + justification: "Smart contract development", issuer: "0xmnop...3456", }, { id: "5", - name: "DeFi", - description: "Decentralized Finance", + badgeName: "DeFi", + justification: "Decentralized Finance", issuer: "0xqrst...7890", }, ], }, { address: "0x5555...7777", - badgeCount: 2, - badges: [ + attestationCount: 2, + attestations: [ { id: "6", - name: "TypeScript", - description: "TypeScript development", + badgeName: "TypeScript", + justification: "TypeScript development", issuer: "0xuvwx...1234", }, ], diff --git a/the-guild-smart-contracts/broadcast/FullDeploymentScript.s.sol/80002/run-latest.json b/the-guild-smart-contracts/broadcast/FullDeploymentScript.s.sol/80002/run-latest.json index 35a2580..4e09e40 100644 --- a/the-guild-smart-contracts/broadcast/FullDeploymentScript.s.sol/80002/run-latest.json +++ b/the-guild-smart-contracts/broadcast/FullDeploymentScript.s.sol/80002/run-latest.json @@ -1,10 +1,10 @@ { "transactions": [ { - "hash": "0x8a5c54d5296dcaa6a0b8964549e0a0b43e1e26d00882c41ac07133921c2cd9ec", + "hash": "0x60ad89b3c639393b160bc1439f493636b52462a63b28e1c21314dda40b21a3da", "transactionType": "CREATE2", "contractName": "TheGuildActivityToken", - "contractAddress": "0x5a79dd0f66e2c1203948dd49634e506b3d8723a0", + "contractAddress": "0x5f0a5293e33af3806ed34ba7dc139c8d3c39f310", "function": null, "arguments": [ "0xb101275a60d8bfb14529C421899aD7CA1Ae5B5Fc" @@ -12,24 +12,24 @@ "transaction": { "from": "0x6cfd0753ec4da15dcb418e11e921c0665c1d1cbf", "to": "0x4e59b44847b379578588920ca78fbf26c0b4956c", - "gas": "0x25fdda", + "gas": "0x2e0ece", "value": "0x0", - "input": "0x7468656775696c64320000000000000000000000000000000000000000000000610100604052348015610010575f5ffd5b506040516124bb3803806124bb83398181016040528101906100329190610334565b80600160045f336040518060400160405280601581526020017f5468654775696c644163746976697479546f6b656e00000000000000000000008152506040518060400160405280600381526020017f544741000000000000000000000000000000000000000000000000000000000081525081600390816100b4919061059c565b5080600490816100c4919061059c565b5050505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610137575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161012e919061067a565b60405180910390fd5b6101468161020260201b60201c565b5082608081815250508160a081815250508060c081815250505050505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101c7576040517f83780ffe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660e08173ffffffffffffffffffffffffffffffffffffffff16815250505050610693565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6102f2826102c9565b9050919050565b5f610303826102e8565b9050919050565b610313816102f9565b811461031d575f5ffd5b50565b5f8151905061032e8161030a565b92915050565b5f60208284031215610349576103486102c5565b5b5f61035684828501610320565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806103da57607f821691505b6020821081036103ed576103ec610396565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261044f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610414565b6104598683610414565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61049d61049861049384610471565b61047a565b610471565b9050919050565b5f819050919050565b6104b683610483565b6104ca6104c2826104a4565b848454610420565b825550505050565b5f5f905090565b6104e16104d2565b6104ec8184846104ad565b505050565b5b8181101561050f576105045f826104d9565b6001810190506104f2565b5050565b601f82111561055457610525816103f3565b61052e84610405565b8101602085101561053d578190505b61055161054985610405565b8301826104f1565b50505b505050565b5f82821c905092915050565b5f6105745f1984600802610559565b1980831691505092915050565b5f61058c8383610565565b9150826002028217905092915050565b6105a58261035f565b67ffffffffffffffff8111156105be576105bd610369565b5b6105c882546103c3565b6105d3828285610513565b5f60209050601f831160018114610604575f84156105f2578287015190505b6105fc8582610581565b865550610663565b601f198416610612866103f3565b5f5b8281101561063957848901518255600182019150602085019450602081019050610614565b868310156106565784890151610652601f891682610565565b8355505b6001600288020188555050505b505050505050565b610674816102e8565b82525050565b5f60208201905061068d5f83018461066b565b92915050565b60805160a05160c05160e051611df56106c65f395f610f4c01525f61063f01525f61061601525f6105ed0152611df55ff3fe608060405260043610610117575f3560e01c806388e5b2d91161009f578063ce46e04611610063578063ce46e046146103ea578063dd62ed3e14610414578063e49617e114610450578063e60c350514610480578063f2fde38b146104b05761015c565b806388e5b2d9146102fa5780638da5cb5b1461032a57806391db0b7e1461035457806395d89b4114610384578063a9059cbb146103ae5761015c565b8063313ce567116100e6578063313ce5671461022c57806340c10f191461025657806354fd4d501461027e57806370a08231146102a8578063715018a6146102e45761015c565b806306fdde0314610160578063095ea7b31461018a57806318160ddd146101c657806323b872dd146101f05761015c565b3661015c576101246104d8565b61015a576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b005b5f5ffd5b34801561016b575f5ffd5b506101746104df565b60405161018191906115cb565b60405180910390f35b348015610195575f5ffd5b506101b060048036038101906101ab9190611680565b61056f565b6040516101bd91906116d8565b60405180910390f35b3480156101d1575f5ffd5b506101da610591565b6040516101e79190611700565b60405180910390f35b3480156101fb575f5ffd5b5061021660048036038101906102119190611719565b61059a565b60405161022391906116d8565b60405180910390f35b348015610237575f5ffd5b506102406105c8565b60405161024d9190611784565b60405180910390f35b348015610261575f5ffd5b5061027c60048036038101906102779190611680565b6105d0565b005b348015610289575f5ffd5b506102926105e6565b60405161029f91906115cb565b60405180910390f35b3480156102b3575f5ffd5b506102ce60048036038101906102c9919061179d565b610689565b6040516102db9190611700565b60405180910390f35b3480156102ef575f5ffd5b506102f86106ce565b005b610314600480360381019061030f919061187e565b6106e1565b60405161032191906116d8565b60405180910390f35b348015610335575f5ffd5b5061033e6107f4565b60405161034b919061190b565b60405180910390f35b61036e6004803603810190610369919061187e565b61081c565b60405161037b91906116d8565b60405180910390f35b34801561038f575f5ffd5b5061039861092f565b6040516103a591906115cb565b60405180910390f35b3480156103b9575f5ffd5b506103d460048036038101906103cf9190611680565b6109bf565b6040516103e191906116d8565b60405180910390f35b3480156103f5575f5ffd5b506103fe6104d8565b60405161040b91906116d8565b60405180910390f35b34801561041f575f5ffd5b5061043a60048036038101906104359190611924565b6109e1565b6040516104479190611700565b60405180910390f35b61046a60048036038101906104659190611985565b610a63565b60405161047791906116d8565b60405180910390f35b61049a60048036038101906104959190611985565b610a7d565b6040516104a791906116d8565b60405180910390f35b3480156104bb575f5ffd5b506104d660048036038101906104d1919061179d565b610a97565b005b5f5f905090565b6060600380546104ee906119f9565b80601f016020809104026020016040519081016040528092919081815260200182805461051a906119f9565b80156105655780601f1061053c57610100808354040283529160200191610565565b820191905f5260205f20905b81548152906001019060200180831161054857829003601f168201915b5050505050905090565b5f5f610579610b1b565b9050610586818585610b22565b600191505092915050565b5f600254905090565b5f5f6105a4610b1b565b90506105b1858285610b34565b6105bc858585610bc7565b60019150509392505050565b5f6012905090565b6105d8610cb7565b6105e28282610d3e565b5050565b60606106117f0000000000000000000000000000000000000000000000000000000000000000610dbd565b61063a7f0000000000000000000000000000000000000000000000000000000000000000610dbd565b6106637f0000000000000000000000000000000000000000000000000000000000000000610dbd565b60405160200161067593929190611aad565b604051602081830303815290604052905090565b5f5f5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b6106d6610cb7565b6106df5f610e87565b565b5f6106ea610f4a565b5f85859050905083839050811461072d576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f3490505f5f90505b828110156107e4575f86868381811061075257610751611af3565b5b90506020020135905082811115610795576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c38989848181106107ab576107aa611af3565b5b90506020028101906107bd9190611b24565b82610fd1565b6107d3575f9450505050506107ec565b808303925050806001019050610736565b506001925050505b949350505050565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f610825610f4a565b5f858590509050838390508114610868576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f3490505f5f90505b8281101561091f575f86868381811061088d5761088c611af3565b5b905060200201359050828111156108d0576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108fe8989848181106108e6576108e5611af3565b5b90506020028101906108f89190611b24565b82610fdc565b61090e575f945050505050610927565b808303925050806001019050610871565b506001925050505b949350505050565b60606004805461093e906119f9565b80601f016020809104026020016040519081016040528092919081815260200182805461096a906119f9565b80156109b55780601f1061098c576101008083540402835291602001916109b5565b820191905f5260205f20905b81548152906001019060200180831161099857829003601f168201915b5050505050905090565b5f5f6109c9610b1b565b90506109d6818585610bc7565b600191505092915050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b5f610a6c610f4a565b610a768234610fd1565b9050919050565b5f610a86610f4a565b610a908234610fdc565b9050919050565b610a9f610cb7565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610b0f575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401610b06919061190b565b60405180910390fd5b610b1881610e87565b50565b5f33905090565b610b2f8383836001611022565b505050565b5f610b3f84846109e1565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811015610bc15781811015610bb2578281836040517ffb8f41b2000000000000000000000000000000000000000000000000000000008152600401610ba993929190611b4c565b60405180910390fd5b610bc084848484035f611022565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610c37575f6040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401610c2e919061190b565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610ca7575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401610c9e919061190b565b60405180910390fd5b610cb28383836111f1565b505050565b610cbf610b1b565b73ffffffffffffffffffffffffffffffffffffffff16610cdd6107f4565b73ffffffffffffffffffffffffffffffffffffffff1614610d3c57610d00610b1b565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401610d33919061190b565b60405180910390fd5b565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610dae575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401610da5919061190b565b60405180910390fd5b610db95f83836111f1565b5050565b60605f6001610dcb8461140a565b0190505f8167ffffffffffffffff811115610de957610de8611b81565b5b6040519080825280601f01601f191660200182016040528015610e1b5781602001600182028036833780820191505090505b5090505f82602083010190505b600115610e7c578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581610e7157610e70611bae565b5b0494505f8503610e28575b819350505050919050565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610fcf576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f6001905092915050565b5f6110188360e0016020810190610ff3919061179d565b610ffb6105c8565b600a6110079190611d37565b600a6110139190611d81565b610d3e565b6001905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611092575f6040517fe602df05000000000000000000000000000000000000000000000000000000008152600401611089919061190b565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611102575f6040517f94280d620000000000000000000000000000000000000000000000000000000081526004016110f9919061190b565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208190555080156111eb578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516111e29190611700565b60405180910390a35b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611241578060025f8282546112359190611dc2565b9250508190555061130f565b5f5f5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050818110156112ca578381836040517fe450d38c0000000000000000000000000000000000000000000000000000000081526004016112c193929190611b4c565b60405180910390fd5b8181035f5f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611356578060025f82825403925050819055506113a0565b805f5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516113fd9190611700565b60405180910390a3505050565b5f5f5f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611466577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161145c5761145b611bae565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106114a3576d04ee2d6d415b85acef8100000000838161149957611498611bae565b5b0492506020810190505b662386f26fc1000083106114d257662386f26fc1000083816114c8576114c7611bae565b5b0492506010810190505b6305f5e10083106114fb576305f5e10083816114f1576114f0611bae565b5b0492506008810190505b612710831061152057612710838161151657611515611bae565b5b0492506004810190505b60648310611543576064838161153957611538611bae565b5b0492506002810190505b600a8310611552576001810190505b80915050919050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61159d8261155b565b6115a78185611565565b93506115b7818560208601611575565b6115c081611583565b840191505092915050565b5f6020820190508181035f8301526115e38184611593565b905092915050565b5f5ffd5b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61161c826115f3565b9050919050565b61162c81611612565b8114611636575f5ffd5b50565b5f8135905061164781611623565b92915050565b5f819050919050565b61165f8161164d565b8114611669575f5ffd5b50565b5f8135905061167a81611656565b92915050565b5f5f60408385031215611696576116956115eb565b5b5f6116a385828601611639565b92505060206116b48582860161166c565b9150509250929050565b5f8115159050919050565b6116d2816116be565b82525050565b5f6020820190506116eb5f8301846116c9565b92915050565b6116fa8161164d565b82525050565b5f6020820190506117135f8301846116f1565b92915050565b5f5f5f606084860312156117305761172f6115eb565b5b5f61173d86828701611639565b935050602061174e86828701611639565b925050604061175f8682870161166c565b9150509250925092565b5f60ff82169050919050565b61177e81611769565b82525050565b5f6020820190506117975f830184611775565b92915050565b5f602082840312156117b2576117b16115eb565b5b5f6117bf84828501611639565b91505092915050565b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f8401126117e9576117e86117c8565b5b8235905067ffffffffffffffff811115611806576118056117cc565b5b602083019150836020820283011115611822576118216117d0565b5b9250929050565b5f5f83601f84011261183e5761183d6117c8565b5b8235905067ffffffffffffffff81111561185b5761185a6117cc565b5b602083019150836020820283011115611877576118766117d0565b5b9250929050565b5f5f5f5f60408587031215611896576118956115eb565b5b5f85013567ffffffffffffffff8111156118b3576118b26115ef565b5b6118bf878288016117d4565b9450945050602085013567ffffffffffffffff8111156118e2576118e16115ef565b5b6118ee87828801611829565b925092505092959194509250565b61190581611612565b82525050565b5f60208201905061191e5f8301846118fc565b92915050565b5f5f6040838503121561193a576119396115eb565b5b5f61194785828601611639565b925050602061195885828601611639565b9150509250929050565b5f5ffd5b5f610140828403121561197c5761197b611962565b5b81905092915050565b5f6020828403121561199a576119996115eb565b5b5f82013567ffffffffffffffff8111156119b7576119b66115ef565b5b6119c384828501611966565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680611a1057607f821691505b602082108103611a2357611a226119cc565b5b50919050565b5f81905092915050565b5f611a3d8261155b565b611a478185611a29565b9350611a57818560208601611575565b80840191505092915050565b7f2e000000000000000000000000000000000000000000000000000000000000005f82015250565b5f611a97600183611a29565b9150611aa282611a63565b600182019050919050565b5f611ab88286611a33565b9150611ac382611a8b565b9150611acf8285611a33565b9150611ada82611a8b565b9150611ae68284611a33565b9150819050949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f5ffd5b5f8235600161014003833603038112611b4057611b3f611b20565b5b80830191505092915050565b5f606082019050611b5f5f8301866118fc565b611b6c60208301856116f1565b611b7960408301846116f1565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f8160011c9050919050565b5f5f8291508390505b6001851115611c5d57808604811115611c3957611c38611bdb565b5b6001851615611c485780820291505b8081029050611c5685611c08565b9450611c1d565b94509492505050565b5f82611c755760019050611d30565b81611c82575f9050611d30565b8160018114611c985760028114611ca257611cd1565b6001915050611d30565b60ff841115611cb457611cb3611bdb565b5b8360020a915084821115611ccb57611cca611bdb565b5b50611d30565b5060208310610133831016604e8410600b8410161715611d065782820a905083811115611d0157611d00611bdb565b5b611d30565b611d138484846001611c14565b92509050818404811115611d2a57611d29611bdb565b5b81810290505b9392505050565b5f611d418261164d565b9150611d4c83611769565b9250611d797fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484611c66565b905092915050565b5f611d8b8261164d565b9150611d968361164d565b9250828202611da48161164d565b91508282048414831517611dbb57611dba611bdb565b5b5092915050565b5f611dcc8261164d565b9150611dd78361164d565b9250828201905080821115611def57611dee611bdb565b5b9291505056000000000000000000000000b101275a60d8bfb14529c421899ad7ca1ae5b5fc", - "nonce": "0x11", + "input": "0x7468656775696c645f765f302e312e3000000000000000000000000000000000610100604052348015610010575f5ffd5b50604051612ba9380380612ba983398181016040528101906100329190610334565b80600160045f336040518060400160405280601581526020017f5468654775696c644163746976697479546f6b656e00000000000000000000008152506040518060400160405280600381526020017f544741000000000000000000000000000000000000000000000000000000000081525081600390816100b4919061059c565b5080600490816100c4919061059c565b5050505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610137575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161012e919061067a565b60405180910390fd5b6101468161020260201b60201c565b5082608081815250508160a081815250508060c081815250505050505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101c7576040517f83780ffe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660e08173ffffffffffffffffffffffffffffffffffffffff16815250505050610693565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6102f2826102c9565b9050919050565b5f610303826102e8565b9050919050565b610313816102f9565b811461031d575f5ffd5b50565b5f8151905061032e8161030a565b92915050565b5f60208284031215610349576103486102c5565b5b5f61035684828501610320565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806103da57607f821691505b6020821081036103ed576103ec610396565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261044f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610414565b6104598683610414565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61049d61049861049384610471565b61047a565b610471565b9050919050565b5f819050919050565b6104b683610483565b6104ca6104c2826104a4565b848454610420565b825550505050565b5f5f905090565b6104e16104d2565b6104ec8184846104ad565b505050565b5b8181101561050f576105045f826104d9565b6001810190506104f2565b5050565b601f82111561055457610525816103f3565b61052e84610405565b8101602085101561053d578190505b61055161054985610405565b8301826104f1565b50505b505050565b5f82821c905092915050565b5f6105745f1984600802610559565b1980831691505092915050565b5f61058c8383610565565b9150826002028217905092915050565b6105a58261035f565b67ffffffffffffffff8111156105be576105bd610369565b5b6105c882546103c3565b6105d3828285610513565b5f60209050601f831160018114610604575f84156105f2578287015190505b6105fc8582610581565b865550610663565b601f198416610612866103f3565b5f5b8281101561063957848901518255600182019150602085019450602081019050610614565b868310156106565784890151610652601f891682610565565b8355505b6001600288020188555050505b505050505050565b610674816102e8565b82525050565b5f60208201905061068d5f83018461066b565b92915050565b60805160a05160c05160e0516124dc6106cd5f395f8181610a51015261109a01525f6106bb01525f61069201525f61066901526124dc5ff3fe60806040526004361061012d575f3560e01c80638da5cb5b116100aa578063a9059cbb1161006e578063a9059cbb1461042a578063ce46e04614610466578063dd62ed3e14610490578063e49617e1146104cc578063e60c3505146104fc578063f2fde38b1461052c57610172565b80638da5cb5b1461034057806391db0b7e1461036a57806395d89b411461039a578063962ea8ae146103c45780639df97fd7146103ee57610172565b806340c10f19116100f157806340c10f191461026c57806354fd4d501461029457806370a08231146102be578063715018a6146102fa57806388e5b2d91461031057610172565b806306fdde0314610176578063095ea7b3146101a057806318160ddd146101dc57806323b872dd14610206578063313ce5671461024257610172565b366101725761013a610554565b610170576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b005b5f5ffd5b348015610181575f5ffd5b5061018a61055b565b60405161019791906117d8565b60405180910390f35b3480156101ab575f5ffd5b506101c660048036038101906101c19190611896565b6105eb565b6040516101d391906118ee565b60405180910390f35b3480156101e7575f5ffd5b506101f061060d565b6040516101fd9190611916565b60405180910390f35b348015610211575f5ffd5b5061022c6004803603810190610227919061192f565b610616565b60405161023991906118ee565b60405180910390f35b34801561024d575f5ffd5b50610256610644565b604051610263919061199a565b60405180910390f35b348015610277575f5ffd5b50610292600480360381019061028d9190611896565b61064c565b005b34801561029f575f5ffd5b506102a8610662565b6040516102b591906117d8565b60405180910390f35b3480156102c9575f5ffd5b506102e460048036038101906102df91906119b3565b610705565b6040516102f19190611916565b60405180910390f35b348015610305575f5ffd5b5061030e61074a565b005b61032a60048036038101906103259190611a94565b61075d565b60405161033791906118ee565b60405180910390f35b34801561034b575f5ffd5b50610354610870565b6040516103619190611b21565b60405180910390f35b610384600480360381019061037f9190611a94565b610898565b60405161039191906118ee565b60405180910390f35b3480156103a5575f5ffd5b506103ae6109ab565b6040516103bb91906117d8565b60405180910390f35b3480156103cf575f5ffd5b506103d8610a3b565b6040516103e59190611916565b60405180910390f35b3480156103f9575f5ffd5b50610414600480360381019061040f9190611b3a565b610a47565b6040516104219190611ce6565b60405180910390f35b348015610435575f5ffd5b50610450600480360381019061044b9190611896565b610b0d565b60405161045d91906118ee565b60405180910390f35b348015610471575f5ffd5b5061047a610554565b60405161048791906118ee565b60405180910390f35b34801561049b575f5ffd5b506104b660048036038101906104b19190611d06565b610b2f565b6040516104c39190611916565b60405180910390f35b6104e660048036038101906104e19190611d67565b610bb1565b6040516104f391906118ee565b60405180910390f35b61051660048036038101906105119190611d67565b610bcb565b60405161052391906118ee565b60405180910390f35b348015610537575f5ffd5b50610552600480360381019061054d91906119b3565b610be5565b005b5f5f905090565b60606003805461056a90611ddb565b80601f016020809104026020016040519081016040528092919081815260200182805461059690611ddb565b80156105e15780601f106105b8576101008083540402835291602001916105e1565b820191905f5260205f20905b8154815290600101906020018083116105c457829003601f168201915b5050505050905090565b5f5f6105f5610c69565b9050610602818585610c70565b600191505092915050565b5f600254905090565b5f5f610620610c69565b905061062d858285610c82565b610638858585610d15565b60019150509392505050565b5f6012905090565b610654610e05565b61065e8282610e8c565b5050565b606061068d7f0000000000000000000000000000000000000000000000000000000000000000610f0b565b6106b67f0000000000000000000000000000000000000000000000000000000000000000610f0b565b6106df7f0000000000000000000000000000000000000000000000000000000000000000610f0b565b6040516020016106f193929190611e8f565b604051602081830303815290604052905090565b5f5f5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b610752610e05565b61075b5f610fd5565b565b5f610766611098565b5f8585905090508383905081146107a9576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f3490505f5f90505b82811015610860575f8686838181106107ce576107cd611ed5565b5b90506020020135905082811115610811576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61083f89898481811061082757610826611ed5565b5b90506020028101906108399190611f06565b8261111f565b61084f575f945050505050610868565b8083039250508060010190506107b2565b506001925050505b949350505050565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f6108a1611098565b5f8585905090508383905081146108e4576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f3490505f5f90505b8281101561099b575f86868381811061090957610908611ed5565b5b9050602002013590508281111561094c576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61097a89898481811061096257610961611ed5565b5b90506020028101906109749190611f06565b8261112a565b61098a575f9450505050506109a3565b8083039250508060010190506108ed565b506001925050505b949350505050565b6060600480546109ba90611ddb565b80601f01602080910402602001604051908101604052809291908181526020018280546109e690611ddb565b8015610a315780601f10610a0857610100808354040283529160200191610a31565b820191905f5260205f20905b815481529060010190602001808311610a1457829003601f168201915b5050505050905090565b5f600680549050905090565b610a4f6116d2565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3112a6460068481548110610a9f57610a9e611ed5565b5b905f5260205f2001546040518263ffffffff1660e01b8152600401610ac49190611f3d565b5f60405180830381865afa158015610ade573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610b069190612219565b9050919050565b5f5f610b17610c69565b9050610b24818585610d15565b600191505092915050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b5f610bba611098565b610bc4823461111f565b9050919050565b5f610bd4611098565b610bde823461112a565b9050919050565b610bed610e05565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610c5d575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401610c549190611b21565b60405180910390fd5b610c6681610fd5565b50565b5f33905090565b610c7d8383836001611199565b505050565b5f610c8d8484610b2f565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811015610d0f5781811015610d00578281836040517ffb8f41b2000000000000000000000000000000000000000000000000000000008152600401610cf793929190612260565b60405180910390fd5b610d0e84848484035f611199565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610d85575f6040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401610d7c9190611b21565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610df5575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401610dec9190611b21565b60405180910390fd5b610e00838383611368565b505050565b610e0d610c69565b73ffffffffffffffffffffffffffffffffffffffff16610e2b610870565b73ffffffffffffffffffffffffffffffffffffffff1614610e8a57610e4e610c69565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401610e819190611b21565b60405180910390fd5b565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610efc575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401610ef39190611b21565b60405180910390fd5b610f075f8383611368565b5050565b60605f6001610f1984611581565b0190505f8167ffffffffffffffff811115610f3757610f36611f5a565b5b6040519080825280601f01601f191660200182016040528015610f695781602001600182028036833780820191505090505b5090505f82602083010190505b600115610fca578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581610fbf57610fbe612295565b5b0494505f8503610f76575b819350505050919050565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461111d576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f6001905092915050565b5f6111668360e001602081019061114191906119b3565b611149610644565b600a611155919061241e565b600a6111619190612468565b610e8c565b6006835f0135908060018154018082558091505060019003905f5260205f20015f90919091909150556001905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611209575f6040517fe602df050000000000000000000000000000000000000000000000000000000081526004016112009190611b21565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611279575f6040517f94280d620000000000000000000000000000000000000000000000000000000081526004016112709190611b21565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508015611362578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516113599190611916565b60405180910390a35b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036113b8578060025f8282546113ac91906124a9565b92505081905550611486565b5f5f5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015611441578381836040517fe450d38c00000000000000000000000000000000000000000000000000000000815260040161143893929190612260565b60405180910390fd5b8181035f5f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036114cd578060025f8282540392505081905550611517565b805f5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516115749190611916565b60405180910390a3505050565b5f5f5f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106115dd577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816115d3576115d2612295565b5b0492506040810190505b6d04ee2d6d415b85acef8100000000831061161a576d04ee2d6d415b85acef810000000083816116105761160f612295565b5b0492506020810190505b662386f26fc10000831061164957662386f26fc10000838161163f5761163e612295565b5b0492506010810190505b6305f5e1008310611672576305f5e100838161166857611667612295565b5b0492506008810190505b612710831061169757612710838161168d5761168c612295565b5b0492506004810190505b606483106116ba57606483816116b0576116af612295565b5b0492506002810190505b600a83106116c9576001810190505b80915050919050565b6040518061014001604052805f81526020015f81526020015f67ffffffffffffffff1681526020015f67ffffffffffffffff1681526020015f67ffffffffffffffff1681526020015f81526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f15158152602001606081525090565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6117aa82611768565b6117b48185611772565b93506117c4818560208601611782565b6117cd81611790565b840191505092915050565b5f6020820190508181035f8301526117f081846117a0565b905092915050565b5f604051905090565b5f5ffd5b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61183282611809565b9050919050565b61184281611828565b811461184c575f5ffd5b50565b5f8135905061185d81611839565b92915050565b5f819050919050565b61187581611863565b811461187f575f5ffd5b50565b5f813590506118908161186c565b92915050565b5f5f604083850312156118ac576118ab611801565b5b5f6118b98582860161184f565b92505060206118ca85828601611882565b9150509250929050565b5f8115159050919050565b6118e8816118d4565b82525050565b5f6020820190506119015f8301846118df565b92915050565b61191081611863565b82525050565b5f6020820190506119295f830184611907565b92915050565b5f5f5f6060848603121561194657611945611801565b5b5f6119538682870161184f565b93505060206119648682870161184f565b925050604061197586828701611882565b9150509250925092565b5f60ff82169050919050565b6119948161197f565b82525050565b5f6020820190506119ad5f83018461198b565b92915050565b5f602082840312156119c8576119c7611801565b5b5f6119d58482850161184f565b91505092915050565b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f8401126119ff576119fe6119de565b5b8235905067ffffffffffffffff811115611a1c57611a1b6119e2565b5b602083019150836020820283011115611a3857611a376119e6565b5b9250929050565b5f5f83601f840112611a5457611a536119de565b5b8235905067ffffffffffffffff811115611a7157611a706119e2565b5b602083019150836020820283011115611a8d57611a8c6119e6565b5b9250929050565b5f5f5f5f60408587031215611aac57611aab611801565b5b5f85013567ffffffffffffffff811115611ac957611ac8611805565b5b611ad5878288016119ea565b9450945050602085013567ffffffffffffffff811115611af857611af7611805565b5b611b0487828801611a3f565b925092505092959194509250565b611b1b81611828565b82525050565b5f602082019050611b345f830184611b12565b92915050565b5f60208284031215611b4f57611b4e611801565b5b5f611b5c84828501611882565b91505092915050565b5f819050919050565b611b7781611b65565b82525050565b5f67ffffffffffffffff82169050919050565b611b9981611b7d565b82525050565b611ba881611828565b82525050565b611bb7816118d4565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f611be182611bbd565b611beb8185611bc7565b9350611bfb818560208601611782565b611c0481611790565b840191505092915050565b5f61014083015f830151611c255f860182611b6e565b506020830151611c386020860182611b6e565b506040830151611c4b6040860182611b90565b506060830151611c5e6060860182611b90565b506080830151611c716080860182611b90565b5060a0830151611c8460a0860182611b6e565b5060c0830151611c9760c0860182611b9f565b5060e0830151611caa60e0860182611b9f565b50610100830151611cbf610100860182611bae565b50610120830151848203610120860152611cd98282611bd7565b9150508091505092915050565b5f6020820190508181035f830152611cfe8184611c0f565b905092915050565b5f5f60408385031215611d1c57611d1b611801565b5b5f611d298582860161184f565b9250506020611d3a8582860161184f565b9150509250929050565b5f5ffd5b5f6101408284031215611d5e57611d5d611d44565b5b81905092915050565b5f60208284031215611d7c57611d7b611801565b5b5f82013567ffffffffffffffff811115611d9957611d98611805565b5b611da584828501611d48565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680611df257607f821691505b602082108103611e0557611e04611dae565b5b50919050565b5f81905092915050565b5f611e1f82611768565b611e298185611e0b565b9350611e39818560208601611782565b80840191505092915050565b7f2e000000000000000000000000000000000000000000000000000000000000005f82015250565b5f611e79600183611e0b565b9150611e8482611e45565b600182019050919050565b5f611e9a8286611e15565b9150611ea582611e6d565b9150611eb18285611e15565b9150611ebc82611e6d565b9150611ec88284611e15565b9150819050949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f5ffd5b5f8235600161014003833603038112611f2257611f21611f02565b5b80830191505092915050565b611f3781611b65565b82525050565b5f602082019050611f505f830184611f2e565b92915050565b5f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611f9082611790565b810181811067ffffffffffffffff82111715611faf57611fae611f5a565b5b80604052505050565b5f611fc16117f8565b9050611fcd8282611f87565b919050565b5f5ffd5b611fdf81611b65565b8114611fe9575f5ffd5b50565b5f81519050611ffa81611fd6565b92915050565b61200981611b7d565b8114612013575f5ffd5b50565b5f8151905061202481612000565b92915050565b5f8151905061203881611839565b92915050565b612047816118d4565b8114612051575f5ffd5b50565b5f815190506120628161203e565b92915050565b5f5ffd5b5f67ffffffffffffffff82111561208657612085611f5a565b5b61208f82611790565b9050602081019050919050565b5f6120ae6120a98461206c565b611fb8565b9050828152602081018484840111156120ca576120c9612068565b5b6120d5848285611782565b509392505050565b5f82601f8301126120f1576120f06119de565b5b815161210184826020860161209c565b91505092915050565b5f61014082840312156121205761211f611f56565b5b61212b610140611fb8565b90505f61213a84828501611fec565b5f83015250602061214d84828501611fec565b602083015250604061216184828501612016565b604083015250606061217584828501612016565b606083015250608061218984828501612016565b60808301525060a061219d84828501611fec565b60a08301525060c06121b18482850161202a565b60c08301525060e06121c58482850161202a565b60e0830152506101006121da84828501612054565b6101008301525061012082015167ffffffffffffffff811115612200576121ff611fd2565b5b61220c848285016120dd565b6101208301525092915050565b5f6020828403121561222e5761222d611801565b5b5f82015167ffffffffffffffff81111561224b5761224a611805565b5b6122578482850161210a565b91505092915050565b5f6060820190506122735f830186611b12565b6122806020830185611907565b61228d6040830184611907565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f8160011c9050919050565b5f5f8291508390505b6001851115612344578086048111156123205761231f6122c2565b5b600185161561232f5780820291505b808102905061233d856122ef565b9450612304565b94509492505050565b5f8261235c5760019050612417565b81612369575f9050612417565b816001811461237f5760028114612389576123b8565b6001915050612417565b60ff84111561239b5761239a6122c2565b5b8360020a9150848211156123b2576123b16122c2565b5b50612417565b5060208310610133831016604e8410600b84101617156123ed5782820a9050838111156123e8576123e76122c2565b5b612417565b6123fa84848460016122fb565b92509050818404811115612411576124106122c2565b5b81810290505b9392505050565b5f61242882611863565b91506124338361197f565b92506124607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461234d565b905092915050565b5f61247282611863565b915061247d83611863565b925082820261248b81611863565b915082820484148315176124a2576124a16122c2565b5b5092915050565b5f6124b382611863565b91506124be83611863565b92508282019050808211156124d6576124d56122c2565b5b9291505056000000000000000000000000b101275a60d8bfb14529c421899ad7ca1ae5b5fc", + "nonce": "0x27", "chainId": "0x13882" }, "additionalContracts": [], "isFixedGasLimit": false }, { - "hash": "0x4a64d8c7e5b419a340eaee5bb14056c53d224cffa8f2ff1e5b297edba99ee82c", + "hash": "0x7d5238c11c298af09e2b184268e4ab0964c8a21cb016f35b884fff97766a178b", "transactionType": "CALL", "contractName": "SchemaRegistry", "contractAddress": "0x23c5701a1bda89c61d181bd79e5203c730708ae7", "function": "register(string,address,bool)", "arguments": [ "bytes32 badgeName, bytes32 justification", - "0x5a79Dd0F66E2C1203948dD49634E506b3D8723A0", + "0x5F0a5293E33AF3806ed34ba7DC139c8D3C39F310", "true" ], "transaction": { @@ -37,37 +37,37 @@ "to": "0x23c5701a1bda89c61d181bd79e5203c730708ae7", "gas": "0x31cee", "value": "0x0", - "input": "0x60d7a27800000000000000000000000000000000000000000000000000000000000000600000000000000000000000005a79dd0f66e2c1203948dd49634e506b3d8723a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000028627974657333322062616467654e616d652c2062797465733332206a757374696669636174696f6e000000000000000000000000000000000000000000000000", - "nonce": "0x12", + "input": "0x60d7a27800000000000000000000000000000000000000000000000000000000000000600000000000000000000000005f0a5293e33af3806ed34ba7dc139c8d3c39f31000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000028627974657333322062616467654e616d652c2062797465733332206a757374696669636174696f6e000000000000000000000000000000000000000000000000", + "nonce": "0x28", "chainId": "0x13882" }, "additionalContracts": [], "isFixedGasLimit": false }, { - "hash": "0x6dc1e766b179ba881ddeda4d2bb1347e4495b57fe3fac8195a2476a356221d3a", + "hash": "0xc92048394ac4d172b964527627701c0e3aa7679b02b5af7351a3b66894293b7b", "transactionType": "CREATE2", "contractName": "TheGuildBadgeRegistry", - "contractAddress": "0x8baa0d5135d241bd22a9eb35915300acfb286307", + "contractAddress": "0x7e67100ce4bc2640f50c47d2dd3eebc749d8f52e", "function": null, "arguments": null, "transaction": { "from": "0x6cfd0753ec4da15dcb418e11e921c0665c1d1cbf", "to": "0x4e59b44847b379578588920ca78fbf26c0b4956c", - "gas": "0xa326c", + "gas": "0xc0d11", "value": "0x0", - "input": "0x7468656775696c643200000000000000000000000000000000000000000000006080604052348015600e575f5ffd5b506107cc8061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610055575f3560e01c80633580dbc71461005957806338a699a41461007557806377002fcf146100a557806381407b1b146100d7578063a490a69714610107575b5f5ffd5b610073600480360381019061006e9190610499565b610125565b005b61008f600480360381019061008a91906104d7565b610309565b60405161009c919061051c565b60405180910390f35b6100bf60048036038101906100ba91906104d7565b61032f565b6040516100ce93929190610583565b60405180910390f35b6100f160048036038101906100ec91906105eb565b610431565b6040516100fe9190610616565b60405180910390f35b61010f610456565b60405161011c919061063e565b60405180910390f35b5f5f1b8203610169576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610160906106b1565b60405180910390fd5b60015f8381526020019081526020015f205f9054906101000a900460ff16156101c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101be90610719565b60405180910390fd5b5f60405180606001604052808481526020018381526020013373ffffffffffffffffffffffffffffffffffffffff168152509050805f5f8581526020019081526020015f205f820151815f0155602082015181600101556040820151816002015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050506001805f8581526020019081526020015f205f6101000a81548160ff021916908315150217905550600283908060018154018082558091505060019003905f5260205f20015f90919091909150553373ffffffffffffffffffffffffffffffffffffffff16837f7d648d3c718d609c93c086fd770653e10a64c5afe41e0b1b0b4bb76bba24c479846040516102fc9190610616565b60405180910390a3505050565b5f60015f8381526020019081526020015f205f9054906101000a900460ff169050919050565b5f5f5f60015f8581526020019081526020015f205f9054906101000a900460ff1661038f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161038690610781565b60405180910390fd5b5f5f5f8681526020019081526020015f206040518060600160405290815f820154815260200160018201548152602001600282015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050805f015181602001518260400151935093509350509193909250565b5f600282815481106104465761044561079f565b5b905f5260205f2001549050919050565b5f600280549050905090565b5f5ffd5b5f819050919050565b61047881610466565b8114610482575f5ffd5b50565b5f813590506104938161046f565b92915050565b5f5f604083850312156104af576104ae610462565b5b5f6104bc85828601610485565b92505060206104cd85828601610485565b9150509250929050565b5f602082840312156104ec576104eb610462565b5b5f6104f984828501610485565b91505092915050565b5f8115159050919050565b61051681610502565b82525050565b5f60208201905061052f5f83018461050d565b92915050565b61053e81610466565b82525050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61056d82610544565b9050919050565b61057d81610563565b82525050565b5f6060820190506105965f830186610535565b6105a36020830185610535565b6105b06040830184610574565b949350505050565b5f819050919050565b6105ca816105b8565b81146105d4575f5ffd5b50565b5f813590506105e5816105c1565b92915050565b5f60208284031215610600576105ff610462565b5b5f61060d848285016105d7565b91505092915050565b5f6020820190506106295f830184610535565b92915050565b610638816105b8565b82525050565b5f6020820190506106515f83018461062f565b92915050565b5f82825260208201905092915050565b7f454d5054595f4e414d45000000000000000000000000000000000000000000005f82015250565b5f61069b600a83610657565b91506106a682610667565b602082019050919050565b5f6020820190508181035f8301526106c88161068f565b9050919050565b7f4455504c49434154455f4e414d450000000000000000000000000000000000005f82015250565b5f610703600e83610657565b915061070e826106cf565b602082019050919050565b5f6020820190508181035f830152610730816106f7565b9050919050565b7f4e4f545f464f554e4400000000000000000000000000000000000000000000005f82015250565b5f61076b600983610657565b915061077682610737565b602082019050919050565b5f6020820190508181035f8301526107988161075f565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd", - "nonce": "0x13", + "input": "0x7468656775696c645f765f302e312e30000000000000000000000000000000006080604052348015600e575f5ffd5b506108cf8061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610060575f3560e01c80633580dbc71461006457806338a699a4146100805780634d3c901d146100b057806377002fcf146100e257806381407b1b14610114578063a490a69714610144575b5f5ffd5b61007e6004803603810190610079919061059c565b610162565b005b61009a600480360381019061009591906105da565b610346565b6040516100a7919061061f565b60405180910390f35b6100ca60048036038101906100c5919061066b565b61036c565b6040516100d9939291906106e4565b60405180910390f35b6100fc60048036038101906100f791906105da565b610432565b60405161010b939291906106e4565b60405180910390f35b61012e6004803603810190610129919061066b565b610534565b60405161013b9190610719565b60405180910390f35b61014c610559565b6040516101599190610741565b60405180910390f35b5f5f1b82036101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161019d906107b4565b60405180910390fd5b60015f8381526020019081526020015f205f9054906101000a900460ff1615610204576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101fb9061081c565b60405180910390fd5b5f60405180606001604052808481526020018381526020013373ffffffffffffffffffffffffffffffffffffffff168152509050805f5f8581526020019081526020015f205f820151815f0155602082015181600101556040820151816002015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050506001805f8581526020019081526020015f205f6101000a81548160ff021916908315150217905550600283908060018154018082558091505060019003905f5260205f20015f90919091909150553373ffffffffffffffffffffffffffffffffffffffff16837f7d648d3c718d609c93c086fd770653e10a64c5afe41e0b1b0b4bb76bba24c479846040516103399190610719565b60405180910390a3505050565b5f60015f8381526020019081526020015f205f9054906101000a900460ff169050919050565b5f5f5f5f600285815481106103845761038361083a565b5b905f5260205f20015490505f5f5f8381526020019081526020015f206040518060600160405290815f820154815260200160018201548152602001600282015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050805f01518160200151826040015194509450945050509193909250565b5f5f5f60015f8581526020019081526020015f205f9054906101000a900460ff16610492576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610489906108b1565b60405180910390fd5b5f5f5f8681526020019081526020015f206040518060600160405290815f820154815260200160018201548152602001600282015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050805f015181602001518260400151935093509350509193909250565b5f600282815481106105495761054861083a565b5b905f5260205f2001549050919050565b5f600280549050905090565b5f5ffd5b5f819050919050565b61057b81610569565b8114610585575f5ffd5b50565b5f8135905061059681610572565b92915050565b5f5f604083850312156105b2576105b1610565565b5b5f6105bf85828601610588565b92505060206105d085828601610588565b9150509250929050565b5f602082840312156105ef576105ee610565565b5b5f6105fc84828501610588565b91505092915050565b5f8115159050919050565b61061981610605565b82525050565b5f6020820190506106325f830184610610565b92915050565b5f819050919050565b61064a81610638565b8114610654575f5ffd5b50565b5f8135905061066581610641565b92915050565b5f602082840312156106805761067f610565565b5b5f61068d84828501610657565b91505092915050565b61069f81610569565b82525050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6106ce826106a5565b9050919050565b6106de816106c4565b82525050565b5f6060820190506106f75f830186610696565b6107046020830185610696565b61071160408301846106d5565b949350505050565b5f60208201905061072c5f830184610696565b92915050565b61073b81610638565b82525050565b5f6020820190506107545f830184610732565b92915050565b5f82825260208201905092915050565b7f454d5054595f4e414d45000000000000000000000000000000000000000000005f82015250565b5f61079e600a8361075a565b91506107a98261076a565b602082019050919050565b5f6020820190508181035f8301526107cb81610792565b9050919050565b7f4455504c49434154455f4e414d450000000000000000000000000000000000005f82015250565b5f610806600e8361075a565b9150610811826107d2565b602082019050919050565b5f6020820190508181035f830152610833816107fa565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e4f545f464f554e4400000000000000000000000000000000000000000000005f82015250565b5f61089b60098361075a565b91506108a682610867565b602082019050919050565b5f6020820190508181035f8301526108c88161088f565b905091905056", + "nonce": "0x29", "chainId": "0x13882" }, "additionalContracts": [], "isFixedGasLimit": false }, { - "hash": "0xeba257e3d5ed67d09c1209043bf0010ada86061d63a33986f17ef8fafa0df8a0", + "hash": "0x5cc04c09a8b590e4ec06b36340baf5f5eba420f48e8b6600e2d23b526140144c", "transactionType": "CALL", "contractName": "TheGuildBadgeRegistry", - "contractAddress": "0x8baa0d5135d241bd22a9eb35915300acfb286307", + "contractAddress": "0x7e67100ce4bc2640f50c47d2dd3eebc749d8f52e", "function": "createBadge(bytes32,bytes32)", "arguments": [ "0x5275737400000000000000000000000000000000000000000000000000000000", @@ -75,21 +75,21 @@ ], "transaction": { "from": "0x6cfd0753ec4da15dcb418e11e921c0665c1d1cbf", - "to": "0x8baa0d5135d241bd22a9eb35915300acfb286307", + "to": "0x7e67100ce4bc2640f50c47d2dd3eebc749d8f52e", "gas": "0x3842f", "value": "0x0", "input": "0x3580dbc752757374000000000000000000000000000000000000000000000000000000004b6e6f7720686f7720746f20636f646520696e20527573740000000000000000", - "nonce": "0x14", + "nonce": "0x2a", "chainId": "0x13882" }, "additionalContracts": [], "isFixedGasLimit": false }, { - "hash": "0x8dc93a2f50dfa31b95892d6f595d250b9acd3c746dfff6618bf152386ab08fd7", + "hash": "0x2a351c6313db82df93884241e47ce66703e68072962645aa11365f84a0b22fa5", "transactionType": "CALL", "contractName": "TheGuildBadgeRegistry", - "contractAddress": "0x8baa0d5135d241bd22a9eb35915300acfb286307", + "contractAddress": "0x7e67100ce4bc2640f50c47d2dd3eebc749d8f52e", "function": "createBadge(bytes32,bytes32)", "arguments": [ "0x536f6c6964697479000000000000000000000000000000000000000000000000", @@ -97,21 +97,21 @@ ], "transaction": { "from": "0x6cfd0753ec4da15dcb418e11e921c0665c1d1cbf", - "to": "0x8baa0d5135d241bd22a9eb35915300acfb286307", + "to": "0x7e67100ce4bc2640f50c47d2dd3eebc749d8f52e", "gas": "0x2f66d", "value": "0x0", "input": "0x3580dbc7536f6c69646974790000000000000000000000000000000000000000000000004b6e6f7720686f7720746f20636f646520696e20536f6c696469747900000000", - "nonce": "0x15", + "nonce": "0x2b", "chainId": "0x13882" }, "additionalContracts": [], "isFixedGasLimit": false }, { - "hash": "0xda89c7964ed4380d61507db18f476b797d8db6ef1ed299fefda188848e9bf9df", + "hash": "0x1d083ac00eff4ff1611a8a257537638ad5df64162429871bee9799f1fbb9bd5d", "transactionType": "CALL", "contractName": "TheGuildBadgeRegistry", - "contractAddress": "0x8baa0d5135d241bd22a9eb35915300acfb286307", + "contractAddress": "0x7e67100ce4bc2640f50c47d2dd3eebc749d8f52e", "function": "createBadge(bytes32,bytes32)", "arguments": [ "0x5479706553637269707400000000000000000000000000000000000000000000", @@ -119,32 +119,32 @@ ], "transaction": { "from": "0x6cfd0753ec4da15dcb418e11e921c0665c1d1cbf", - "to": "0x8baa0d5135d241bd22a9eb35915300acfb286307", + "to": "0x7e67100ce4bc2640f50c47d2dd3eebc749d8f52e", "gas": "0x2f6af", "value": "0x0", "input": "0x3580dbc754797065536372697074000000000000000000000000000000000000000000004b6e6f7720686f7720746f20636f646520696e20547970655363726970740000", - "nonce": "0x16", + "nonce": "0x2c", "chainId": "0x13882" }, "additionalContracts": [], "isFixedGasLimit": false }, { - "hash": "0x914c22bc3d75a60a2088d5672f6c04a76da28af0bdd832f6d05907697fdf9c05", + "hash": "0x03caf940c8741e272e5182b109d7504c3641522d7b6db3eace7e33d35322f4a0", "transactionType": "CALL", "contractName": "EAS", "contractAddress": "0xb101275a60d8bfb14529c421899ad7ca1ae5b5fc", "function": "attest((bytes32,(address,uint64,bool,bytes32,bytes,uint256)))", "arguments": [ - "(0x466295ad970fa5fc0742a99115a9002bdd1c3921574039fec2c24f8863c74470, (0x0000000000000000000000000000000000001234, 0, true, 0x0000000000000000000000000000000000000000000000000000000000000000, 0x5275737400000000000000000000000000000000000000000000000000000000536177207468656d20636f64696e6720696e2052757374000000000000000000, 0))" + "(0x7b0ac75049ac0cf0a8f6606194f9ff2b892bed81560a7d84d484f96c788042cc, (0x0000000000000000000000000000000000001234, 0, true, 0x0000000000000000000000000000000000000000000000000000000000000000, 0x5275737400000000000000000000000000000000000000000000000000000000536177207468656d20636f64696e6720696e2052757374000000000000000000, 0))" ], "transaction": { "from": "0x6cfd0753ec4da15dcb418e11e921c0665c1d1cbf", "to": "0xb101275a60d8bfb14529c421899ad7ca1ae5b5fc", - "gas": "0x5e152", + "gas": "0x6d0ad", "value": "0x0", - "input": "0xf17325e70000000000000000000000000000000000000000000000000000000000000020466295ad970fa5fc0742a99115a9002bdd1c3921574039fec2c24f8863c744700000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000123400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000405275737400000000000000000000000000000000000000000000000000000000536177207468656d20636f64696e6720696e2052757374000000000000000000", - "nonce": "0x17", + "input": "0xf17325e700000000000000000000000000000000000000000000000000000000000000207b0ac75049ac0cf0a8f6606194f9ff2b892bed81560a7d84d484f96c788042cc0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000123400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000405275737400000000000000000000000000000000000000000000000000000000536177207468656d20636f64696e6720696e2052757374000000000000000000", + "nonce": "0x2d", "chainId": "0x13882" }, "additionalContracts": [], @@ -154,21 +154,21 @@ "receipts": [ { "status": "0x1", - "cumulativeGasUsed": "0x1b8158", + "cumulativeGasUsed": "0x250ef2", "logs": [ { - "address": "0x5a79dd0f66e2c1203948dd49634e506b3d8723a0", + "address": "0x5f0a5293e33af3806ed34ba7dc139c8d3c39f310", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c" ], "data": "0x", - "blockHash": "0x63ca3700d3e0a8e33bd6fefd8f8470e1b437ca4ead38fb90f9ed1ab008bf09b1", - "blockNumber": "0x19166c2", - "transactionHash": "0x8a5c54d5296dcaa6a0b8964549e0a0b43e1e26d00882c41ac07133921c2cd9ec", - "transactionIndex": "0x0", - "logIndex": "0x0", + "blockHash": "0xefaab971a9fddfc2587cc91e5e1a7fe9e4ee2d6411073f0b65b774d208c85b19", + "blockNumber": "0x1938c90", + "transactionHash": "0x60ad89b3c639393b160bc1439f493636b52462a63b28e1c21314dda40b21a3da", + "transactionIndex": "0x2", + "logIndex": "0x7", "removed": false }, { @@ -179,44 +179,44 @@ "0x0000000000000000000000006cfd0753ec4da15dcb418e11e921c0665c1d1cbf", "0x0000000000000000000000007ee41d8a25641000661b1ef5e6ae8a00400466b0" ], - "data": "0x000000000000000000000000000000000000000000000000017bcd12e9768bc80000000000000000000000000000000000000000000000055c301826555993bd00000000000000000000000000000000000000000000001d05d6748ff3c43aaf0000000000000000000000000000000000000000000000055ab44b136be307f500000000000000000000000000000000000000000000001d075241a2dd3ac677", - "blockHash": "0x63ca3700d3e0a8e33bd6fefd8f8470e1b437ca4ead38fb90f9ed1ab008bf09b1", - "blockNumber": "0x19166c2", - "transactionHash": "0x8a5c54d5296dcaa6a0b8964549e0a0b43e1e26d00882c41ac07133921c2cd9ec", - "transactionIndex": "0x0", - "logIndex": "0x1", + "data": "0x00000000000000000000000000000000000000000000000001842ffbe368c71500000000000000000000000000000000000000000000000551332e1711c9ada700000000000000000000000000000000000000000000009ebb36526abcc902650000000000000000000000000000000000000000000000054faefe1b2e60e69200000000000000000000000000000000000000000000009ebcba8266a031c97a", + "blockHash": "0xefaab971a9fddfc2587cc91e5e1a7fe9e4ee2d6411073f0b65b774d208c85b19", + "blockNumber": "0x1938c90", + "transactionHash": "0x60ad89b3c639393b160bc1439f493636b52462a63b28e1c21314dda40b21a3da", + "transactionIndex": "0x2", + "logIndex": "0x8", "removed": false } ], - "logsBloom": "0x00000000000000000002000000000000000000000000000000800000000000000000000000000000000000010000000000008000000000000000000000000000000080000000000000000000000000840001000000000000000100000000000000000000020000000000000000000800000000000000000080000000000000400000000000000000020000000400000000000000001100000000000000000000200000000001000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000400000000000300000000020000000000000000000000000000000000080000000000000000000000000100000", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000000010000000000008000000000000000000000000000000000000000000000000000000000800001000000000000000100000000000000000000020000000000000000000800000000000000000080000000000000400000020000000000020000000400000000000000001100000000000000000000200040000001000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000400000000000300000000020000000000000000000000000000000000080000000000000000000000000110000", "type": "0x2", - "transactionHash": "0x8a5c54d5296dcaa6a0b8964549e0a0b43e1e26d00882c41ac07133921c2cd9ec", - "transactionIndex": "0x0", - "blockHash": "0x63ca3700d3e0a8e33bd6fefd8f8470e1b437ca4ead38fb90f9ed1ab008bf09b1", - "blockNumber": "0x19166c2", - "gasUsed": "0x1b8158", - "effectiveGasPrice": "0xdceed8f2a", + "transactionHash": "0x60ad89b3c639393b160bc1439f493636b52462a63b28e1c21314dda40b21a3da", + "transactionIndex": "0x2", + "blockHash": "0xefaab971a9fddfc2587cc91e5e1a7fe9e4ee2d6411073f0b65b774d208c85b19", + "blockNumber": "0x1938c90", + "gasUsed": "0x215855", + "effectiveGasPrice": "0xba43b7400", "from": "0x6cfd0753ec4da15dcb418e11e921c0665c1d1cbf", "to": "0x4e59b44847b379578588920ca78fbf26c0b4956c", - "contractAddress": "0x5a79dd0f66e2c1203948dd49634e506b3d8723a0" + "contractAddress": "0x5f0a5293e33af3806ed34ba7dc139c8d3c39f310" }, { "status": "0x1", - "cumulativeGasUsed": "0x1da241", + "cumulativeGasUsed": "0x35b2a7", "logs": [ { "address": "0x23c5701a1bda89c61d181bd79e5203c730708ae7", "topics": [ "0xd0b86852e21f9e5fa4bc3b0cff9757ffe243d50c4b43968a42202153d651ea5e", - "0x466295ad970fa5fc0742a99115a9002bdd1c3921574039fec2c24f8863c74470", + "0x7b0ac75049ac0cf0a8f6606194f9ff2b892bed81560a7d84d484f96c788042cc", "0x0000000000000000000000006cfd0753ec4da15dcb418e11e921c0665c1d1cbf" ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000020466295ad970fa5fc0742a99115a9002bdd1c3921574039fec2c24f8863c744700000000000000000000000005a79dd0f66e2c1203948dd49634e506b3d8723a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000028627974657333322062616467654e616d652c2062797465733332206a757374696669636174696f6e000000000000000000000000000000000000000000000000", - "blockHash": "0x63ca3700d3e0a8e33bd6fefd8f8470e1b437ca4ead38fb90f9ed1ab008bf09b1", - "blockNumber": "0x19166c2", - "transactionHash": "0x4a64d8c7e5b419a340eaee5bb14056c53d224cffa8f2ff1e5b297edba99ee82c", - "transactionIndex": "0x1", - "logIndex": "0x2", + "data": "0x00000000000000000000000000000000000000000000000000000000000000207b0ac75049ac0cf0a8f6606194f9ff2b892bed81560a7d84d484f96c788042cc0000000000000000000000005f0a5293e33af3806ed34ba7dc139c8d3c39f310000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000028627974657333322062616467654e616d652c2062797465733332206a757374696669636174696f6e000000000000000000000000000000000000000000000000", + "blockHash": "0xefaab971a9fddfc2587cc91e5e1a7fe9e4ee2d6411073f0b65b774d208c85b19", + "blockNumber": "0x1938c90", + "transactionHash": "0x7d5238c11c298af09e2b184268e4ab0964c8a21cb016f35b884fff97766a178b", + "transactionIndex": "0x4", + "logIndex": "0xb", "removed": false }, { @@ -227,30 +227,30 @@ "0x0000000000000000000000006cfd0753ec4da15dcb418e11e921c0665c1d1cbf", "0x0000000000000000000000007ee41d8a25641000661b1ef5e6ae8a00400466b0" ], - "data": "0x000000000000000000000000000000000000000000000000001d644a25ea73e30000000000000000000000000000000000000000000000055ab44b13651e334d00000000000000000000000000000000000000000000001d075241a2dd3ac6770000000000000000000000000000000000000000000000055a96e6c93f33bf6a00000000000000000000000000000000000000000000001d076fa5ed03253a5a", - "blockHash": "0x63ca3700d3e0a8e33bd6fefd8f8470e1b437ca4ead38fb90f9ed1ab008bf09b1", - "blockNumber": "0x19166c2", - "transactionHash": "0x4a64d8c7e5b419a340eaee5bb14056c53d224cffa8f2ff1e5b297edba99ee82c", - "transactionIndex": "0x1", - "logIndex": "0x3", + "data": "0x0000000000000000000000000000000000000000000000000018c796d0167aa90000000000000000000000000000000000000000000000054faefe1b262c29a700000000000000000000000000000000000000000000009ebd63705404e809460000000000000000000000000000000000000000000000054f9636845615aefe00000000000000000000000000000000000000000000009ebd7c37ead4fe83ef", + "blockHash": "0xefaab971a9fddfc2587cc91e5e1a7fe9e4ee2d6411073f0b65b774d208c85b19", + "blockNumber": "0x1938c90", + "transactionHash": "0x7d5238c11c298af09e2b184268e4ab0964c8a21cb016f35b884fff97766a178b", + "transactionIndex": "0x4", + "logIndex": "0xc", "removed": false } ], - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000800000000000000000000000000010000000000008000000000000020000000000000000004000040000000000000000000800000000000000000000100000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000020002000400000000000000000100800000000000000000200000000000000010000000000000000000000000000000000400000000004000000000000000000001000000000000000000400000000000300000000000000000000000000000000000000000000000000000000000000000000010100000", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000800000000000080000000000000010000000000008000000000000020000000000000000000000040000000000000000000800000000000000008000100000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000020002000400000000000000000100800000000000000000200000000000000010000000000000000000000000000000000000000000004000000000000000000001800000000000000000400000000000300000000000000000000000000000000000000000000000000000000000000000000000100000", "type": "0x2", - "transactionHash": "0x4a64d8c7e5b419a340eaee5bb14056c53d224cffa8f2ff1e5b297edba99ee82c", - "transactionIndex": "0x1", - "blockHash": "0x63ca3700d3e0a8e33bd6fefd8f8470e1b437ca4ead38fb90f9ed1ab008bf09b1", - "blockNumber": "0x19166c2", + "transactionHash": "0x7d5238c11c298af09e2b184268e4ab0964c8a21cb016f35b884fff97766a178b", + "transactionIndex": "0x4", + "blockHash": "0xefaab971a9fddfc2587cc91e5e1a7fe9e4ee2d6411073f0b65b774d208c85b19", + "blockNumber": "0x1938c90", "gasUsed": "0x220e9", - "effectiveGasPrice": "0xdceed8f2a", + "effectiveGasPrice": "0xba43b7400", "from": "0x6cfd0753ec4da15dcb418e11e921c0665c1d1cbf", "to": "0x23c5701a1bda89c61d181bd79e5203c730708ae7", "contractAddress": null }, { "status": "0x1", - "cumulativeGasUsed": "0x250428", + "cumulativeGasUsed": "0x3df01a", "logs": [ { "address": "0x0000000000000000000000000000000000001010", @@ -260,44 +260,44 @@ "0x0000000000000000000000006cfd0753ec4da15dcb418e11e921c0665c1d1cbf", "0x0000000000000000000000007ee41d8a25641000661b1ef5e6ae8a00400466b0" ], - "data": "0x0000000000000000000000000000000000000000000000000065f05ca3f0010d0000000000000000000000000000000000000000000000055a96e6c93eada61300000000000000000000000000000000000000000000001d076fa5ed03253a5a0000000000000000000000000000000000000000000000055a30f66c9abda50600000000000000000000000000000000000000000000001d07d59649a7153b67", - "blockHash": "0x63ca3700d3e0a8e33bd6fefd8f8470e1b437ca4ead38fb90f9ed1ab008bf09b1", - "blockNumber": "0x19166c2", - "transactionHash": "0x6dc1e766b179ba881ddeda4d2bb1347e4495b57fe3fac8195a2476a356221d3a", - "transactionIndex": "0x2", - "logIndex": "0x4", + "data": "0x000000000000000000000000000000000000000000000000005fed388f51fcb30000000000000000000000000000000000000000000000054f963684558f95a700000000000000000000000000000000000000000000009ebd7c37ead4fe83ef0000000000000000000000000000000000000000000000054f36494bc63d98f400000000000000000000000000000000000000000000009ebddc2523645080a2", + "blockHash": "0xefaab971a9fddfc2587cc91e5e1a7fe9e4ee2d6411073f0b65b774d208c85b19", + "blockNumber": "0x1938c90", + "transactionHash": "0xc92048394ac4d172b964527627701c0e3aa7679b02b5af7351a3b66894293b7b", + "transactionIndex": "0x5", + "logIndex": "0xd", "removed": false } ], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000020000000400000000000000000100000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000400000000000300000000000000000000000000000000000000000000000000000000000000000000000100000", "type": "0x2", - "transactionHash": "0x6dc1e766b179ba881ddeda4d2bb1347e4495b57fe3fac8195a2476a356221d3a", - "transactionIndex": "0x2", - "blockHash": "0x63ca3700d3e0a8e33bd6fefd8f8470e1b437ca4ead38fb90f9ed1ab008bf09b1", - "blockNumber": "0x19166c2", - "gasUsed": "0x761e7", - "effectiveGasPrice": "0xdceed8f2a", + "transactionHash": "0xc92048394ac4d172b964527627701c0e3aa7679b02b5af7351a3b66894293b7b", + "transactionIndex": "0x5", + "blockHash": "0xefaab971a9fddfc2587cc91e5e1a7fe9e4ee2d6411073f0b65b774d208c85b19", + "blockNumber": "0x1938c90", + "gasUsed": "0x83d73", + "effectiveGasPrice": "0xba43b7400", "from": "0x6cfd0753ec4da15dcb418e11e921c0665c1d1cbf", "to": "0x4e59b44847b379578588920ca78fbf26c0b4956c", - "contractAddress": "0x8baa0d5135d241bd22a9eb35915300acfb286307" + "contractAddress": "0x7e67100ce4bc2640f50c47d2dd3eebc749d8f52e" }, { "status": "0x1", - "cumulativeGasUsed": "0x276bab", + "cumulativeGasUsed": "0x40579d", "logs": [ { - "address": "0x8baa0d5135d241bd22a9eb35915300acfb286307", + "address": "0x7e67100ce4bc2640f50c47d2dd3eebc749d8f52e", "topics": [ "0x7d648d3c718d609c93c086fd770653e10a64c5afe41e0b1b0b4bb76bba24c479", "0x5275737400000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000006cfd0753ec4da15dcb418e11e921c0665c1d1cbf" ], "data": "0x4b6e6f7720686f7720746f20636f646520696e20527573740000000000000000", - "blockHash": "0x63ca3700d3e0a8e33bd6fefd8f8470e1b437ca4ead38fb90f9ed1ab008bf09b1", - "blockNumber": "0x19166c2", - "transactionHash": "0xeba257e3d5ed67d09c1209043bf0010ada86061d63a33986f17ef8fafa0df8a0", - "transactionIndex": "0x3", - "logIndex": "0x5", + "blockHash": "0xefaab971a9fddfc2587cc91e5e1a7fe9e4ee2d6411073f0b65b774d208c85b19", + "blockNumber": "0x1938c90", + "transactionHash": "0x5cc04c09a8b590e4ec06b36340baf5f5eba420f48e8b6600e2d23b526140144c", + "transactionIndex": "0x6", + "logIndex": "0xe", "removed": false }, { @@ -308,44 +308,44 @@ "0x0000000000000000000000006cfd0753ec4da15dcb418e11e921c0665c1d1cbf", "0x0000000000000000000000007ee41d8a25641000661b1ef5e6ae8a00400466b0" ], - "data": "0x0000000000000000000000000000000000000000000000000021332d95e6af410000000000000000000000000000000000000000000000055a30f66c98ec8d2d00000000000000000000000000000000000000000000001d07d59649a7153b670000000000000000000000000000000000000000000000055a0fc33f0305ddec00000000000000000000000000000000000000000000001d07f6c9773cfbeaa8", - "blockHash": "0x63ca3700d3e0a8e33bd6fefd8f8470e1b437ca4ead38fb90f9ed1ab008bf09b1", - "blockNumber": "0x19166c2", - "transactionHash": "0xeba257e3d5ed67d09c1209043bf0010ada86061d63a33986f17ef8fafa0df8a0", - "transactionIndex": "0x3", - "logIndex": "0x6", + "data": "0x000000000000000000000000000000000000000000000000001bfd7fdd80e2c30000000000000000000000000000000000000000000000054f36494bc43679a700000000000000000000000000000000000000000000009ebddc2523645080a20000000000000000000000000000000000000000000000054f1a4bcbe6b596e400000000000000000000000000000000000000000000009ebdf822a341d16365", + "blockHash": "0xefaab971a9fddfc2587cc91e5e1a7fe9e4ee2d6411073f0b65b774d208c85b19", + "blockNumber": "0x1938c90", + "transactionHash": "0x5cc04c09a8b590e4ec06b36340baf5f5eba420f48e8b6600e2d23b526140144c", + "transactionIndex": "0x6", + "logIndex": "0xf", "removed": false } ], - "logsBloom": "0x00000000000000000000000000000200000000000000000000000000000000000000000000002000000000010000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000001000000000000000000000000000020000000000000000000000080000000000000000001000000000000020000000400000000000000000100000000000000000000200000000000000000000000000000000000000040000000000000000001004000000000000000000001000000000000000008400000000000300000000000400000000000000000000000000000000000000000000000000000000000100000", + "logsBloom": "0x00000000000000000000000000000200000000000000000000000000000000000000000000000000000000010000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000001000000000000000000000000008020000000000000000000000080000000000000000001000000200000020000000400000000000000000100000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000201000000000000000008400000000000300000000000400000000000000000000000000000000000000000000000000000000000100000", "type": "0x2", - "transactionHash": "0xeba257e3d5ed67d09c1209043bf0010ada86061d63a33986f17ef8fafa0df8a0", - "transactionIndex": "0x3", - "blockHash": "0x63ca3700d3e0a8e33bd6fefd8f8470e1b437ca4ead38fb90f9ed1ab008bf09b1", - "blockNumber": "0x19166c2", + "transactionHash": "0x5cc04c09a8b590e4ec06b36340baf5f5eba420f48e8b6600e2d23b526140144c", + "transactionIndex": "0x6", + "blockHash": "0xefaab971a9fddfc2587cc91e5e1a7fe9e4ee2d6411073f0b65b774d208c85b19", + "blockNumber": "0x1938c90", "gasUsed": "0x26783", - "effectiveGasPrice": "0xdceed8f2a", + "effectiveGasPrice": "0xba43b7400", "from": "0x6cfd0753ec4da15dcb418e11e921c0665c1d1cbf", - "to": "0x8baa0d5135d241bd22a9eb35915300acfb286307", + "to": "0x7e67100ce4bc2640f50c47d2dd3eebc749d8f52e", "contractAddress": null }, { "status": "0x1", - "cumulativeGasUsed": "0x2990c2", + "cumulativeGasUsed": "0x427cb4", "logs": [ { - "address": "0x8baa0d5135d241bd22a9eb35915300acfb286307", + "address": "0x7e67100ce4bc2640f50c47d2dd3eebc749d8f52e", "topics": [ "0x7d648d3c718d609c93c086fd770653e10a64c5afe41e0b1b0b4bb76bba24c479", "0x536f6c6964697479000000000000000000000000000000000000000000000000", "0x0000000000000000000000006cfd0753ec4da15dcb418e11e921c0665c1d1cbf" ], "data": "0x4b6e6f7720686f7720746f20636f646520696e20536f6c696469747900000000", - "blockHash": "0x63ca3700d3e0a8e33bd6fefd8f8470e1b437ca4ead38fb90f9ed1ab008bf09b1", - "blockNumber": "0x19166c2", - "transactionHash": "0x8dc93a2f50dfa31b95892d6f595d250b9acd3c746dfff6618bf152386ab08fd7", - "transactionIndex": "0x4", - "logIndex": "0x7", + "blockHash": "0xefaab971a9fddfc2587cc91e5e1a7fe9e4ee2d6411073f0b65b774d208c85b19", + "blockNumber": "0x1938c90", + "transactionHash": "0x2a351c6313db82df93884241e47ce66703e68072962645aa11365f84a0b22fa5", + "transactionIndex": "0x7", + "logIndex": "0x10", "removed": false }, { @@ -356,44 +356,44 @@ "0x0000000000000000000000006cfd0753ec4da15dcb418e11e921c0665c1d1cbf", "0x0000000000000000000000007ee41d8a25641000661b1ef5e6ae8a00400466b0" ], - "data": "0x000000000000000000000000000000000000000000000000001d9e010ad5ce1d0000000000000000000000000000000000000000000000055a0fc33f026e64af00000000000000000000000000000000000000000000001d07f6c9773cfbeaa800000000000000000000000000000000000000000000000559f2253df798969200000000000000000000000000000000000000000000001d0814677847d1b8c5", - "blockHash": "0x63ca3700d3e0a8e33bd6fefd8f8470e1b437ca4ead38fb90f9ed1ab008bf09b1", - "blockNumber": "0x19166c2", - "transactionHash": "0x8dc93a2f50dfa31b95892d6f595d250b9acd3c746dfff6618bf152386ab08fd7", - "transactionIndex": "0x4", - "logIndex": "0x8", + "data": "0x0000000000000000000000000000000000000000000000000018f83f40944b570000000000000000000000000000000000000000000000054f1a4bcbe61e1da700000000000000000000000000000000000000000000009ebdf822a341d163650000000000000000000000000000000000000000000000054f01538ca589d25000000000000000000000000000000000000000000000009ebe111ae28265aebc", + "blockHash": "0xefaab971a9fddfc2587cc91e5e1a7fe9e4ee2d6411073f0b65b774d208c85b19", + "blockNumber": "0x1938c90", + "transactionHash": "0x2a351c6313db82df93884241e47ce66703e68072962645aa11365f84a0b22fa5", + "transactionIndex": "0x7", + "logIndex": "0x11", "removed": false } ], - "logsBloom": "0x00000000008000000000000000000200000000000000000000000000000000000000000000002000000000010000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000000000000000000000080000000000000000001000000000000020000000400000000000000000100000000000000000000200000000000000000000000000000000000000040000000000040000001004000000000000000000001000000000000000000400000000000300000000000400000040000000000000000000000000000000000000000000000000000100000", + "logsBloom": "0x00000000008000000000000000000200000000000000000000000000000000000000000000000000000000010000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000008000000000000000000000000080000000000000000001000000200000020000000400000000000000000100000000000000000000200000000000000000000000000000000000000000000000000040000000004000000000000000000201000000000000000000400000000000300000000000400000040000000000000000000000000000000000000000000000000000100000", "type": "0x2", - "transactionHash": "0x8dc93a2f50dfa31b95892d6f595d250b9acd3c746dfff6618bf152386ab08fd7", - "transactionIndex": "0x4", - "blockHash": "0x63ca3700d3e0a8e33bd6fefd8f8470e1b437ca4ead38fb90f9ed1ab008bf09b1", - "blockNumber": "0x19166c2", + "transactionHash": "0x2a351c6313db82df93884241e47ce66703e68072962645aa11365f84a0b22fa5", + "transactionIndex": "0x7", + "blockHash": "0xefaab971a9fddfc2587cc91e5e1a7fe9e4ee2d6411073f0b65b774d208c85b19", + "blockNumber": "0x1938c90", "gasUsed": "0x22517", - "effectiveGasPrice": "0xdceed8f2a", + "effectiveGasPrice": "0xba43b7400", "from": "0x6cfd0753ec4da15dcb418e11e921c0665c1d1cbf", - "to": "0x8baa0d5135d241bd22a9eb35915300acfb286307", + "to": "0x7e67100ce4bc2640f50c47d2dd3eebc749d8f52e", "contractAddress": null }, { "status": "0x1", - "cumulativeGasUsed": "0x2bb609", + "cumulativeGasUsed": "0x44a1fb", "logs": [ { - "address": "0x8baa0d5135d241bd22a9eb35915300acfb286307", + "address": "0x7e67100ce4bc2640f50c47d2dd3eebc749d8f52e", "topics": [ "0x7d648d3c718d609c93c086fd770653e10a64c5afe41e0b1b0b4bb76bba24c479", "0x5479706553637269707400000000000000000000000000000000000000000000", "0x0000000000000000000000006cfd0753ec4da15dcb418e11e921c0665c1d1cbf" ], "data": "0x4b6e6f7720686f7720746f20636f646520696e20547970655363726970740000", - "blockHash": "0x63ca3700d3e0a8e33bd6fefd8f8470e1b437ca4ead38fb90f9ed1ab008bf09b1", - "blockNumber": "0x19166c2", - "transactionHash": "0xda89c7964ed4380d61507db18f476b797d8db6ef1ed299fefda188848e9bf9df", - "transactionIndex": "0x5", - "logIndex": "0x9", + "blockHash": "0xefaab971a9fddfc2587cc91e5e1a7fe9e4ee2d6411073f0b65b774d208c85b19", + "blockNumber": "0x1938c90", + "transactionHash": "0x1d083ac00eff4ff1611a8a257537638ad5df64162429871bee9799f1fbb9bd5d", + "transactionIndex": "0x8", + "logIndex": "0x12", "removed": false }, { @@ -404,30 +404,30 @@ "0x0000000000000000000000006cfd0753ec4da15dcb418e11e921c0665c1d1cbf", "0x0000000000000000000000007ee41d8a25641000661b1ef5e6ae8a00400466b0" ], - "data": "0x000000000000000000000000000000000000000000000000001da097d7609a2d00000000000000000000000000000000000000000000000559f2253df71175e900000000000000000000000000000000000000000000001d0814677847d1b8c500000000000000000000000000000000000000000000000559d484a61fb0dbbc00000000000000000000000000000000000000000000001d083208101f3252f2", - "blockHash": "0x63ca3700d3e0a8e33bd6fefd8f8470e1b437ca4ead38fb90f9ed1ab008bf09b1", - "blockNumber": "0x19166c2", - "transactionHash": "0xda89c7964ed4380d61507db18f476b797d8db6ef1ed299fefda188848e9bf9df", - "transactionIndex": "0x5", - "logIndex": "0xa", + "data": "0x0000000000000000000000000000000000000000000000000018fa6e0bb9ff870000000000000000000000000000000000000000000000054f01538ca502b1a700000000000000000000000000000000000000000000009ebe111ae28265aebc0000000000000000000000000000000000000000000000054ee8591e9948b22000000000000000000000000000000000000000000000009ebe2a15508e1fae43", + "blockHash": "0xefaab971a9fddfc2587cc91e5e1a7fe9e4ee2d6411073f0b65b774d208c85b19", + "blockNumber": "0x1938c90", + "transactionHash": "0x1d083ac00eff4ff1611a8a257537638ad5df64162429871bee9799f1fbb9bd5d", + "transactionIndex": "0x8", + "logIndex": "0x13", "removed": false } ], - "logsBloom": "0x00000000000000000000000000000200000000000000000000000000000000000000000000002000000000010000000000008000000000000000000000000000000000000000000000000000000001800000000000000000000100000000000000000000000000000000000000000000002000000000000080000000000000000001000000000000020000000400000000000000000100000000000000000000200000000000000000000000000000000000000040000000000000000001004000000000000000000001000000000000000000400000004000300000000000400000000000000000000000000000000000000000000000000000000000100000", + "logsBloom": "0x00000000000000000000000000000200000000000000000000000000000000000000000000000000000000010000000000008000000000000000000000000000000000000000000000000000000001800000000000000000000100000000000000000000000000000000008000000000002000000000000080000000000000000001000000200000020000000400000000000000000100000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000201000000000000000000400000004000300000000000400000000000000000000000000000000000000000000000000000000000100000", "type": "0x2", - "transactionHash": "0xda89c7964ed4380d61507db18f476b797d8db6ef1ed299fefda188848e9bf9df", - "transactionIndex": "0x5", - "blockHash": "0x63ca3700d3e0a8e33bd6fefd8f8470e1b437ca4ead38fb90f9ed1ab008bf09b1", - "blockNumber": "0x19166c2", + "transactionHash": "0x1d083ac00eff4ff1611a8a257537638ad5df64162429871bee9799f1fbb9bd5d", + "transactionIndex": "0x8", + "blockHash": "0xefaab971a9fddfc2587cc91e5e1a7fe9e4ee2d6411073f0b65b774d208c85b19", + "blockNumber": "0x1938c90", "gasUsed": "0x22547", - "effectiveGasPrice": "0xdceed8f2a", + "effectiveGasPrice": "0xba43b7400", "from": "0x6cfd0753ec4da15dcb418e11e921c0665c1d1cbf", - "to": "0x8baa0d5135d241bd22a9eb35915300acfb286307", + "to": "0x7e67100ce4bc2640f50c47d2dd3eebc749d8f52e", "contractAddress": null }, { "status": "0x1", - "cumulativeGasUsed": "0x2ff7dd", + "cumulativeGasUsed": "0x499119", "logs": [ { "address": "0xb101275a60d8bfb14529c421899ad7ca1ae5b5fc", @@ -435,29 +435,29 @@ "0x8bf46bf4cfd674fa735a3d63ec1c9ad4153f033c290341f3a588b75685141b35", "0x0000000000000000000000000000000000000000000000000000000000001234", "0x0000000000000000000000006cfd0753ec4da15dcb418e11e921c0665c1d1cbf", - "0x466295ad970fa5fc0742a99115a9002bdd1c3921574039fec2c24f8863c74470" + "0x7b0ac75049ac0cf0a8f6606194f9ff2b892bed81560a7d84d484f96c788042cc" ], - "data": "0xcbb30ddddfefb9857dd186877a6b9c942db9178d057e4f830aae9d23f18046b1", - "blockHash": "0x63ca3700d3e0a8e33bd6fefd8f8470e1b437ca4ead38fb90f9ed1ab008bf09b1", - "blockNumber": "0x19166c2", - "transactionHash": "0x914c22bc3d75a60a2088d5672f6c04a76da28af0bdd832f6d05907697fdf9c05", - "transactionIndex": "0x6", - "logIndex": "0xb", + "data": "0x46085befe2fa38b8e4a986ea6b2d9b3a4a4d2664949f89bda14fbbb249b2c02d", + "blockHash": "0xefaab971a9fddfc2587cc91e5e1a7fe9e4ee2d6411073f0b65b774d208c85b19", + "blockNumber": "0x1938c90", + "transactionHash": "0x03caf940c8741e272e5182b109d7504c3641522d7b6db3eace7e33d35322f4a0", + "transactionIndex": "0x9", + "logIndex": "0x14", "removed": false }, { - "address": "0x5a79dd0f66e2c1203948dd49634e506b3d8723a0", + "address": "0x5f0a5293e33af3806ed34ba7dc139c8d3c39f310", "topics": [ "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000006cfd0753ec4da15dcb418e11e921c0665c1d1cbf" ], "data": "0x0000000000000000000000000000000000000000000000008ac7230489e80000", - "blockHash": "0x63ca3700d3e0a8e33bd6fefd8f8470e1b437ca4ead38fb90f9ed1ab008bf09b1", - "blockNumber": "0x19166c2", - "transactionHash": "0x914c22bc3d75a60a2088d5672f6c04a76da28af0bdd832f6d05907697fdf9c05", - "transactionIndex": "0x6", - "logIndex": "0xc", + "blockHash": "0xefaab971a9fddfc2587cc91e5e1a7fe9e4ee2d6411073f0b65b774d208c85b19", + "blockNumber": "0x1938c90", + "transactionHash": "0x03caf940c8741e272e5182b109d7504c3641522d7b6db3eace7e33d35322f4a0", + "transactionIndex": "0x9", + "logIndex": "0x15", "removed": false }, { @@ -468,23 +468,23 @@ "0x0000000000000000000000006cfd0753ec4da15dcb418e11e921c0665c1d1cbf", "0x0000000000000000000000007ee41d8a25641000661b1ef5e6ae8a00400466b0" ], - "data": "0x000000000000000000000000000000000000000000000000003ac8afe9b0059c00000000000000000000000000000000000000000000000559d484a61f29af4300000000000000000000000000000000000000000000001d083208101f3252f20000000000000000000000000000000000000000000000055999bbf63579a9a700000000000000000000000000000000000000000000001d086cd0c008e2588e", - "blockHash": "0x63ca3700d3e0a8e33bd6fefd8f8470e1b437ca4ead38fb90f9ed1ab008bf09b1", - "blockNumber": "0x19166c2", - "transactionHash": "0x914c22bc3d75a60a2088d5672f6c04a76da28af0bdd832f6d05907697fdf9c05", - "transactionIndex": "0x6", - "logIndex": "0xd", + "data": "0x0000000000000000000000000000000000000000000000000039709e8f0cbf9e0000000000000000000000000000000000000000000000054ee8591e98c185a700000000000000000000000000000000000000000000009ebe2a15508e1fae430000000000000000000000000000000000000000000000054eaee88009b4c60900000000000000000000000000000000000000000000009ebe6385ef1d2c6de1", + "blockHash": "0xefaab971a9fddfc2587cc91e5e1a7fe9e4ee2d6411073f0b65b774d208c85b19", + "blockNumber": "0x1938c90", + "transactionHash": "0x03caf940c8741e272e5182b109d7504c3641522d7b6db3eace7e33d35322f4a0", + "transactionIndex": "0x9", + "logIndex": "0x16", "removed": false } ], - "logsBloom": "0x00000000000000000002000040000000000000000000000000000000000008000000000000000000000000010000000000008000000000000000000000000000000084000000000000000009000000840000000000000000000100000000000000000000020000000000000000000800000000000000000080000010000000002000000000000000020000000400000000000000000100000000000200000000200000000000000000000000000000000000000010000000000400000000004000000002000000000001000000000000000000400004000000300000000020010000000000000000000000000000000000000000000000000000000010100004", + "logsBloom": "0x00000000000000000000000040000000000000000000000000000000000008000000000080000000000000010000000000008000000000000000000000000000000000000000000000000009000000800000000000000008000100000000000000000000020000000000000000000800000000000000000080000010000000002000020000000000020000000400000000000000000100000000000200000000200040000000000000000000000000000000000010000000000000000000004000000002000000000001800000000000000000400004000000300000000020010000000000000000000000000000000000000000000000000000000000110004", "type": "0x2", - "transactionHash": "0x914c22bc3d75a60a2088d5672f6c04a76da28af0bdd832f6d05907697fdf9c05", - "transactionIndex": "0x6", - "blockHash": "0x63ca3700d3e0a8e33bd6fefd8f8470e1b437ca4ead38fb90f9ed1ab008bf09b1", - "blockNumber": "0x19166c2", - "gasUsed": "0x441d4", - "effectiveGasPrice": "0xdceed8f2a", + "transactionHash": "0x03caf940c8741e272e5182b109d7504c3641522d7b6db3eace7e33d35322f4a0", + "transactionIndex": "0x9", + "blockHash": "0xefaab971a9fddfc2587cc91e5e1a7fe9e4ee2d6411073f0b65b774d208c85b19", + "blockNumber": "0x1938c90", + "gasUsed": "0x4ef1e", + "effectiveGasPrice": "0xba43b7400", "from": "0x6cfd0753ec4da15dcb418e11e921c0665c1d1cbf", "to": "0xb101275a60d8bfb14529c421899ad7ca1ae5b5fc", "contractAddress": null @@ -493,7 +493,7 @@ "libraries": [], "pending": [], "returns": {}, - "timestamp": 1757670047685, + "timestamp": 1757951555100, "chain": 80002, - "commit": "e036e5a" + "commit": "65abfb7" } \ No newline at end of file diff --git a/the-guild-smart-contracts/script/FullDeploymentScript.s.sol b/the-guild-smart-contracts/script/FullDeploymentScript.s.sol index 9236646..567deff 100644 --- a/the-guild-smart-contracts/script/FullDeploymentScript.s.sol +++ b/the-guild-smart-contracts/script/FullDeploymentScript.s.sol @@ -13,7 +13,7 @@ import {console} from "forge-std/console.sol"; contract FullDeploymentScript is Script { function run() public { EAS eas; - bytes32 salt = bytes32("theguild2"); + bytes32 salt = bytes32("theguild_v_0.1.0"); // EAS addresses per https://github.com/ethereum-attestation-service/eas-contracts deployments // Base mainnet (8453) and Base Goerli/Sepolia (84531/84532) use the canonical predeploy 0x...21 // Optimism mainnet (10) and OP Sepolia (11155420) also use canonical 0x...21 @@ -73,7 +73,8 @@ contract FullDeploymentScript is Script { // Create some attestations AttestationRequestData memory data = AttestationRequestData({ - recipient: address(0x1234), + // TheGuild test account + recipient: address(0x6cfD0753EC4da15Dcb418E11e921C0665c1d1cBf), expirationTime: 0, revocable: true, refUID: bytes32(0), diff --git a/the-guild-smart-contracts/src/TheGuildActivityToken.sol b/the-guild-smart-contracts/src/TheGuildActivityToken.sol index 118a649..783b93f 100644 --- a/the-guild-smart-contracts/src/TheGuildActivityToken.sol +++ b/the-guild-smart-contracts/src/TheGuildActivityToken.sol @@ -9,6 +9,11 @@ import {IEAS, Attestation} from "eas-contracts/IEAS.sol"; /// @title TheGuildActivityToken (TGA) /// @notice ERC20 that also serves as an EAS schema resolver; mints on attest. contract TheGuildActivityToken is ERC20, Ownable, SchemaResolver { + // enumerate attestation ids + bytes32[] private attestationIds; + + //IEAS private _eas; + constructor( IEAS eas ) @@ -28,6 +33,8 @@ contract TheGuildActivityToken is ERC20, Ownable, SchemaResolver { uint256 ) internal override returns (bool) { _mint(attestation.attester, 10 * (10 ** decimals())); + // TODO: get rid of this when we have our graphQL setup + attestationIds.push(attestation.uid); return true; } @@ -38,4 +45,18 @@ contract TheGuildActivityToken is ERC20, Ownable, SchemaResolver { ) internal pure override returns (bool) { return true; } + + // TODO: get rid of this when we have our graphQL setup + + /// @notice Get attestation count + function getAttestationCount() external view returns (uint256) { + return attestationIds.length; + } + + /// @notice Get attestation id at a specific index + function getAttestationAtIndex( + uint256 index + ) external view returns (Attestation memory) { + return _eas.getAttestation(attestationIds[index]); + } } From 3bfc3db492967586d26e91f840f76d4236d362a5 Mon Sep 17 00:00:00 2001 From: Antoine Estienne Date: Tue, 16 Sep 2025 12:00:04 +0200 Subject: [PATCH 15/18] refactor files in appropriate folders --- frontend/src/components/badges/BadgesList.tsx | 8 +- .../components/badges/CreateBadgeButton.tsx | 1 - .../profiles/AddAttestationDialog.tsx | 1 - ...fileButton.tsx => CreateProfileDialog.tsx} | 0 .../src/components/profiles/ProfilesList.tsx | 10 ++- frontend/src/components/ui/button.tsx | 18 ++--- frontend/src/components/ui/card.tsx | 20 ++--- frontend/src/components/ui/dialog.tsx | 2 +- frontend/src/components/ui/form.tsx | 77 ++++++++++--------- frontend/src/components/ui/input.tsx | 8 +- frontend/src/components/ui/label.tsx | 10 +-- frontend/src/components/ui/select.tsx | 32 ++++---- frontend/src/components/ui/separator.tsx | 10 +-- frontend/src/components/ui/sheet.tsx | 2 +- frontend/src/components/ui/sidebar.tsx | 2 +- frontend/src/components/ui/skeleton.tsx | 6 +- frontend/src/components/ui/tooltip.tsx | 16 ++-- .../attestations/use-create-attestation.ts | 44 ++--------- .../attestations/use-get-attestations.ts | 71 +---------------- frontend/src/hooks/badges/use-create-badge.ts | 22 +----- frontend/src/hooks/badges/use-get-badges.ts | 32 +------- .../src/hooks/profiles/use-create-profile.ts | 16 +--- .../src/hooks/profiles/use-delete-profile.ts | 14 ++-- .../src/hooks/profiles/use-get-profiles.ts | 22 ++---- .../src/hooks/profiles/use-update-profile.ts | 17 ++-- frontend/src/lib/abis/activityTokenAbi.ts | 35 +++++++++ frontend/src/lib/abis/easAbi.ts | 31 ++++++++ frontend/src/lib/constants/apiConstants.ts | 2 + frontend/src/lib/constants/badgeConstants.ts | 6 +- .../src/lib/constants/blockchainConstants.ts | 14 ++++ .../src/lib/constants/profileConstants.ts | 15 +--- frontend/src/lib/types/api.d.ts | 24 ++++++ frontend/src/lib/types/attestation.d.ts | 6 ++ frontend/src/lib/types/badges.d.ts | 4 + frontend/src/lib/types/profiles.d.ts | 23 ++++++ frontend/src/lib/utils/blockchainUtils.ts | 35 +++++++++ .../lib/{utils.ts => utils/tailwindUtils.ts} | 0 the-guild-smart-contracts/README.md | 8 +- 38 files changed, 327 insertions(+), 337 deletions(-) rename frontend/src/components/profiles/{CreateProfileButton.tsx => CreateProfileDialog.tsx} (100%) create mode 100644 frontend/src/lib/abis/activityTokenAbi.ts create mode 100644 frontend/src/lib/abis/easAbi.ts create mode 100644 frontend/src/lib/constants/apiConstants.ts create mode 100644 frontend/src/lib/constants/blockchainConstants.ts create mode 100644 frontend/src/lib/types/api.d.ts create mode 100644 frontend/src/lib/types/attestation.d.ts create mode 100644 frontend/src/lib/types/badges.d.ts create mode 100644 frontend/src/lib/types/profiles.d.ts create mode 100644 frontend/src/lib/utils/blockchainUtils.ts rename frontend/src/lib/{utils.ts => utils/tailwindUtils.ts} (100%) diff --git a/frontend/src/components/badges/BadgesList.tsx b/frontend/src/components/badges/BadgesList.tsx index ff2d4d1..c1ca6b5 100644 --- a/frontend/src/components/badges/BadgesList.tsx +++ b/frontend/src/components/badges/BadgesList.tsx @@ -9,9 +9,11 @@ import { CardTitle, } from "@/components/ui/card"; import { useGetBadges } from "@/hooks/badges/use-get-badges"; -import { HARD_CODED_BADGES, type Badge } from "@/lib/constants/badgeConstants"; +import { HARD_CODED_BADGES } from "@/lib/constants/badgeConstants"; +import type { Badge } from "@/lib/types/badges"; import { Search } from "lucide-react"; import { CreateBadgeButton } from "@/components/badges/CreateBadgeButton"; +import { Input } from "../ui/input"; export function BadgesList(): React.ReactElement { const { data, isLoading } = useGetBadges(); @@ -32,10 +34,10 @@ export function BadgesList(): React.ReactElement {
- setSearchQuery(e.target.value)} /> diff --git a/frontend/src/components/badges/CreateBadgeButton.tsx b/frontend/src/components/badges/CreateBadgeButton.tsx index 017d2f6..af1fa7d 100644 --- a/frontend/src/components/badges/CreateBadgeButton.tsx +++ b/frontend/src/components/badges/CreateBadgeButton.tsx @@ -23,7 +23,6 @@ import { import { useForm } from "react-hook-form"; import { z } from "zod"; import { zodResolver } from "@hookform/resolvers/zod"; -import { useQueryClient } from "@tanstack/react-query"; import { useGetBadges } from "@/hooks/badges/use-get-badges"; const formSchema = z.object({ diff --git a/frontend/src/components/profiles/AddAttestationDialog.tsx b/frontend/src/components/profiles/AddAttestationDialog.tsx index 86d6869..e5a2b4c 100644 --- a/frontend/src/components/profiles/AddAttestationDialog.tsx +++ b/frontend/src/components/profiles/AddAttestationDialog.tsx @@ -1,5 +1,4 @@ import { useEffect, useState } from "react"; -import { Plus } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Dialog, diff --git a/frontend/src/components/profiles/CreateProfileButton.tsx b/frontend/src/components/profiles/CreateProfileDialog.tsx similarity index 100% rename from frontend/src/components/profiles/CreateProfileButton.tsx rename to frontend/src/components/profiles/CreateProfileDialog.tsx diff --git a/frontend/src/components/profiles/ProfilesList.tsx b/frontend/src/components/profiles/ProfilesList.tsx index 181a9f0..a785dfc 100644 --- a/frontend/src/components/profiles/ProfilesList.tsx +++ b/frontend/src/components/profiles/ProfilesList.tsx @@ -1,10 +1,12 @@ import { ProfileCard } from "./ProfileCard"; import { Search } from "lucide-react"; -import { CreateProfileButton } from "./CreateProfileButton"; +import { CreateProfileButton } from "./CreateProfileDialog"; import { useGetProfiles } from "@/hooks/profiles/use-get-profiles"; -import { PROFILES, type Profile } from "@/lib/constants/profileConstants"; +import { PROFILES } from "@/lib/constants/profileConstants"; +import type { Profile } from "@/lib/types/profiles"; import { useMemo, useState } from "react"; import { useGetAttestations } from "@/hooks/attestations/use-get-attestations"; +import { Input } from "../ui/input"; export function ProfilesList() { const { data, isLoading, error } = useGetProfiles(); @@ -65,10 +67,10 @@ export function ProfilesList() {
- setSearchQuery(e.target.value)} /> diff --git a/frontend/src/components/ui/button.tsx b/frontend/src/components/ui/button.tsx index a2df8dc..87378da 100644 --- a/frontend/src/components/ui/button.tsx +++ b/frontend/src/components/ui/button.tsx @@ -1,8 +1,8 @@ -import * as React from "react" -import { Slot } from "@radix-ui/react-slot" -import { cva, type VariantProps } from "class-variance-authority" +import * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { cva, type VariantProps } from "class-variance-authority"; -import { cn } from "@/lib/utils" +import { cn } from "@/lib/utils/tailwindUtils"; const buttonVariants = cva( "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", @@ -33,7 +33,7 @@ const buttonVariants = cva( size: "default", }, } -) +); function Button({ className, @@ -43,9 +43,9 @@ function Button({ ...props }: React.ComponentProps<"button"> & VariantProps & { - asChild?: boolean + asChild?: boolean; }) { - const Comp = asChild ? Slot : "button" + const Comp = asChild ? Slot : "button"; return ( - ) + ); } -export { Button, buttonVariants } +export { Button, buttonVariants }; diff --git a/frontend/src/components/ui/card.tsx b/frontend/src/components/ui/card.tsx index d05bbc6..481f46b 100644 --- a/frontend/src/components/ui/card.tsx +++ b/frontend/src/components/ui/card.tsx @@ -1,6 +1,6 @@ -import * as React from "react" +import * as React from "react"; -import { cn } from "@/lib/utils" +import { cn } from "@/lib/utils/tailwindUtils"; function Card({ className, ...props }: React.ComponentProps<"div">) { return ( @@ -12,7 +12,7 @@ function Card({ className, ...props }: React.ComponentProps<"div">) { )} {...props} /> - ) + ); } function CardHeader({ className, ...props }: React.ComponentProps<"div">) { @@ -25,7 +25,7 @@ function CardHeader({ className, ...props }: React.ComponentProps<"div">) { )} {...props} /> - ) + ); } function CardTitle({ className, ...props }: React.ComponentProps<"div">) { @@ -35,7 +35,7 @@ function CardTitle({ className, ...props }: React.ComponentProps<"div">) { className={cn("leading-none font-semibold", className)} {...props} /> - ) + ); } function CardDescription({ className, ...props }: React.ComponentProps<"div">) { @@ -45,7 +45,7 @@ function CardDescription({ className, ...props }: React.ComponentProps<"div">) { className={cn("text-muted-foreground text-sm", className)} {...props} /> - ) + ); } function CardAction({ className, ...props }: React.ComponentProps<"div">) { @@ -58,7 +58,7 @@ function CardAction({ className, ...props }: React.ComponentProps<"div">) { )} {...props} /> - ) + ); } function CardContent({ className, ...props }: React.ComponentProps<"div">) { @@ -68,7 +68,7 @@ function CardContent({ className, ...props }: React.ComponentProps<"div">) { className={cn("px-6", className)} {...props} /> - ) + ); } function CardFooter({ className, ...props }: React.ComponentProps<"div">) { @@ -78,7 +78,7 @@ function CardFooter({ className, ...props }: React.ComponentProps<"div">) { className={cn("flex items-center px-6 [.border-t]:pt-6", className)} {...props} /> - ) + ); } export { @@ -89,4 +89,4 @@ export { CardAction, CardDescription, CardContent, -} +}; diff --git a/frontend/src/components/ui/dialog.tsx b/frontend/src/components/ui/dialog.tsx index bd0cd89..8534fdc 100644 --- a/frontend/src/components/ui/dialog.tsx +++ b/frontend/src/components/ui/dialog.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import * as DialogPrimitive from "@radix-ui/react-dialog"; import { XIcon } from "lucide-react"; -import { cn } from "@/lib/utils"; +import { cn } from "@/lib/utils/tailwindUtils"; function Dialog({ ...props diff --git a/frontend/src/components/ui/form.tsx b/frontend/src/components/ui/form.tsx index 524b986..694a4ed 100644 --- a/frontend/src/components/ui/form.tsx +++ b/frontend/src/components/ui/form.tsx @@ -1,8 +1,8 @@ -"use client" +"use client"; -import * as React from "react" -import * as LabelPrimitive from "@radix-ui/react-label" -import { Slot } from "@radix-ui/react-slot" +import * as React from "react"; +import * as LabelPrimitive from "@radix-ui/react-label"; +import { Slot } from "@radix-ui/react-slot"; import { Controller, FormProvider, @@ -11,23 +11,23 @@ import { type ControllerProps, type FieldPath, type FieldValues, -} from "react-hook-form" +} from "react-hook-form"; -import { cn } from "@/lib/utils" -import { Label } from "@/components/ui/label" +import { cn } from "@/lib/utils/tailwindUtils"; +import { Label } from "@/components/ui/label"; -const Form = FormProvider +const Form = FormProvider; type FormFieldContextValue< TFieldValues extends FieldValues = FieldValues, TName extends FieldPath = FieldPath, > = { - name: TName -} + name: TName; +}; const FormFieldContext = React.createContext( {} as FormFieldContextValue -) +); const FormField = < TFieldValues extends FieldValues = FieldValues, @@ -39,21 +39,21 @@ const FormField = < - ) -} + ); +}; const useFormField = () => { - const fieldContext = React.useContext(FormFieldContext) - const itemContext = React.useContext(FormItemContext) - const { getFieldState } = useFormContext() - const formState = useFormState({ name: fieldContext.name }) - const fieldState = getFieldState(fieldContext.name, formState) + const fieldContext = React.useContext(FormFieldContext); + const itemContext = React.useContext(FormItemContext); + const { getFieldState } = useFormContext(); + const formState = useFormState({ name: fieldContext.name }); + const fieldState = getFieldState(fieldContext.name, formState); if (!fieldContext) { - throw new Error("useFormField should be used within ") + throw new Error("useFormField should be used within "); } - const { id } = itemContext + const { id } = itemContext; return { id, @@ -62,19 +62,19 @@ const useFormField = () => { formDescriptionId: `${id}-form-item-description`, formMessageId: `${id}-form-item-message`, ...fieldState, - } -} + }; +}; type FormItemContextValue = { - id: string -} + id: string; +}; const FormItemContext = React.createContext( {} as FormItemContextValue -) +); function FormItem({ className, ...props }: React.ComponentProps<"div">) { - const id = React.useId() + const id = React.useId(); return ( @@ -84,14 +84,14 @@ function FormItem({ className, ...props }: React.ComponentProps<"div">) { {...props} /> - ) + ); } function FormLabel({ className, ...props }: React.ComponentProps) { - const { error, formItemId } = useFormField() + const { error, formItemId } = useFormField(); return (