Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat(maci-signup): implement signup with MACI and EAS #14

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ NEXT_PUBLIC_METADATA_SCHEMA=0xd00c966351896bd3dc37d22017bf1ef23165f859d7546a2aba
NEXT_PUBLIC_EAS_CONTRACT_ADDRESS=0x4200000000000000000000000000000000000021
NEXT_PUBLIC_EAS_SCHEMA_REGISTRY_ADDRESS=0x4200000000000000000000000000000000000020

# The address of a deployed MACI instance
NEXT_MACI_ADDRESS=""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this also be added to env.js?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessary, but recommended, because it can verify if it's configured correctly before running the app via a Zod schema. For example:

NEXT_PUBLIC_ADMIN_ADDRESSES: z.string().startsWith("0x"),


# ----------------------
# Advanced Configuration
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
"formidable": "^3.5.1",
"graphql-request": "^6.1.0",
"lucide-react": "^0.316.0",
"maci-cli": "0.0.0-ci.1ac55ff",
"maci-crypto": "0.0.0-ci.1003c10",
"maci-domainobjs": "0.0.0-ci.1003c10",
"next": "^14.1.0",
"next-auth": "^4.24.5",
"next-themes": "^0.2.1",
Expand Down
2,211 changes: 2,163 additions & 48 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions src/components/MaciSignup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Button } from "./ui/Button"
import { useEffect } from "react"
import { useAccount } from "wagmi"
import { useProfile } from "~/hooks/useProfile"

/**
* Signup to the MACI contract for voting
* @returns
*/
export const MaciSignup = () => {

const { address } = useAccount()
const profile = useProfile(address)

console.log("address", address)
console.log("profile", profile)

useEffect(() => {
const _getAttestations = async () => {
// const profile = useProfile(address) // Fetch the profile for the current Ethereum address
console.log("profile", profile.data)
}

_getAttestations()
}, [])

const signup = () => {
console.log("signup")

}

return (
<Button onClick={signup}>Signup to MACI</Button>
)
}
1 change: 1 addition & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const config = {
admins: (process.env.NEXT_PUBLIC_ADMIN_ADDRESSES ?? "").split(","),
network:
wagmiChains[process.env.NEXT_PUBLIC_CHAIN_NAME as keyof typeof wagmiChains],
maciAddress: process.env.MACI_ADDRESS!,
};

export const theme = {
Expand Down
2 changes: 2 additions & 0 deletions src/layouts/BaseLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useRouter } from "next/router";
import { metadata } from "~/config";
import { useTheme } from "next-themes";
import { Footer } from "~/components/Footer";
import { MaciSignup } from "~/components/MaciSignup";

const Context = createContext({ eligibilityCheck: false, showBallot: false });
export const useLayoutOptions = () => useContext(Context);
Expand Down Expand Up @@ -79,6 +80,7 @@ export const BaseLayout = ({
{header}
<div className="mx-auto w-full flex-1 pt-12 2xl:container md:flex">
{sidebar === "left" ? sidebarComponent : null}
<MaciSignup />
<div
className={clsx("w-full min-w-0 px-2 pb-24", {
["mx-auto max-w-5xl"]: !sidebar,
Expand Down
1 change: 1 addition & 0 deletions src/utils/fetchAttestations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ type Metadata = {
round: string;
type: string;
};

export function parseDecodedMetadata(json: string): Metadata {
const data = JSON.parse(json) as { name: string; value: { value: string } }[];
const metadata = data.reduce(
Expand Down
49 changes: 49 additions & 0 deletions src/utils/maci.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { signup } from "maci-cli";
import { useAccount } from "wagmi";
import { eas } from "~/config";
import { genRandomBabyJubValue } from "maci-crypto";
import { Keypair, PrivKey } from "maci-domainobjs";
import { config } from "~/config";
import { toBytes } from "viem";
import { useEthersSigner } from "~/hooks/useEthersSigner";

/**
* Signup to MACI
*/
export const maciSignup = async () => {
// get the ethereum address of the connected user
const { address } = useAccount();

// get the signer
const signer = useEthersSigner()

// generate the maci keypair from a signature
// 1. request signature

// 2. generate private key (mock for now)
const privateKey = new PrivKey(genRandomBabyJubValue());

// 3. generate keypair
const keypair = new Keypair(privateKey)

// 4. save them to local storage
localStorage.setItem("maciPrivateKey", privateKey.serialize());
localStorage.setItem("maciPublicKey", keypair.pubKey.serialize());

// 5. get the attestation and eas related data
const schema = eas.schemas.badgeholder;
const attester = eas.schemas.badgeholderAttester;
Comment on lines +34 to +35
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Badgeholder is the same as voter.
To verify if an address is an approved voter, you can use:

const { data: isApproved } = useApprovedVoter(address);

// and on server-side
const isApproved = await fetchApprovedVoter(address);

const attestation = "todo"

// 6. call the maci signup function
const stateIndex = await signup({
maciPubKey: keypair.pubKey.serialize(),
maciAddress: config.maciAddress,
sgDataArg: toBytes(attestation).toString(),
// for now we can leave out the initial voice credit proxy data
// signer to be added once new package is published
})

// 7. save the state index to local storage
localStorage.setItem("userStateIndex", stateIndex.toString());
}