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(backend): add attestation handler #37

Merged
merged 1 commit into from
Jul 1, 2024
Merged
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
96 changes: 96 additions & 0 deletions frontend/src/components/Attestations.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { Address, Avatar, Badge, Identity, Name, getAttestations } from "@coinbase/onchainkit/identity";
import { useEffect, useState } from "react";

import { base, baseSepolia } from 'wagmi/chains'
import LoadingIndicator from "./LoadingIndicator";
import Link from "next/link";

export default function Attestations({ queueIndex }: any) {
console.debug("Attestations");

console.debug("queueIndex:", queueIndex);

const [data, setData] = useState(null);

useEffect(() => {
fetch("https://base-sepolia.easscan.org/graphql", {
method: "POST",
headers: {
"content-type": "application/json"
},
body: JSON.stringify({
query: `
query AttestationsQuery {
attestations(where: {schemaId: {equals: "0x47ae9f9a75fc6f94927dfcabe6c68ecaad18b8e55db85911b91846017103387e"}}) {
id,
attester,
recipient,
time,
decodedDataJson
}
}
`
})
})
.then(response => response.json())
.then(result => {
console.debug("then");
console.debug("result.data:", result.data);
setData(result.data);
})
.catch(error => {
console.error("error:", error);
// TODO: Handle errors
});
Comment on lines +41 to +44
Copy link

Choose a reason for hiding this comment

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

Improve error handling in data fetching.

Consider adding user-friendly error messages and retry logic for better user experience.

-  // TODO: Handle errors
+  alert("Failed to fetch attestation data. Please try again later.");
+  // Optionally, implement retry logic here.
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.catch(error => {
console.error("error:", error);
// TODO: Handle errors
});
.catch(error => {
console.error("error:", error);
alert("Failed to fetch attestation data. Please try again later.");
// Optionally, implement retry logic here.
});

}, []);

if (!data) {
return <LoadingIndicator />
}

const attestationsData: any = data;
console.debug("attestationsData:", attestationsData);

if (!attestationsData.attestations) {
// TODO: Handle errors
}
Comment on lines +54 to +56
Copy link

Choose a reason for hiding this comment

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

Handle undefined attestationsData.attestations.

Ensure the component handles cases where attestationsData.attestations is undefined.

-  // TODO: Handle errors
+  return <div>No attestations found.</div>;
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!attestationsData.attestations) {
// TODO: Handle errors
}
if (!attestationsData.attestations) {
return <div>No attestations found.</div>;
}


// const EAS_SCHEMA_ID = "0x47ae9f9a75fc6f94927dfcabe6c68ecaad18b8e55db85911b91846017103387e";
// // const attestationOptions = {
// // schemas: [EAS_SCHEMA_ID]
// // };
// const attestations = getAttestations(address, baseSepolia);
// console.log("attestations:", attestations);
// return (
// <Identity
// address={address}
// schemaId="0x47ae9f9a75fc6f94927dfcabe6c68ecaad18b8e55db85911b91846017103387e"
// >
// <Avatar className="h-8 w-8 border-2 rounded-full" />
// <Name>
// <Badge />
// </Name>
// <Address />
// </Identity>
// )
Comment on lines +58 to +75
Copy link

Choose a reason for hiding this comment

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

Remove commented-out code.

Remove the commented-out code if it is not needed to keep the codebase clean.

-  // const EAS_SCHEMA_ID = "0x47ae9f9a75fc6f94927dfcabe6c68ecaad18b8e55db85911b91846017103387e";
-  // // const attestationOptions = {
-  // //     schemas: [EAS_SCHEMA_ID]
-  // // };
-  // const attestations = getAttestations(address, baseSepolia);
-  // console.log("attestations:", attestations);
-  // return (
-  //     <Identity
-  //         address={address}
-  //         schemaId="0x47ae9f9a75fc6f94927dfcabe6c68ecaad18b8e55db85911b91846017103387e"
-  //         >
-  //         <Avatar className="h-8 w-8 border-2 rounded-full" />
-  //         <Name>
-  //             <Badge />
-  //         </Name>
-  //         <Address />
-  //     </Identity>
-  // )
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// const EAS_SCHEMA_ID = "0x47ae9f9a75fc6f94927dfcabe6c68ecaad18b8e55db85911b91846017103387e";
// // const attestationOptions = {
// // schemas: [EAS_SCHEMA_ID]
// // };
// const attestations = getAttestations(address, baseSepolia);
// console.log("attestations:", attestations);
// return (
// <Identity
// address={address}
// schemaId="0x47ae9f9a75fc6f94927dfcabe6c68ecaad18b8e55db85911b91846017103387e"
// >
// <Avatar className="h-8 w-8 border-2 rounded-full" />
// <Name>
// <Badge />
// </Name>
// <Address />
// </Identity>
// )


return (
attestationsData.attestations.map((attestation: any, i: number) => {
return (
<div key={i} className="p-4 bg-zinc-50 dark:bg-zinc-900 rounded-lg">
<Name address={attestation.attester} />
<div className="mt-2">
{new Date(attestation.time * 1_000).toISOString().substring(0,10)} {new Date(attestation.time * 1_000).toISOString().substring(11,16)}
<Link href={`https://base-sepolia.easscan.org/attestation/view/${attestation.id}`} target="_blank" className="ml-2">↗</Link>
</div>
<div className="mt-2">
{/* {attestation.decodedDataJson.verified} */}
<span className="px-3 py-1 text-sm text-emerald-400 border-emerald-400 bg-emerald-800 border-2 rounded-2xl">
Verified✅
</span>
</div>
</div>
)
})
)
}
3 changes: 1 addition & 2 deletions frontend/src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import "@/styles/globals.css";
import type { AppProps } from "next/app";
import { WagmiProvider, createConfig, http } from "wagmi";
import { base, baseSepolia } from 'wagmi/chains'
// import { wagmiConfig } from "@/config";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { RainbowKitProvider, getDefaultConfig, darkTheme, connectorsForWallets } from "@rainbow-me/rainbowkit";
import { RainbowKitProvider, darkTheme, connectorsForWallets } from "@rainbow-me/rainbowkit";
import { metaMaskWallet, coinbaseWallet } from "@rainbow-me/rainbowkit/wallets";

// Rainbowkit 🌈
Expand Down
9 changes: 9 additions & 0 deletions frontend/src/pages/distributions/[queueNumber].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import MainHeader from "@/components/MainHeader";
import DistributionSummary from "@/components/DistributionSummary";
import Head from "next/head";
import { useRouter } from "next/router";
import Attestations from "@/components/Attestations";

export default function DistributionDetails() {
console.debug("DistributionDetails");
Expand Down Expand Up @@ -32,6 +33,14 @@ export default function DistributionDetails() {
<div className="mt-8 p-4 text-2xl bg-zinc-50 dark:bg-zinc-900 rounded-lg">
<DistributionSummary queueIndex={queueIndex} />
</div>

<h2 className="mt-8 text-2xl">
Attestations:
</h2>

<div className="mt-8 text-xl space-y-2">
<Attestations queueIndex={queueIndex} />
</div>
</main>
<MainFooter />
</>
Expand Down
Loading