Skip to content
Merged
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,4 @@ src/eas_sdk/proto/
buf.lock

CLAUDE.md
node_modules/
132 changes: 71 additions & 61 deletions examples/full_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,62 +36,64 @@ def __init__(self):
def setup_eas(self) -> bool:
"""Set up EAS instance."""
print("🔧 Setting up EAS instance...")

try:
# Method 1: From environment (recommended)
self.eas = EAS.from_environment()
print(" ✅ EAS created from environment variables")
return True

except Exception as env_error:
print(f" ⚠️ Environment setup failed: {env_error}")

# Method 2: Direct configuration (fallback)
try:
print(" 🔄 Trying direct configuration...")

# Get configuration for testnet
config = get_network_config("sepolia")

# You would need to provide these values
private_key = os.getenv("PRIVATE_KEY")
from_account = os.getenv("FROM_ACCOUNT")
from_account = os.getenv("FROM_ACCOUNT")

if not private_key or not from_account:
print(" ❌ PRIVATE_KEY and FROM_ACCOUNT environment variables required")
print(
" ❌ PRIVATE_KEY and FROM_ACCOUNT environment variables required"
)
return False

self.eas = EAS.from_chain(
chain_name="sepolia",
private_key=private_key,
from_account=from_account
from_account=from_account,
)
print(" ✅ EAS created with direct configuration")
return True

except Exception as direct_error:
print(f" ❌ Direct configuration failed: {direct_error}")
return False

def register_schema(self) -> bool:
"""Register a schema for our attestations."""
print("\n📝 Registering schema...")

try:
# Define a useful schema for user profiles
schema = "string name,string email,uint256 reputation,bool verified,bytes32 profileHash"

print(f" Schema: {schema}")

result = self.eas.register_schema(
schema=schema,
network_name="sepolia", # Use testnet for safety
revocable=True # Allow revocations
chain_name="sepolia", # Use testnet for safety
revocable=True, # Allow revocations
)

if result.success:
# Extract schema UID from transaction logs or response
schema_uid = result.data.get('schema_uid')
schema_uid = result.data.get("schema_uid")
if schema_uid:
self.schema_uid = schema_uid
print(f" ✅ Schema registered: {schema_uid}")
Expand All @@ -103,51 +105,55 @@ def register_schema(self) -> bool:
else:
print(f" ❌ Schema registration failed: {result.error}")
return False

except Exception as e:
print(f" ❌ Schema registration error: {e}")
return False

def create_attestation(self) -> bool:
"""Create an attestation using our schema."""
print("\n🏅 Creating attestation...")

if not self.schema_uid:
print(" ❌ No schema UID available")
return False

try:
# Prepare attestation data
recipient = "0x742d35Cc6634C0532925a3b8D16c30B9b2C4e40B" # Example recipient

recipient = (
"0x742d35Cc6634C0532925a3b8D16c30B9b2C4e40B" # Example recipient
)

# Encode data according to our schema
# Schema: "string name,string email,uint256 reputation,bool verified,bytes32 profileHash"
attestation_data = encode(
["string", "string", "uint256", "bool", "bytes32"],
[
"Alice Johnson",
"alice@example.com",
"alice@example.com",
1000, # reputation score
True, # verified
bytes.fromhex("a1b2c3d4e5f6789012345678901234567890123456789012345678901234567890")
]
bytes.fromhex(
"a1b2c3d4e5f6789012345678901234567890123456789012345678901234567890"
),
],
)

print(f" 👤 Recipient: {recipient}")
print(f" 📦 Data length: {len(attestation_data)} bytes")

result = self.eas.create_attestation(
schema_uid=self.schema_uid,
recipient=recipient,
encoded_data=attestation_data,
expiration=0, # No expiration
revocable=True,
value=0 # No ETH value
value=0, # No ETH value
)

if result.success:
# Extract attestation UID from transaction logs
attestation_uid = result.data.get('attestation_uid')
attestation_uid = result.data.get("attestation_uid")
if attestation_uid:
self.attestation_uid = attestation_uid
print(f" ✅ Attestation created: {attestation_uid}")
Expand All @@ -160,22 +166,22 @@ def create_attestation(self) -> bool:
else:
print(f" ❌ Attestation creation failed: {result.error}")
return False

except Exception as e:
print(f" ❌ Attestation creation error: {e}")
return False

