-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f56089e
commit e20b010
Showing
6 changed files
with
536 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
"use client" | ||
import React, { useState } from "react"; | ||
import { attestFitnessChallenge } from "../../helpers/Attest"; | ||
|
||
const FitnessChallenge = () => { | ||
const [userAddress, setUserAddress] = useState(""); | ||
const [success, setSuccess] = useState(false); | ||
const [response, setResponse] = useState<string | null>(null); | ||
const [error, setError] = useState<string | null>(null); | ||
const [loading, setLoading] = useState(false); | ||
|
||
const handleAttest = async () => { | ||
setLoading(true); | ||
setResponse(null); | ||
setError(null); | ||
|
||
const PRIVATE_KEY = process.env.NEXT_PUBLIC_PRIVATE_KEY; | ||
if (!PRIVATE_KEY) { | ||
setError("Private key is not configured. Please check your .env file."); | ||
setLoading(false); | ||
return; | ||
} | ||
|
||
try { | ||
const attestationId = await attestFitnessChallenge(userAddress, success, PRIVATE_KEY); | ||
setResponse(`Attestation successful! Attestation ID: ${attestationId}`); | ||
} catch (err: any) { | ||
setError(err.message || "An error occurred during attestation."); | ||
} finally { | ||
setLoading(false); | ||
} | ||
}; | ||
|
||
return ( | ||
<div style={{ maxWidth: "600px", margin: "0 auto", textAlign: "center" }}> | ||
<h1>Fitness Challenge Attestation</h1> | ||
|
||
<div style={{ marginBottom: "20px" }}> | ||
<label> | ||
User Address: | ||
<input | ||
type="text" | ||
value={userAddress} | ||
onChange={e => setUserAddress(e.target.value)} | ||
placeholder="Enter recipient address" | ||
style={{ width: "100%", margin: "10px 0", padding: "10px", borderRadius: "5px" }} | ||
/> | ||
</label> | ||
</div> | ||
|
||
<div style={{ marginBottom: "20px" }}> | ||
<label> | ||
Challenge Completed: | ||
<input | ||
type="checkbox" | ||
checked={success} | ||
onChange={e => setSuccess(e.target.checked)} | ||
style={{ marginLeft: "10px" }} | ||
/> | ||
</label> | ||
</div> | ||
|
||
<button | ||
onClick={handleAttest} | ||
style={{ | ||
padding: "10px 20px", | ||
borderRadius: "5px", | ||
background: "#0070f3", | ||
color: "white", | ||
border: "none", | ||
cursor: "pointer", | ||
}} | ||
disabled={loading} | ||
> | ||
{loading ? "Attesting..." : "Attest"} | ||
</button> | ||
|
||
{response && <p style={{ color: "green", marginTop: "20px" }}>{response}</p>} | ||
{error && <p style={{ color: "red", marginTop: "20px" }}>{error}</p>} | ||
</div> | ||
); | ||
}; | ||
|
||
export default FitnessChallenge; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import { NO_EXPIRATION } from "@ethereum-attestation-service/eas-sdk"; | ||
import eas, { schemaIds, encoders } from "./EAS"; | ||
import { ethers } from "ethers"; | ||
import { injected } from "wagmi/connectors"; | ||
import { baseSepolia } from "viem/chains"; | ||
|
||
// Generalized attestation function | ||
export async function attestToSchema( | ||
schemaKey: keyof typeof schemaIds, | ||
attestationData: any, | ||
// privateKey: string | ||
) { | ||
try { | ||
const schemaId = schemaIds[schemaKey]; | ||
const encoder = encoders[schemaKey]; | ||
|
||
if (!schemaId || !encoder) { | ||
throw new Error(`Schema ${schemaKey} not defined`); | ||
} | ||
|
||
// Encode attestation data | ||
const encodedData = encoder.encodeData(attestationData); | ||
|
||
// Initialize signer (replace with your wallet setup) | ||
const wallet = new ethers.Wallet(privateKey, ethers.getDefaultProvider("base-sepolia")); | ||
|
||
// Connect wallet to EAS | ||
eas.connect(wallet); | ||
|
||
// Create attestation | ||
const tx = await eas.attest({ | ||
schema: schemaId, | ||
data: { | ||
recipient: attestationData[0].value, // Assume recipient is the first field | ||
expirationTime: NO_EXPIRATION, // Never expires | ||
revocable: false, // Cannot be revoked | ||
data: encodedData, | ||
}, | ||
}); | ||
|
||
console.log(`Transaction hash for ${schemaKey}:`, tx.hash); | ||
|
||
// Wait for confirmation | ||
const receipt = await tx.wait(); | ||
console.log(`${schemaKey} attestation created successfully:`, receipt); | ||
|
||
// Extract attestation ID from logs | ||
const attestationId = receipt.logs[0].topics[1]; | ||
console.log(`${schemaKey} Attestation ID:`, attestationId); | ||
return attestationId; | ||
} catch (error) { | ||
console.error(`Error attesting to ${schemaKey}:`, error); | ||
throw error; | ||
} | ||
} | ||
|
||
// Example usage for fitness challenge attestation | ||
export async function attestFitnessChallenge( | ||
userAddress: string, | ||
success: boolean, | ||
// privateKey: string | ||
) { | ||
return attestToSchema("fitnessChallenge", [ | ||
{ name: "user", value: userAddress, type: "address" }, | ||
{ name: "timestamp", value: Math.floor(Date.now() / 1000), type: "uint256" }, | ||
{ name: "success", value: success, type: "bool" }, | ||
]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { | ||
EAS, | ||
SchemaEncoder, | ||
} from "@ethereum-attestation-service/eas-sdk"; | ||
import { ethers } from "ethers"; | ||
|
||
// EAS Contract Address for Base Sepolia | ||
export const EASContractAddress = "0x4200000000000000000000000000000000000021"; | ||
|
||
// Initialize EAS SDK | ||
const eas = new EAS(EASContractAddress); | ||
|
||
// Default provider for Base Sepolia | ||
const provider = ethers.getDefaultProvider("sepolia"); | ||
|
||
// Connect provider to EAS | ||
eas.connect(provider); | ||
|
||
// Schema IDs (replace with actual deployed schema IDs) | ||
export const schemaIds = { | ||
fitnessChallenge: "0x51a8a63da0f823d83d6355aee1e1643f58247253874fa36a70059b841287960e", | ||
stakingGoal: "0x51a8a63da0f823d83d6355aee1e1643f58247253874fa36a70059b841287960e", | ||
rewardDistribution: "0x51a8a63da0f823d83d6355aee1e1643f58247253874fa36a70059b841287960e", | ||
}; | ||
|
||
// Schema Encoders for each schema | ||
export const encoders = { | ||
fitnessChallenge: new SchemaEncoder( | ||
"address user, uint256 timestamp, bool success" | ||
), | ||
stakingGoal: new SchemaEncoder( | ||
"address user, uint256 timestamp, bool success" | ||
), | ||
rewardDistribution: new SchemaEncoder( | ||
"address user, uint256 timestamp, bool success" | ||
), | ||
}; | ||
|
||
export default eas; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import eas from "./EAS"; | ||
|
||
// Function to verify attestation | ||
export async function verifyAttestation(attestationId: string) { | ||
try { | ||
// Fetch attestation details | ||
const attestation = await eas.getAttestation(attestationId); | ||
|
||
if (!attestation) { | ||
throw new Error("Attestation not found"); | ||
} | ||
|
||
console.log("Attestation details:", attestation); | ||
|
||
// Example: Check if the attestation is valid | ||
if (attestation.revoked) { | ||
throw new Error("Attestation has been revoked"); | ||
} | ||
|
||
return { | ||
isValid: true, | ||
attestation, | ||
}; | ||
} catch (error) { | ||
console.error("Error verifying attestation:", error); | ||
return { | ||
isValid: false, | ||
error: error.message, | ||
}; | ||
} | ||
} |
Oops, something went wrong.