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

add field based searching #5

Open
wants to merge 2 commits into
base: hackathon
Choose a base branch
from
Open
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
86 changes: 86 additions & 0 deletions pages/api/find.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { ComposeClient } from '@composedb/client';
import { RuntimeCompositeDefinition } from '@composedb/types';
import { NextApiRequest, NextApiResponse } from 'next';

import { definition } from '../../src/__generated__/definition.js';

export default async function listAttestations(
req: NextApiRequest,
res: NextApiResponse<any>
) {
//instantiate a composeDB client instance
const composeClient = new ComposeClient({
ceramic: 'http://localhost:7007',
definition: definition as RuntimeCompositeDefinition,
});


let filters: string[] = [];

if (req.body.context) {
filters.push(`data: {
context: {
contains: "${req.body.context}"
}
}`);
}

if (req.body.cid) {
filters.push(`data: {
researchObjectCID: {
equalTo: "${req.body.cid}"
}
}`);
}

let where = filters.join(',');

try {
console.log(req.body.account);
const data: any = await composeClient.executeQuery(`
query {
attestationIndex(filters: {

where: {
${where}
}
},
first: 100) {
edges {
node {
id
uid
schema
attester
verifyingContract
easVersion
version
chainId
types{
name
type
}
r
s
v
recipient
refUID
data{
isVettedResearchObject
context
researchObjectCID
}
time
}
}
}
}
`);
console.log("listAttestation: got data " + JSON.stringify(data));
return res.json(data);
} catch (err) {
res.json({
err,
});
}
}
161 changes: 161 additions & 0 deletions pages/search.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
"use client";
import React, { useEffect, useState } from "react";
import { networks } from "../utils/networks";
import { AttestationItem } from "../components/AttestationItem";
import { ResolvedAttestation } from "../utils/types";

export default function Home() {
const [account, setAccount] = useState("");
const [network, setNetwork] = useState("");
const [attestations, setAttestations] = useState<ResolvedAttestation[]>([]);
const [loading, setLoading] = useState(false);

const connectWallet = async () => {
try {
const { ethereum } = window;
if (!ethereum) {
alert("Get MetaMask -> https://metamask.io/");
return;
}
const accounts = await ethereum.request({
method: "eth_requestAccounts",
});
console.log("Connected", accounts[0]);
setAccount(accounts[0].toLowerCase());
} catch (error) {
console.log(error);
}
};

const handleChainChanged = (_chainId: string) => {
window.location.reload();
};

const checkIfWalletIsConnected = async () => {
const { ethereum } = window;
if (!ethereum) {
console.log("Make sure you have metamask!");
return;
} else {
console.log("We have the ethereum object", ethereum);
}
// Check if we're authorized to access the user's wallet
const accounts = await ethereum.request({ method: "eth_accounts" });
// Users can have multiple authorized accounts, we grab the first one if its there!
if (accounts.length !== 0) {
const acc = accounts[0];
console.log("Found an authorized account:", acc);
setAccount(acc.toLowerCase());
await getAtts()

} else {
console.log("No authorized account found");
}

const chainId: string = await ethereum.request({ method: "eth_chainId" });

// @ts-expect-error: Ignore the following line
setNetwork(networks[chainId]);
ethereum.on("chainChanged", handleChainChanged);
};

//method to get all attestations
async function getAtts() {
setLoading(true);
const requestBody = { account };
const requestOptions = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(requestBody),
};
const tmpAttestations = await fetch("/api/find", requestOptions)
.then((response) => response.json())
.then((data) => data);
setAttestations([]);

//exit call if no attestations are found
if (!account || !tmpAttestations.data) {
return;
}

//establish allRecords to check whether corresponding confirmations exist
const allRecords = tmpAttestations.data.attestationIndex.edges;
const addresses = new Set<string>();

allRecords.forEach((att: any) => {
const obj = att.node;
addresses.add(obj.attester);
addresses.add(obj.recipient);
});


const records: any[] = [];
allRecords.forEach((att: any) => {
const item = att.node;
//if confirm field contains an item, a confirmation has been found
if (att.node.confirm && att.node.confirm.edges.length) {
item.confirmation = true;
}
item.uid = att.node.uid;
item.currAccount = account;
records.push(item);
});
setAttestations([...attestations, ...records]);
console.log(records)
setLoading(false);
}


useEffect(() => {
checkIfWalletIsConnected();
}, [account]);

return (
<>
<div className="relative flex flex-1">
<div className="flex-center flex h-full flex-1 flex-col items-center justify-center text-center">
<div className="Container">
{account.length && (
<div className="right">
<img alt="Network logo" className="logo" src={"/ethlogo.png"} />
<p style={{ textAlign: "center" }}>
{" "}
Connected with: {account.slice(0, 6)}...{account.slice(-4)}{" "}
</p>
</div>
)}
<a
className="SubText"
href={"/"}
style={{
margin: "auto",
position: "relative",
textAlign: "center",
textDecoration: "none",
}}
>
Back home
</a>
<div className="GradientBar" />

<div className="NewConnection">Research Object Reviews.</div>
<div className="AttestationHolder">
<div className="WhiteBox">
{loading && <div>Loading...</div>}
{!loading && !attestations.length && <div>No one here</div>}
{attestations.length > 0 || loading ? (
attestations.map((attestation, i) => (
<AttestationItem key={i} data={attestation} />
))
) : (
<div></div>
)}
{!account && <button className="MetButton" onClick={async () => connectWallet()}>Connect Wallet</button>}
</div>
</div>
</div>
</div>
</div>
</>
);
}