def query_attestation(self) -> bool:
"""Query the attestation we just created."""
print("\n🔍 Querying attestation...")

if not self.attestation_uid:
print(" ⚠️ No attestation UID to query")
return False

try:
attestation = self.eas.get_attestation(self.attestation_uid)

if attestation:
print(f" ✅ Attestation found:")
print(f" Schema: {attestation[1]}") # schema UID
Expand All @@ -192,15 +198,15 @@ def query_attestation(self) -> bool:
else:
print(" ❌ Attestation not found")
return False

except Exception as e:
print(f" ❌ Query error: {e}")
return False

def demonstrate_offchain_attestation(self) -> bool:
"""Demonstrate off-chain attestation."""
print("\n🌐 Creating off-chain attestation...")

try:
# Create off-chain attestation message
message = {
Expand All @@ -211,46 +217,48 @@ def demonstrate_offchain_attestation(self) -> bool:
"expirationTime": 0,
"revocable": True,
"refUID": None,
"data": json.dumps({
"name": "Bob Smith",
"email": "bob@example.com",
"reputation": 750,
"verified": False,
"note": "Off-chain attestation example"
}).encode()
"data": json.dumps(
{
"name": "Bob Smith",
"email": "bob@example.com",
"reputation": 750,
"verified": False,
"note": "Off-chain attestation example",
}
).encode(),
}

offchain_attestation = self.eas.attest_offchain(message)

print(f" ✅ Off-chain attestation created")
print(f" 🆔 UID: {offchain_attestation['message']['uid']}")
print(f" ✍️ Signature: {offchain_attestation['signature']['r'][:10]}...")

return True

except Exception as e:
print(f" ❌ Off-chain attestation error: {e}")
return False

def demonstrate_revocation(self) -> bool:
"""Demonstrate attestation revocation."""
print("\n❌ Revoking attestation...")

if not self.attestation_uid:
print(" ⚠️ No attestation UID to revoke")
return False

try:
result = self.eas.revoke_attestation(self.attestation_uid)

if result.success:
print(f" ✅ Attestation revoked")
print(f" 🔗 Transaction: {result.tx_hash}")
return True
else:
print(f" ❌ Revocation failed: {result.error}")
return False

except Exception as e:
print(f" ❌ Revocation error: {e}")
return False
Expand All @@ -259,39 +267,41 @@ def run_complete_workflow(self):
"""Run the complete EAS workflow."""
print("🚀 EAS SDK Complete Workflow Example")
print("=" * 50)

# Step 1: Setup
if not self.setup_eas():
print("\n❌ Setup failed. Cannot continue.")
return

# Step 2: Register schema
if not self.register_schema():
print("\n⚠️ Using fallback schema for remaining examples...")
# Use a known schema for testnets
self.schema_uid = "0x83c23d3c24c90bc5d1b8b44a7c2cc50e4d9efca2e80d78a3ce5f8e4d10e5d4e5"

self.schema_uid = (
"0x83c23d3c24c90bc5d1b8b44a7c2cc50e4d9efca2e80d78a3ce5f8e4d10e5d4e5"
)

# Step 3: Create attestation
if self.create_attestation():
# Step 4: Query attestation
self.query_attestation()

# Step 5: Demonstrate revocation
print("\n⏱️ Waiting 5 seconds before revocation...")
time.sleep(5)
self.demonstrate_revocation()

# Step 6: Off-chain attestation (always works)
self.demonstrate_offchain_attestation()

print("\n✨ Complete workflow finished!")
print("\n📚 What you've learned:")
print(" • How to initialize EAS from environment variables")
print(" • How to register schemas on-chain")
print(" • How to create and query attestations")
print(" • How to create off-chain attestations")
print(" • How to revoke attestations")

print("\n🛠️ Development Tips:")
print(" • Use testnet (sepolia) for development")
print(" • Check transaction status before proceeding")
Expand All @@ -306,4 +316,4 @@ def main():


if __name__ == "__main__":
main()
main()
2 changes: 1 addition & 1 deletion examples/multi_chain_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def demonstrate_factory_methods():
from EAS.config import create_eas_instance

eas = create_eas_instance(
network_name='mainnet', # or 'sepolia', 'goerli', etc.
chain_name='mainnet', # or 'sepolia', 'goerli', etc.
from_account='0x1234...',
private_key='0x1234...'
)
Expand Down
Loading