Skip to content

Commit

Permalink
Merge pull request #33 from daqhris/cleanup-unnecessary-code
Browse files Browse the repository at this point in the history
Resolve missing semver/index.js and stage changes for push
  • Loading branch information
daqhris authored Aug 11, 2024
2 parents ad4d7cd + 0b7847b commit 4f40627
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 1,213 deletions.
4 changes: 1 addition & 3 deletions components/EventAttendanceVerification.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,7 @@ const EventAttendanceProof: React.FC<{ onVerified: () => void }> = ({ onVerified
setProofResult(`Proof successful! ${inputAddress} has attended an ETHGlobal event in Brussels.`);
onVerified();
} else {
setProofResult(
`Proof failed. No eligible POAPs found for ${inputAddress} at ETHGlobal events in Brussels.`,
);
setProofResult(`Proof failed. No eligible POAPs found for ${inputAddress} at ETHGlobal events in Brussels.`);
}
}, [poaps, inputAddress, onVerified, setProofResult]);

Expand Down
45 changes: 25 additions & 20 deletions components/OnchainAttestation.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { useState } from "react";
import type { POAPEvent } from "./EventAttendanceVerification"; // Corrected import
import { EAS, SchemaEncoder } from "@ethereum-attestation-service/eas-sdk";
import { ethers } from "ethers";
import { BrowserProvider } from "ethers";
import { useAccount } from "wagmi";

// This component uses the Ethereum Attestation Service (EAS) protocol
Expand All @@ -17,7 +16,13 @@ const ATTESTER_NAME = "daqhris.eth";

interface OnchainAttestationProps {
onAttestationComplete: () => void;
poaps: POAPEvent[];
poaps: Array<{
event: {
name: string;
start_date: string;
};
tokenId: string;
}>;
}

