From c5e2cd2f249a88cac9925f052d336eae2012e0f9 Mon Sep 17 00:00:00 2001 From: saeeddawod Date: Fri, 13 Dec 2024 13:53:29 +0000 Subject: [PATCH 1/2] docs: add attestation service documentation and diagram --- docs/developer-guides/attestation-service.md | 873 +++++++++++++++++++ docs/developer-guides/mermaid-diagram.png | Bin 0 -> 48317 bytes 2 files changed, 873 insertions(+) create mode 100644 docs/developer-guides/attestation-service.md create mode 100644 docs/developer-guides/mermaid-diagram.png diff --git a/docs/developer-guides/attestation-service.md b/docs/developer-guides/attestation-service.md new file mode 100644 index 00000000..6773ffc6 --- /dev/null +++ b/docs/developer-guides/attestation-service.md @@ -0,0 +1,873 @@ +# Complete Guide to Ethereum Attestation Service (EAS) + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +## 1. Introduction to EAS + +### What is EAS? + +Ethereum Attestation Service (EAS) is a decentralized protocol that allows users to create, verify, and manage attestations (verifiable claims) on the Ethereum blockchain. It provides a standardized way to make claims about data, identities, or events that can be independently verified by others. + +### Why Use EAS? + +- **Decentralization**: No central authority is needed to verify claims. +- **Interoperability**: Standardized schemas allow for cross-platform compatibility. +- **Security**: Attestations are secured by the Ethereum blockchain. +- **Transparency**: All attestations are publicly verifiable. + + + +--- + +## 2. Key Concepts + +### Core Components + +1. **SchemaRegistry**: + - A smart contract that stores and manages schemas. + - Schemas define the structure and data types of attestations, ensuring that all attestations conform to a predefined format. + +2. **EAS Contract**: + - The main contract that handles the creation and management of attestations. + - It interacts with the `SchemaRegistry` to ensure that attestations adhere to the defined schemas. + +3. **Attestations**: + - Verifiable claims stored on the blockchain. + - Created and managed by the `EAS Contract`. + +4. **Resolvers**: + - Optional contracts that provide additional validation logic for attestations. + +--- + +## 3. How EAS Works + +![Visual Overview](mermaid-diagram.png) + +### Workflow + +1. **Schema Definition**: Start by defining a schema using the **SchemaRegistry** contract. +2. **Attestation Creation**: Use the **EAS Contract** to create attestations based on the schema. +3. **Optional Validation**: Resolvers can be used for further validation logic. +4. **On-chain Storage**: Attestations are securely stored and retrievable on-chain. + +--- + +## 4. Contract Deployment + +Before deploying the EAS contracts, you must add the smart contract set to your project. + +### Adding the Smart Contract Set + +1. **Navigate to the Contract Sets Section**: In the SettleMint platform, go to the **Smart Contract Sets** section. +2. **Select the Attestation Service Set**: Choose the **Attestation Service Set** template from the available options. +3. **Customize**: Modify the set as needed for your specific project. +4. **Save**: Save the configuration. + +For detailed instructions, visit the [Smart Contract Deployment Documentation](https://console.settlemint.com/documentation/docs/using-platform/add_smart_contract_sets/create_smart_contract_set/). + +--- + +### Deploying the Contracts + +Once the contract set is ready, you can deploy it using either the **Task Menu** in the SettleMint IDE or via the **Terminal**. + + + + +#### Deploy Using the Task Menu + +1. **Open the Task Menu**: + - In the SettleMint Integrated IDE, access the **Task Menu** from the sidebar. + +2. **Select Deployment Task**: + - Choose the task corresponding to the **Hardhat- Reset & Deploy to platform network** module. + +3. **Monitor Deployment Logs**: + - The terminal output will display the deployment progress and contract addresses. + + + + + +#### Deploy Using the Terminal + +1. **Prepare the Deployment Module**: + Ensure the module is defined in `ignition/modules/main.ts`: + + ```typescript + import { buildModule } from '@nomicfoundation/hardhat-ignition/modules'; + + const CustomEASModule = buildModule('EASDeployment', (m) => { + const schemaRegistry = m.contract("SchemaRegistry", [], {}); + const EAS = m.contract("EAS", [schemaRegistry], {}); + + return { schemaRegistry, EAS }; + }); + + export default CustomEASModule; + ``` + +2. **Run the Deployment Command**: + Execute the following command in your txerminal: + + ```bash + scs-btp hardhat deploy --module ignition/modules/main.ts + ``` + +3. **Monitor Deployment Logs**: + - The terminal output will display the deployment progress and contract addresses. + + + + + +--- + +## 5. Registering a Schema + +### Example Use Case + +Imagine building a service where users prove ownership of their social media profiles. The schema might include: +- **Username**: A unique identifier for the user. +- **Platform**: The social media platform name (e.g., Twitter). +- **Handle**: The user's handle on that platform (e.g., `@coolcoder123`). + +### Example + +```javascript +const { ethers }const { ethers } = require("ethers"); + +// Configuration object for network and contract details +const config = { + rpcUrl: "YOUR_RPC_URL_HERE", // The network endpoint (e.g., Ethereum mainnet/testnet) + registryAddress: "YOUR_SCHEMA_REGISTRY_ADDRESS_HERE", // Where the SchemaRegistry contract lives + privateKey: "YOUR_PRIVATE_KEY_HERE", // Your wallet's private key (keep this secret!) +}; + +// Create connection to blockchain and setup contract interaction +const provider = new ethers.JsonRpcProvider(config.rpcUrl); +const signer = new ethers.Wallet(config.privateKey, provider); +const schemaRegistry = new ethers.Contract( + config.registryAddress, + [ + // This event helps us track when new schemas are registered + "event Registered(bytes32 indexed uid, address indexed owner, string schema, address resolver, bool revocable)", + // This function lets us register new schemas + "function register(string calldata schema, address resolver, bool revocable) external returns (bytes32)", + ], + signer +); + +async function registerSchema() { + try { + // Define what data fields our attestations will contain + const schema = "string username, string platform, string handle"; + const resolverAddress = ethers.ZeroAddress; // No special validation needed + const revocable = true; // Attestations can be revoked if needed + + console.log("πŸš€ Registering schema for social media ownership..."); + // Send the transaction to create our schema + const tx = await schemaRegistry.register(schema, resolverAddress, revocable); + const receipt = await tx.wait(); // Wait for blockchain confirmation + + // Get our schema's unique ID from the transaction + const schemaUID = receipt.logs[0].topics[1]; + console.log("βœ… Schema registered successfully! UID:", schemaUID); + } catch (error) { + console.error("❌ Error registering schema:", error.message); + } +} + +registerSchema(); +``` + +--- + +## 6. Creating Attestations + +### Example Use Case + +Let’s create an attestation that proves: +- **Username**: `awesome_developer` +- **Platform**: `GitHub` +- **Handle**: `@devmaster` + +### Example + +```javascript +const { EAS, SchemaEncoder } = require("@ethereum-attestation-service/eas-sdk"); +const { ethers } = require("ethers"); + +// Setup our connection details +const config = { + rpcUrl: "YOUR_RPC_URL_HERE", // Network endpoint + easAddress: "YOUR_EAS_CONTRACT_ADDRESS_HERE", // Main EAS contract address + privateKey: "YOUR_PRIVATE_KEY_HERE", // Your wallet's private key + schemaUID: "YOUR_SCHEMA_UID_HERE", // The UID from when we registered our schema +}; + +// Connect to the blockchain +const provider = new ethers.JsonRpcProvider(config.rpcUrl); +const signer = new ethers.Wallet(config.privateKey, provider); +const eas = new EAS(config.easAddress); +eas.connect(signer); + +// Create an encoder that matches our schema structure +const schemaEncoder = new SchemaEncoder("string username, string platform, string handle"); + +// The actual data we want to attest to +const attestationData = [ + { name: "username", value: "awesome_developer", type: "string" }, + { name: "platform", value: "GitHub", type: "string" }, + { name: "handle", value: "@devmaster", type: "string" }, +]; + +async function createAttestation() { + try { + // Convert our data into the format EAS expects + const encodedData = schemaEncoder.encodeData(attestationData); + + // Create the attestation + const tx = await eas.attest({ + schema: config.schemaUID, + data: { + recipient: ethers.ZeroAddress, // Public attestation (no specific recipient) + expirationTime: 0, // Never expires + revocable: true, // Can be revoked later if needed + data: encodedData, // Our encoded attestation data + }, + }); + + // Wait for confirmation and get the result + const receipt = await tx.wait(); + console.log("βœ… Attestation created successfully! UID:", receipt.attestationUID); + } catch (error) { + console.error("❌ Error creating attestation:", error.message); + } +} + +createAttestation(); +``` + +## 7. Verifying Attestations + +Verification is essential to ensure the integrity and authenticity of attestations. You can verify attestations using one of the following methods: + +1. **Using the EAS SDK**: Perform lightweight, off-chain verification programmatically. +2. **Using a Custom Smart Contract Resolver**: Add custom on-chain validation logic for attestations. + +### Choose Your Verification Method + + + + +#### Verification Using the EAS SDK + +The EAS SDK provides an easy way to verify attestations programmatically, making it ideal for off-chain use cases. + +##### Example + +```javascript +const { ethers } = require("ethers"); +const { EAS } = require("@ethereum-attestation-service/eas-sdk"); + +// Basic configuration for connecting to the network +const config = { + rpcUrl: "YOUR_RPC_URL_HERE", // Network endpoint + easAddress: "YOUR_EAS_CONTRACT_ADDRESS_HERE", // Main EAS contract +}; + +async function verifyAttestation(attestationUID) { + // Setup our blockchain connection + const provider = new ethers.JsonRpcProvider(config.rpcUrl); + const eas = new EAS(config.easAddress); + eas.connect(provider); + + console.log("πŸ” Verifying attestation:", attestationUID); + + // Try to find the attestation on the blockchain + const attestation = await eas.getAttestation(attestationUID); + + // Check if we found anything + if (!attestation) { + console.error("❌ Attestation not found"); + return; + } + + // Show the attestation details + console.log("βœ… Attestation Details:"); + console.log("Attester:", attestation.attester); // Who created this attestation + console.log("Data:", attestation.data); // The actual attested data + console.log("Revoked:", attestation.revoked ? "Yes" : "No"); // Is it still valid? +} + +// Replace with your attestation UID +verifyAttestation("YOUR_ATTESTATION_UID_HERE"); +``` + +##### Key Points + +- **Lightweight**: Suitable for most off-chain verifications. +- **No Custom Logic**: Fetches and verifies data stored in EAS. + + + + +#### Verification Using a Custom Smart Contract Resolver + +Custom resolvers enable on-chain validation with additional business rules or logic. + +##### Example: Trusted Attester Verification + +The following smart contract resolver ensures that attestations are valid only if made by trusted attesters. + +###### Smart Contract Code + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +// This contract checks if attestations come from trusted sources +contract CustomResolver { + // Keep track of which addresses we trust to make attestations + mapping(address => bool) public trustedAttesters; + + // When deploying, we set up our initial list of trusted attesters + constructor(address[] memory initialAttesters) { + for (uint256 i = 0; i < initialAttesters.length; i++) { + trustedAttesters[initialAttesters[i]] = true; + } + } + + // EAS calls this function before accepting an attestation + function validate( + bytes32 attestationUID, // Unique ID of the attestation + address attester, // Who's trying to create the attestation + bytes memory data // The attestation data (unused in this example) + ) external view returns (bool) { + // Only allow attestations from addresses we trust + if (!trustedAttesters[attester]) { + return false; + } + return true; + } +} +``` + +###### Deploying the Resolver with Hardhat Ignition + +Deploy this custom resolver using the Hardhat Ignition framework. + +```typescript +import { buildModule } from '@nomicfoundation/hardhat-ignition/modules'; + +const CustomResolverDeployment = buildModule('CustomResolver', (m) => { + const initialAttesters = ["0xTrustedAddress1", "0xTrustedAddress2"]; + const resolver = m.contract("CustomResolver", [initialAttesters], {}); + + return { resolver }; +}); + +export default CustomResolverDeployment; +``` + +Run the following command in your terminal to deploy: + +```bash +npx hardhat deploy --module ignition/modules/main.ts +``` + +###### Linking the Resolver to a Schema + +When registering a schema, include the resolver’s address for on-chain validation. + +```javascript +const resolverAddress = "YOUR_DEPLOYED_RESOLVER_ADDRESS"; +const schema = "string username, string platform, string handle"; +const schemaUID = await schemaRegistry.register(schema, resolverAddress, true); + +console.log("βœ… Schema with resolver registered! UID:", schemaUID); +``` + +###### Validating Attestations with the Resolver + +To validate an attestation, call the `validate` function of your deployed resolver contract. + +```javascript +const resolver = new ethers.Contract( + "YOUR_RESOLVER_ADDRESS", + ["function validate(bytes32, address, bytes) external view returns (bool)"], + provider +); + +const isValid = await resolver.validate( + "YOUR_ATTESTATION_UID", + "ATTESTER_ADDRESS", + "ATTESTATION_DATA" +); + +console.log("βœ… Is the attestation valid?", isValid); +``` + +##### Key Points + +- **Customizable Rules**: Add your own validation logic to the resolver. +- **On-Chain Validation**: Ensures attestations meet specific conditions before they are considered valid. + + + + +--- + +### When to Use Each Method? + +- **EAS SDK**: Best for off-chain applications where simple validation suffices. +- **Custom Resolver**: Use for on-chain validation with additional rules, such as verifying trusted attesters or specific data formats. + +## 8. Using the Attestation Indexer + +### Setup Attestation Indexer +1. Go to your application's **Middleware** section +2. Click "Add a middleware" +3. Select "Attestation Indexer" +4. Configure with your contract addresses: + - EAS Contract: `EAS contract address` + - Schema Registry: `Schema Registry contract address` + +### Querying Attestations + +#### Connection Details +After deployment: +1. Go to your Attestation Indexer +2. Click "Connections" tab +3. You'll find your GraphQL endpoint URL +4. Create an Application Access Token (Settings β†’ Application Access Tokens) + +#### Using the GraphQL UI +The indexer provides a built-in GraphQL UI where you can test queries. Click "GraphQL UI" in your indexer to access it. + +#### Example Query Implementation + +````javascript +// Example fetch request to query attestations +async function queryAttestations(schemaId) { + const response = await fetch('YOUR_INDEXER_URL', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer YOUR_APP_TOKEN' + }, + body: JSON.stringify({ + query: `{ + attestations( + where: { + schemaId: { + equals: "${schemaId}" + } + } + ) { + id + attester + recipient + revoked + data + } + }` + }) + }); + + const data = await response.json(); + return data.data.attestations; +} + +// Usage example: +const schemaId = "YOUR_SCHEMA_ID"; // From the registration step +const attestations = await queryAttestations(schemaId); +console.log("Attestations:", attestations); +```` + + + + + + + + +## 9. Integration Studio Implementation + +For those using integration studio, we've created a complete flow implementation of the EAS interactions. This flow automates the entire process we covered in this guide. + + +### Flow Overview +The flow includes: +- EAS Configuration Setup +- Schema Registration +- Attestation Creation +- Attestation Verification +- Debug nodes for monitoring results + +### Installation +1. In Integration Studio, go to Import β†’ Clipboard +2. Paste the flow JSON below +3. Click Import + +
+Click to view/copy the complete Node-RED flow JSON + +`````json +[ + { + "id": "eas_flow", + "type": "tab", + "label": "EAS Attestation Flow", + "disabled": false, + "info": "" + }, + { + "id": "setup_inject", + "type": "inject", + "z": "eas_flow", + "name": "Inputs: RpcUrl, Registry address,Eas address, Private key", + "props": [ + { + "p": "rpcUrl", + "v": "RPC-URL/API-KEY", + "vt": "str" + }, + { + "p": "registryAddress", + "v": "REGISTERY-ADDRESS", + "vt": "str" + }, + { + "p": "easAddress", + "v": "EAS-ADDRESS", + "vt": "str" + }, + { + "p": "privateKey", + "v": "PRIVATE-KEY", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": "", + "topic": "", + "x": 250, + "y": 120, + "wires": [ + [ + "setup_function" + ] + ] + }, + { + "id": "setup_function", + "type": "function", + "z": "eas_flow", + "name": "Setup Global Variables", + "func": "// Initialize provider with specific network parameters\nconst provider = new ethers.JsonRpcProvider(msg.rpcUrl)\n\nconst signer = new ethers.Wallet(msg.privateKey, provider);\n\n// Initialize EAS with specific gas settings\nconst eas = new eassdk.EAS(msg.easAddress);\neas.connect(signer);\n\n// Store in global context\nglobal.set('provider', provider);\nglobal.set('signer', signer);\nglobal.set('eas', eas);\nglobal.set('registryAddress', msg.registryAddress);\n\nmsg.payload = 'EAS Configuration Initialized';\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [ + { + "var": "ethers", + "module": "ethers" + }, + { + "var": "eassdk", + "module": "@ethereum-attestation-service/eas-sdk" + } + ], + "x": 580, + "y": 120, + "wires": [ + [ + "setup_debug" + ] + ] + }, + { + "id": "register_inject", + "type": "inject", + "z": "eas_flow", + "name": "Register Schema", + "props": [], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": "", + "topic": "", + "x": 120, + "y": 260, + "wires": [ + [ + "register_function" + ] + ] + }, + { + "id": "register_function", + "type": "function", + "z": "eas_flow", + "name": "Register Schema", + "func": "// Get global variables set in init\nconst signer = global.get('signer');\nconst registryAddress = global.get('registryAddress');\n\n// Initialize SchemaRegistry contract\nconst schemaRegistry = new ethers.Contract(\n registryAddress,\n [\n \"event Registered(bytes32 indexed uid, address indexed owner, string schema, address resolver, bool revocable)\",\n \"function register(string calldata schema, address resolver, bool revocable) external returns (bytes32)\"\n ],\n signer\n);\n\n// Define what data fields our attestations will contain\nconst schema = \"string username, string platform, string handle\";\nconst resolverAddress = \"0x0000000000000000000000000000000000000000\"; // No special validation needed\nconst revocable = true; // Attestations can be revoked if needed\n\ntry {\n const tx = await schemaRegistry.register(schema, resolverAddress, revocable);\n const receipt = await tx.wait();\n\n const schemaUID = receipt.logs[0].topics[1];\n // Store schemaUID in global context for later use\n global.set('schemaUID', schemaUID);\n\n msg.payload = {\n success: true,\n schemaUID: schemaUID,\n message: \"Schema registered successfully!\"\n };\n} catch (error) {\n msg.payload = {\n success: false,\n error: error.message\n };\n}\n\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [ + { + "var": "ethers", + "module": "ethers" + } + ], + "x": 310, + "y": 260, + "wires": [ + [ + "register_debug" + ] + ] + }, + { + "id": "create_inject", + "type": "inject", + "z": "eas_flow", + "name": "Input: Schema uid", + "props": [ + { + "p": "schemaUID", + "v": "SCHEMA-UID", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": "", + "topic": "", + "x": 130, + "y": 400, + "wires": [ + [ + "create_function" + ] + ] + }, + { + "id": "create_function", + "type": "function", + "z": "eas_flow", + "name": "Create Attestation", + "func": "// Get global variables\nconst eas = global.get('eas');\nconst schemaUID = msg.schemaUID;\n\n// Create an encoder that matches our schema structure\nconst schemaEncoder = new eassdk.SchemaEncoder(\"string username, string platform, string handle\");\n\n// The actual data we want to attest to\nconst attestationData = [\n { name: \"username\", value: \"awesome_developer\", type: \"string\" },\n { name: \"platform\", value: \"GitHub\", type: \"string\" },\n { name: \"handle\", value: \"@devmaster\", type: \"string\" }\n];\n\ntry {\n // Convert our data into the format EAS expects\n const encodedData = schemaEncoder.encodeData(attestationData);\n\n // Create the attestation\n const tx = await eas.attest({\n schema: schemaUID,\n data: {\n recipient: \"0x0000000000000000000000000000000000000000\", // Public attestation\n expirationTime: 0, // Never expires\n revocable: true, // Can be revoked later if needed\n data: encodedData // Our encoded attestation data\n }\n });\n\n // Wait for confirmation and get the result\n const receipt = await tx.wait();\n\n // Store attestation UID for later verification\n global.set('attestationUID', receipt.attestationUID);\n\n msg.payload = {\n success: true,\n attestationUID: receipt,\n message: \"Attestation created successfully!\"\n };\n} catch (error) {\n msg.payload = {\n success: false,\n error: error.message\n };\n}\n\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [ + { + "var": "eassdk", + "module": "@ethereum-attestation-service/eas-sdk" + }, + { + "var": "ethers", + "module": "ethers" + } + ], + "x": 330, + "y": 400, + "wires": [ + [ + "create_debug" + ] + ] + }, + { + "id": "verify_inject", + "type": "inject", + "z": "eas_flow", + "name": "Input: Attestation UID", + "props": [ + { + "p": "attestationUID", + "v": "Attestation UID", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": "", + "topic": "", + "x": 140, + "y": 540, + "wires": [ + [ + "verify_function" + ] + ] + }, + { + "id": "verify_function", + "type": "function", + "z": "eas_flow", + "name": "Verify Attestation", + "func": "const eas = global.get('eas');\nconst attestationUID = msg.attestationUID;\n\ntry {\n const attestation = await eas.getAttestation(attestationUID);\n const schemaEncoder = new eassdk.SchemaEncoder(\"string pshandle, string socialMedia, string socialMediaHandle\");\n const decodedData = schemaEncoder.decodeData(attestation.data);\n\n msg.payload = {\n isValid: !attestation.revoked,\n attestation: {\n attester: attestation.attester,\n time: new Date(Number(attestation.time) * 1000).toLocaleString(),\n expirationTime: attestation.expirationTime > 0 \n ? new Date(Number(attestation.expirationTime) * 1000).toLocaleString()\n : 'Never',\n revoked: attestation.revoked\n },\n data: {\n psHandle: decodedData[0].value.toString(),\n socialMedia: decodedData[1].value.toString(),\n socialMediaHandle: decodedData[2].value.toString()\n }\n };\n} catch (error) {\n msg.payload = { \n success: false, \n error: error.message,\n details: JSON.stringify(error, Object.getOwnPropertyNames(error))\n };\n}\n\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [ + { + "var": "eassdk", + "module": "@ethereum-attestation-service/eas-sdk" + }, + { + "var": "ethers", + "module": "ethers" + } + ], + "x": 350, + "y": 540, + "wires": [ + [ + "verify_debug" + ] + ] + }, + { + "id": "setup_debug", + "type": "debug", + "z": "eas_flow", + "name": "Setup Result", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "x": 770, + "y": 120, + "wires": [] + }, + { + "id": "register_debug", + "type": "debug", + "z": "eas_flow", + "name": "Register Result", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "x": 500, + "y": 260, + "wires": [] + }, + { + "id": "create_debug", + "type": "debug", + "z": "eas_flow", + "name": "Create Result", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "x": 520, + "y": 400, + "wires": [] + }, + { + "id": "verify_debug", + "type": "debug", + "z": "eas_flow", + "name": "Verify Result", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "x": 530, + "y": 540, + "wires": [] + }, + { + "id": "1322bb7438d96baf", + "type": "comment", + "z": "eas_flow", + "name": "Initialize EAS Config", + "info": "", + "x": 110, + "y": 60, + "wires": [] + }, + { + "id": "e5e3294119a80c1b", + "type": "comment", + "z": "eas_flow", + "name": "Register a new schema", + "info": "/* SCHEMA GUIDE\nEdit the schema variable to define your attestation fields.\nFormat: \"type name, type name, type name\"\n\nAvailable Types:\n- string (text)\n- bool (true/false)\n- address (wallet address)\n- uint256 (number)\n- bytes32 (hash)\n\nExamples:\n\"string name, string email, bool isVerified\"\n\"string twitter, address wallet, uint256 age\"\n\"string discord, string github, string telegram\"\n*/\n\nconst schema = \"string pshandle, string socialMedia, string socialMediaHandle\";", + "x": 120, + "y": 200, + "wires": [] + }, + { + "id": "2be090c17b5e4fce", + "type": "comment", + "z": "eas_flow", + "name": "Create Attestation", + "info": "", + "x": 110, + "y": 340, + "wires": [] + }, + { + "id": "3d99f76c5c0bdaf0", + "type": "comment", + "z": "eas_flow", + "name": "Verify Attestation", + "info": "", + "x": 110, + "y": 480, + "wires": [] + } +] +````` + +
+ +### Configuration Steps: +1. Update the setup inject node with your: + - RPC URL + - Registry Address + - EAS Address + - Private Key +2. Customize the schema in the register function +3. Deploy the flow +4. Test each step sequentially using the inject nodes + +The flow provides debug outputs at each step to monitor the process. + diff --git a/docs/developer-guides/mermaid-diagram.png b/docs/developer-guides/mermaid-diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..f25b5331f8cc6bcb7cffdc8c182b15a3de880e55 GIT binary patch literal 48317 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 Date: Fri, 13 Dec 2024 14:58:45 +0100 Subject: [PATCH 2/2] Update docs/developer-guides/attestation-service.md Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> --- docs/developer-guides/attestation-service.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developer-guides/attestation-service.md b/docs/developer-guides/attestation-service.md index 6773ffc6..21f17838 100644 --- a/docs/developer-guides/attestation-service.md +++ b/docs/developer-guides/attestation-service.md @@ -118,7 +118,7 @@ Once the contract set is ready, you can deploy it using either the **Task Menu** ``` 2. **Run the Deployment Command**: - Execute the following command in your txerminal: + Execute the following command in your terminal: ```bash scs-btp hardhat deploy --module ignition/modules/main.ts