Skip to content

Commit 79dea65

Browse files
committed
feat: add simple EAS SDK workflow example and refactor schema types
1 parent 1bb86bd commit 79dea65

File tree

11 files changed

+1248
-1410
lines changed

11 files changed

+1248
-1410
lines changed
Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
#!/usr/bin/env bun
2+
3+
/**
4+
* Simple EAS SDK Workflow Example
5+
*
6+
* This example demonstrates the complete EAS workflow:
7+
* 1. Initialize EAS client
8+
* 2. Deploy EAS contracts (if needed)
9+
* 3. Register a schema
10+
* 4. Create attestations
11+
* 5. Retrieve schemas and attestations
12+
*/
13+
14+
import type { Address, Hex } from "viem";
15+
import { createEASClient } from "../src/eas.js";
16+
import type { SchemaField } from "../src/types.js";
17+
18+
// Configuration
19+
const CONFIG = {
20+
instance:
21+
process.env.SETTLEMINT_PORTAL_GRAPHQL_ENDPOINT ||
22+
"https://attestation-portal-ee231.gke-europe.settlemint.com/graphql",
23+
accessToken: process.env.SETTLEMINT_ACCESS_TOKEN || "your-eas-portal-token",
24+
// Contract addresses are optional - can be deployed via client
25+
// easContractAddress: "0xd46081aeEC4Ee8DB98eBDd9E066B5B9b151A2096" as Address,
26+
// schemaRegistryContractAddress: "0x5EFfB599d6DebD7cf576fb94F4C086b2bCC917b6" as Address,
27+
debug: true,
28+
};
29+
30+
// Schema definition with proper typing
31+
interface UserReputationSchema {
32+
user: Address;
33+
score: bigint;
34+
category: string;
35+
timestamp: bigint;
36+
verified: boolean;
37+
}
38+
39+
async function simpleEASWorkflow() {
40+
console.log("🚀 Simple EAS SDK Workflow");
41+
console.log("===========================\n");
42+
43+
try {
44+
// 1. Initialize EAS client
45+
console.log("📋 Step 1: Initialize EAS Client");
46+
const eas = createEASClient(CONFIG);
47+
console.log("✅ EAS client initialized\n");
48+
49+
// 2. Deploy EAS contracts (if needed)
50+
console.log("🏗️ Step 2: Deploy EAS Contracts");
51+
try {
52+
const deployResult = await eas.deploy();
53+
console.log("✅ Contracts deployed:");
54+
console.log(` EAS: ${deployResult.easAddress}`);
55+
console.log(` Schema Registry: ${deployResult.schemaRegistryAddress}`);
56+
} catch (error) {
57+
console.log("ℹ️ Using existing contracts:");
58+
const addresses = eas.getContractAddresses();
59+
console.log(` EAS: ${addresses.easAddress || "Not set"}`);
60+
console.log(` Schema Registry: ${addresses.schemaRegistryAddress || "Not set"}`);
61+
console.log("✅ Contracts ready");
62+
}
63+
console.log();
64+
65+
// 3. Register a schema
66+
console.log("📝 Step 3: Register Schema");
67+
const schemaFields: SchemaField[] = [
68+
{ name: "user", type: "address", description: "User's wallet address" },
69+
{ name: "score", type: "uint256", description: "Reputation score (0-100)" },
70+
{ name: "category", type: "string", description: "Reputation category" },
71+
{ name: "timestamp", type: "uint256", description: "When reputation was earned" },
72+
{ name: "verified", type: "bool", description: "Whether reputation is verified" },
73+
];
74+
75+
try {
76+
const schemaResult = await eas.registerSchema({
77+
fields: schemaFields,
78+
resolver: "0x0000000000000000000000000000000000000000" as Address,
79+
revocable: true,
80+
});
81+
82+
console.log("✅ Schema registered:");
83+
console.log(` Transaction: ${schemaResult.hash}`);
84+
console.log(` Success: ${schemaResult.success}`);
85+
} catch (error) {
86+
console.log("⚠️ Schema registration not implemented yet");
87+
console.log(" Schema fields defined:");
88+
schemaFields.forEach((field, index) => {
89+
console.log(` ${index + 1}. ${field.name}: ${field.type} - ${field.description}`);
90+
});
91+
}
92+
93+
// For demo purposes, we'll use a mock schema UID
94+
const schemaUID = "0x1234567890123456789012345678901234567890123456789012345678901234" as Hex;
95+
console.log(` Schema UID: ${schemaUID}\n`);
96+
97+
// 4. Create attestations
98+
console.log("🎯 Step 4: Create Attestations");
99+
100+
try {
101+
// Attestation 1: High reputation user
102+
const attestation1 = await eas.attest({
103+
schema: schemaUID,
104+
data: {
105+
recipient: "0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6" as Address,
106+
expirationTime: BigInt(0), // Never expires
107+
revocable: true,
108+
refUID: "0x0000000000000000000000000000000000000000000000000000000000000000" as Hex,
109+
data: "0x" as Hex, // Encoded: user=0x742d35..., score=95, category="developer", timestamp=1704067200, verified=true
110+
value: BigInt(0),
111+
},
112+
});
113+
114+
console.log("✅ Attestation 1 created:");
115+
console.log(` Transaction: ${attestation1.hash}`);
116+
console.log(" Type: High reputation developer");
117+
118+
// Attestation 2: Community contributor
119+
const attestation2 = await eas.attest({
120+
schema: schemaUID,
121+
data: {
122+
recipient: "0x8ba1f109551bD432803012645Hac136c22C177ec" as Address,
123+
expirationTime: BigInt(Math.floor(Date.now() / 1000) + 365 * 24 * 60 * 60), // 1 year
124+
revocable: true,
125+
refUID: "0x0000000000000000000000000000000000000000000000000000000000000000" as Hex,
126+
data: "0x" as Hex, // Encoded: user=0x8ba1f1..., score=78, category="community", timestamp=1704067200, verified=true
127+
value: BigInt(0),
128+
},
129+
});
130+
131+
console.log("✅ Attestation 2 created:");
132+
console.log(` Transaction: ${attestation2.hash}`);
133+
console.log(" Type: Community contributor");
134+
} catch (error) {
135+
console.log("⚠️ Attestation creation not implemented yet");
136+
console.log(" Attestation data prepared:");
137+
console.log(" - High reputation developer");
138+
console.log(" - Community contributor");
139+
}
140+
console.log();
141+
142+
// 5. Retrieve schema
143+
console.log("📖 Step 5: Retrieve Schema");
144+
try {
145+
const retrievedSchema = await eas.getSchema(schemaUID);
146+
console.log("✅ Schema retrieved:");
147+
console.log(` UID: ${retrievedSchema.uid}`);
148+
console.log(` Schema: ${retrievedSchema.schema}`);
149+
console.log(` Resolver: ${retrievedSchema.resolver}`);
150+
console.log(` Revocable: ${retrievedSchema.revocable}`);
151+
} catch (error) {
152+
console.log("⚠️ Schema retrieval not implemented yet");
153+
console.log(` Would retrieve schema: ${schemaUID}`);
154+
}
155+
console.log();
156+
157+
// 6. Retrieve all schemas
158+
console.log("📚 Step 6: Retrieve All Schemas");
159+
try {
160+
const allSchemas = await eas.getSchemas({ limit: 10 });
161+
console.log(`✅ Retrieved ${allSchemas.length} schemas`);
162+
allSchemas.forEach((schema, index) => {
163+
console.log(` ${index + 1}. ${schema.uid} - ${schema.schema}`);
164+
});
165+
} catch (error) {
166+
console.log("⚠️ Schemas retrieval not implemented yet");
167+
console.log(" Would retrieve paginated schemas");
168+
}
169+
console.log();
170+
171+
// 7. Retrieve attestations
172+
console.log("📋 Step 7: Retrieve Attestations");
173+
174+
// Mock attestation UIDs for demo
175+
const attestationUID1 = "0xabcd567890123456789012345678901234567890123456789012345678901234" as Hex;
176+
const attestationUID2 = "0xefgh567890123456789012345678901234567890123456789012345678901234" as Hex;
177+
178+
try {
179+
const retrievedAttestation1 = await eas.getAttestation(attestationUID1);
180+
console.log("✅ Attestation 1 retrieved:");
181+
console.log(` UID: ${retrievedAttestation1.uid}`);
182+
console.log(` Schema: ${retrievedAttestation1.schema}`);
183+
console.log(` Attester: ${retrievedAttestation1.attester}`);
184+
console.log(` Recipient: ${retrievedAttestation1.recipient}`);
185+
console.log(` Time: ${new Date(Number(retrievedAttestation1.time) * 1000).toISOString()}`);
186+
console.log(` Revocable: ${retrievedAttestation1.revocable}`);
187+
188+
const retrievedAttestation2 = await eas.getAttestation(attestationUID2);
189+
console.log("✅ Attestation 2 retrieved:");
190+
console.log(` UID: ${retrievedAttestation2.uid}`);
191+
console.log(` Schema: ${retrievedAttestation2.schema}`);
192+
console.log(` Attester: ${retrievedAttestation2.attester}`);
193+
console.log(` Recipient: ${retrievedAttestation2.recipient}`);
194+
console.log(` Time: ${new Date(Number(retrievedAttestation2.time) * 1000).toISOString()}`);
195+
console.log(` Revocable: ${retrievedAttestation2.revocable}`);
196+
} catch (error) {
197+
console.log("⚠️ Attestation retrieval not implemented yet");
198+
console.log(` Would retrieve attestations: ${attestationUID1}, ${attestationUID2}`);
199+
}
200+
console.log();
201+
202+
// 8. Retrieve all attestations
203+
console.log("📋 Step 8: Retrieve All Attestations");
204+
try {
205+
const allAttestations = await eas.getAttestations({
206+
limit: 10,
207+
schema: schemaUID,
208+
});
209+
console.log(`✅ Retrieved ${allAttestations.length} attestations for schema`);
210+
allAttestations.forEach((attestation, index) => {
211+
console.log(` ${index + 1}. ${attestation.uid} - ${attestation.recipient}`);
212+
});
213+
} catch (error) {
214+
console.log("⚠️ Attestations retrieval not implemented yet");
215+
console.log(" Would retrieve paginated attestations");
216+
}
217+
console.log();
218+
219+
// 9. Summary
220+
console.log("🎉 Workflow Complete!");
221+
console.log("=====================");
222+
console.log("✅ EAS client initialized");
223+
console.log("✅ Contract deployment interface ready");
224+
console.log("✅ Schema registration interface ready");
225+
console.log("✅ Attestation creation interface ready");
226+
console.log("✅ Schema retrieval interface ready");
227+
console.log("✅ Attestation retrieval interface ready");
228+
console.log("\n💡 Next steps:");
229+
console.log("- Implement the actual method logic");
230+
console.log("- Add Portal or direct blockchain integration");
231+
console.log("- Add data encoding/decoding utilities");
232+
console.log("- Set up event monitoring");
233+
} catch (error) {
234+
console.error("❌ Workflow failed:", error);
235+
236+
if (error instanceof Error) {
237+
console.error("Error details:", error.message);
238+
239+
// Provide helpful debugging information
240+
if (error.message.includes("not implemented yet")) {
241+
console.log("\n💡 Implementation Status:");
242+
console.log("- This is the clean interface design phase");
243+
console.log("- Method implementations will be added later");
244+
console.log("- All method signatures are properly defined");
245+
}
246+
}
247+
}
248+
}
249+
250+
// Type-safe helper functions for working with the schema
251+
export const UserReputationSchemaHelpers = {
252+
/**
253+
* Encode user reputation data for attestation
254+
*/
255+
encodeData(data: UserReputationSchema): Hex {
256+
// In a real implementation, this would use ABI encoding
257+
// For demo purposes, we return a placeholder
258+
return "0x" as Hex;
259+
},
260+
261+
/**
262+
* Decode attestation data to typed object
263+
*/
264+
decodeData(encodedData: Hex): UserReputationSchema {
265+
// In a real implementation, this would use ABI decoding
266+
// For demo purposes, we return mock data
267+
return {
268+
user: "0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6" as Address,
269+
score: BigInt(95),
270+
category: "developer",
271+
timestamp: BigInt(Math.floor(Date.now() / 1000)),
272+
verified: true,
273+
};
274+
},
275+
276+
/**
277+
* Validate reputation score
278+
*/
279+
validateScore(score: bigint): boolean {
280+
return score >= BigInt(0) && score <= BigInt(100);
281+
},
282+
283+
/**
284+
* Get reputation category enum
285+
*/
286+
getCategories(): readonly string[] {
287+
return ["developer", "community", "governance", "security", "education"] as const;
288+
},
289+
};
290+
291+
// Run the workflow
292+
if (typeof require !== "undefined" && require.main === module) {
293+
simpleEASWorkflow().catch(console.error);
294+
}
295+
296+
export { simpleEASWorkflow, type UserReputationSchema };

0 commit comments

Comments
 (0)