const OnchainAttestation: React.FC<OnchainAttestationProps> = ({ onAttestationComplete, poaps }) => {
Expand All @@ -36,18 +41,13 @@ const OnchainAttestation: React.FC<OnchainAttestationProps> = ({ onAttestationCo
setAttestationStatus("Initiating attestation...");

try {
// Initialize EAS SDK
const eas = new EAS(EAS_CONTRACT_ADDRESS);

// Connect to the provider (assuming MetaMask is connected)
// @ts-ignore
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
const provider = new BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
eas.connect(signer);

// Encode the attestation data
const schemaEncoder = new SchemaEncoder(
"address recipient,uint256 tokenId,string eventName,uint256 timestamp,string rollup,string attester",
"address recipient,uint256 tokenId,string eventName,uint256 timestamp,string rollup,string attester"
);
const poapData = poaps[0]; // Assuming we're using the first POAP for simplicity
const encodedData = schemaEncoder.encodeData([
Expand All @@ -59,7 +59,6 @@ const OnchainAttestation: React.FC<OnchainAttestationProps> = ({ onAttestationCo
{ name: "attester", value: ATTESTER_NAME, type: "string" },
]);

// Create the attestation
const tx = await eas.attest({
schema: SCHEMA_UID,
data: {
Expand All @@ -72,7 +71,9 @@ const OnchainAttestation: React.FC<OnchainAttestationProps> = ({ onAttestationCo

const newAttestationUID = await tx.wait();

setAttestationStatus(`Attestation created successfully on ${selectedRollup}. UID: ${newAttestationUID}`);
setAttestationStatus(
`Attestation created successfully on ${selectedRollup}. UID: ${newAttestationUID}`
);
onAttestationComplete();
} catch (error) {
console.error("Attestation error:", error);
Expand All @@ -86,7 +87,8 @@ const OnchainAttestation: React.FC<OnchainAttestationProps> = ({ onAttestationCo
<div className="p-4 bg-white shadow rounded-lg">
<h2 className="text-2xl font-bold mb-4">Onchain Attestation</h2>
<p className="mb-4">
Receive an onchain attestation for completing the mission using the Ethereum Attestation Service (EAS) protocol:
Receive an onchain attestation for completing the mission using the
Ethereum Attestation Service (EAS) protocol:
</p>
<div className="mb-4">
<label htmlFor="rollup" className="block mb-2 font-semibold">
Expand All @@ -95,38 +97,41 @@ const OnchainAttestation: React.FC<OnchainAttestationProps> = ({ onAttestationCo
<select
id="rollup"
value={selectedRollup}
onChange={e => setSelectedRollup(e.target.value as "base" | "optimism")}
onChange={(e) => setSelectedRollup(e.target.value as "base" | "optimism")}
className="w-full p-2 border rounded"
>
<option value="base">Base (Ethereum L2 Rollup)</option>
<option value="optimism">Optimism (Ethereum L2 Rollup)</option>
</select>
<p className="mt-2 text-sm text-gray-600">
Your attestation will be created on the selected rollup, leveraging its scalability and lower transaction costs.
Your attestation will be created on the selected rollup, leveraging
its scalability and lower transaction costs.
</p>
</div>
{poaps.length > 0 && (
<div className="mb-4">
<h3 className="text-lg font-semibold">POAP Data for Attestation:</h3>
<ul className="list-disc pl-5">
{poaps.map(poap => (
{poaps.map((poap) => (
<li key={poap.tokenId}>
{poap.event.name} - {new Date(poap.event.start_date).toLocaleDateString()}
</li>
))}
</ul>
<p className="mt-2 text-sm text-gray-600">
This POAP data will be included in your onchain attestation as proof of your event attendance.
This POAP data will be included in your onchain attestation as proof
of your event attendance.
</p>
</div>
)}
<div className="mb-4">
<h3 className="text-lg font-semibold">Attestation Details:</h3>
<p className="mb-2">
<span className="font-semibold">Attester's onchain name:</span> {ATTESTER_NAME}
<span className="font-semibold">Attester&apos;s onchain name:</span> {ATTESTER_NAME}
</p>
<p className="text-sm text-gray-600">
The attestation will be created by {ATTESTER_NAME} using the Ethereum Attestation Service protocol on the selected rollup.
The attestation will be created by {ATTESTER_NAME} using the Ethereum
Attestation Service protocol on the selected rollup.
</p>
</div>
<button
Expand Down
5 changes: 0 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
},
"dependencies": {
"@apollo/client": "^3.11.3",
"@chainlink/contracts": "^1.2.0",
"@chainlink/contracts-ccip": "^1.4.0",
"@ensdomains/ens-contracts": "file:./package",
"@ensdomains/ensjs": "^4.0.0",
"@ethereum-attestation-service/eas-sdk": "2.5.0",
Expand All @@ -29,11 +27,8 @@
"@tanstack/react-query": "^5.51.23",
"@tanstack/react-query-devtools": "^5.51.21",
"@testing-library/dom": "^10.4.0",
"@uniswap/sdk-core": "^4.0.1",
"@uniswap/v2-sdk": "^3.0.1",
"axios": "^1.7.3",
"blo": "^1.0.1",
"burner-connector": "^0.0.8",
"daisyui": "4.5.0",
"ethers": "6.13.2",
"express": "^4.19.2",
Expand Down
36 changes: 28 additions & 8 deletions pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ import OnchainAttestation from "../components/OnchainAttestation";
const stages = ["identity", "attendance", "attestation", "complete"] as const;
type Stage = (typeof stages)[number];

interface POAPEvent {
event: {
name: string;
start_date: string;
};
tokenId: string;
}

const stageDescriptions = {
identity: "Verify your identity using ENS or Ethereum address",
attendance: "Confirm your attendance proof for ETHGlobal Brussels 2024",
Expand All @@ -15,8 +23,9 @@ const stageDescriptions = {
};

const Home: React.FC = () => {
const [currentStage, setCurrentStage] = useLocalStorage<Stage>("currentStage", "identity");
const [completedStages, setCompletedStages] = useLocalStorage<Stage[]>("completedStages", []);
const [currentStage, setCurrentStage] = useState<Stage>("identity");
const [completedStages, setCompletedStages] = useState<Stage[]>([]);
const [poaps] = useState<POAPEvent[]>([]);

useEffect(() => {
if (completedStages.length === 0 && currentStage !== "identity") {
Expand Down Expand Up @@ -45,15 +54,23 @@ const Home: React.FC = () => {
const renderCurrentStage = () => {
switch (currentStage) {
case "identity":
return <IdentityVerification onVerified={() => handleStageCompletion("identity")} />;
case "attendance":
return (
<IdentityVerification
onVerified={() => handleStageCompletion("identity")}
<EventAttendanceVerification
onVerified={() => {
// We'll handle setting POAPs in the component itself
handleStageCompletion("attendance");
}}
/>
);
case "attendance":
return <EventAttendanceProof onVerified={() => handleStageCompletion("attendance")} />;
case "attestation":
return <OnchainAttestation onAttestationComplete={() => handleStageCompletion("attestation")} />;
return (
<OnchainAttestation
onAttestationComplete={() => handleStageCompletion("attestation")}
poaps={poaps}
/>
);
case "complete":
return (
<div className="p-4 bg-white shadow rounded-lg">
Expand All @@ -70,9 +87,12 @@ const Home: React.FC = () => {
<div className="container mx-auto px-4 py-8">
<h1 className="text-3xl font-bold mb-8">Mission Enrollment 2024</h1>
<div className="mb-8 p-4 bg-blue-100 rounded-lg">
<h2 className="text-xl font-semibold mb-2">Current Stage: {currentStage.charAt(0).toUpperCase() + currentStage.slice(1)}</h2>
<h2 className="text-xl font-semibold mb-2">
Current Stage: {currentStage.charAt(0).toUpperCase() + currentStage.slice(1)}
</h2>
<p className="text-lg">{stageDescriptions[currentStage]}</p>
<p className="mt-2 text-sm text-blue-700">Complete this stage to proceed to the next step of your mission enrollment.</p>

</div>
{renderCurrentStage()}
<div className="mt-8">
Expand Down
6 changes: 1 addition & 5 deletions services/web3/wagmiConnectors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ import {
safeWallet,
walletConnectWallet,
} from "@rainbow-me/rainbowkit/wallets";
import { rainbowkitBurnerWallet } from "burner-connector";
import * as chains from "viem/chains";
import scaffoldConfig from "~~/scaffold.config";

const { onlyLocalBurnerWallet, targetNetworks } = scaffoldConfig;
const { targetNetworks } = scaffoldConfig;

const wallets = [
metaMaskWallet,
Expand All @@ -20,9 +19,6 @@ const wallets = [
coinbaseWallet,
rainbowWallet,
safeWallet,
...(!targetNetworks.some(network => network.id !== (chains.hardhat as chains.Chain).id) || !onlyLocalBurnerWallet
? [rainbowkitBurnerWallet]
: []),
];

/**
Expand Down
63 changes: 33 additions & 30 deletions utils/scaffold-eth/fetchPriceFromUniswap.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { ChainWithAttributes, getAlchemyHttpUrl } from "./networks";
import { CurrencyAmount, Token } from "@uniswap/sdk-core";
import { Pair, Route } from "@uniswap/v2-sdk";
import { Address, createPublicClient, http, parseAbi } from "viem";
import { mainnet } from "viem/chains";

Expand All @@ -15,6 +13,9 @@ const ABI = parseAbi([
"function token1() external view returns (address)",
]);

const DAI_ADDRESS = "0x6B175474E89094C44Da98b954EedeAC495271d0F";
const WETH_ADDRESS = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";

export const fetchPriceFromUniswap = async (targetNetwork: ChainWithAttributes): Promise<number> => {
if (
targetNetwork.nativeCurrency.symbol !== "ETH" &&
Expand All @@ -24,42 +25,30 @@ export const fetchPriceFromUniswap = async (targetNetwork: ChainWithAttributes):
return 0;
}
try {
const DAI = new Token(1, "0x6B175474E89094C44Da98b954EedeAC495271d0F", 18);
const TOKEN = new Token(
1,
targetNetwork.nativeCurrencyTokenAddress || "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
18,
);
const pairAddress = Pair.getAddress(TOKEN, DAI) as Address;
const tokenAddress = targetNetwork.nativeCurrencyTokenAddress || WETH_ADDRESS;
const pairAddress = computePairAddress(tokenAddress, DAI_ADDRESS);

const wagmiConfig = {
address: pairAddress,
abi: ABI,
};

const reserves = await publicClient.readContract({
...wagmiConfig,
functionName: "getReserves",
});
const [reserves, token0Address] = await Promise.all([
publicClient.readContract({
...wagmiConfig,
functionName: "getReserves",
}),
publicClient.readContract({
...wagmiConfig,
functionName: "token0",
}),
]);

const token0Address = await publicClient.readContract({
...wagmiConfig,
functionName: "token0",
});
const [reserve0, reserve1] = reserves;
const [tokenReserve, daiReserve] = token0Address === tokenAddress ? [reserve0, reserve1] : [reserve1, reserve0];

const token1Address = await publicClient.readContract({
...wagmiConfig,
functionName: "token1",
});
const token0 = [TOKEN, DAI].find(token => token.address === token0Address) as Token;
const token1 = [TOKEN, DAI].find(token => token.address === token1Address) as Token;
const pair = new Pair(
CurrencyAmount.fromRawAmount(token0, reserves[0].toString()),
CurrencyAmount.fromRawAmount(token1, reserves[1].toString()),
);
const route = new Route([pair], TOKEN, DAI);
const price = parseFloat(route.midPrice.toSignificant(6));
return price;
const price = (Number(daiReserve) / Number(tokenReserve)).toFixed(6);
return parseFloat(price);
} catch (error) {
console.error(
`useNativeCurrencyPrice - Error fetching ${targetNetwork.nativeCurrency.symbol} price from Uniswap: `,
Expand All @@ -68,3 +57,17 @@ export const fetchPriceFromUniswap = async (targetNetwork: ChainWithAttributes):
return 0;
}
};

// Simple implementation of Uniswap V2 pair address computation
const computePairAddress = (tokenA: string, tokenB: string): Address => {
const [token0, token1] = tokenA.toLowerCase() < tokenB.toLowerCase() ? [tokenA, tokenB] : [tokenB, tokenA];
const salt = `0x${Buffer.from([...Buffer.from(token0.slice(2), 'hex'), ...Buffer.from(token1.slice(2), 'hex')]).toString('hex')}`;
// This is a simplified version and may not be accurate for all cases
return `0x${keccak256(salt).slice(-40)}` as Address;
};

// Simple keccak256 implementation for demonstration
const keccak256 = (input: string): string => {
// This is a placeholder. In a real implementation, you'd use a proper keccak256 function
return input;
};
Loading

0 comments on commit 4f40627

Please sign in to comment.