/** * DAIS Service - DAARION Autonomous Identity System * Based on: docs/foundation/DAARION_Identity_And_Access_Draft_v1.md */ import { db } from '../../infra/db/client'; import { logger } from '../../infra/logger/logger'; import type { DaisIdentity, DaisProfile, DaisEmail, DaisWallet, CreateDaisRequest, DaisCreationResult, DaisTrustLevel, } from '../../domain/dais/types'; import { v4 as uuidv4 } from 'uuid'; export class DaisService { /** * Create a new DAIS identity */ async createIdentity(request: CreateDaisRequest): Promise { const id = `dais-${uuidv4()}`; const did = `did:daarion:${uuidv4()}`; try { // Create DAIS identity const identity = await db.query( `INSERT INTO dais_identities (id, did, default_email, default_wallet, trust_level) VALUES ($1, $2, $3, $4, $5) RETURNING *`, [id, did, request.email || null, request.walletAddress || null, 'agent'] ); // Add email if provided if (request.email) { await db.query( `INSERT INTO dais_emails (dais_id, email, verified) VALUES ($1, $2, false)`, [id, request.email] ); } // Add wallet if provided if (request.walletAddress) { await db.query( `INSERT INTO dais_wallets (dais_id, wallet_address, network, verified) VALUES ($1, $2, $3, false)`, [id, request.walletAddress, request.network || 'evm'] ); } // Create agent linked to DAIS const agentId = `agent-${uuidv4()}`; const matrixHandle = `@${agentId}:matrix.daarion.city`; await db.query( `INSERT INTO agents (id, name, kind, dais_identity_id, agent_role, home_microdao_id) VALUES ($1, $2, $3, $4, $5, $6)`, [agentId, 'New Agent', 'personal', id, 'regular', 'daarion'] ); // Update DAIS with matrix handle await db.query( `UPDATE dais_identities SET matrix_handle = $1 WHERE id = $2`, [matrixHandle, id] ); logger.info(`Created DAIS identity: ${id}, agent: ${agentId}`); return { identity: identity.rows[0], agentId, matrixHandle, }; } catch (error) { logger.error('Failed to create DAIS identity', error); throw error; } } /** * Get DAIS profile with all linked identities */ async getProfile(daisId: string): Promise { try { const identity = await db.query( `SELECT * FROM dais_identities WHERE id = $1`, [daisId] ); if (identity.rows.length === 0) { return null; } const emails = await db.query( `SELECT * FROM dais_emails WHERE dais_id = $1`, [daisId] ); const wallets = await db.query( `SELECT * FROM dais_wallets WHERE dais_id = $1`, [daisId] ); const keys = await db.query( `SELECT * FROM dais_keys WHERE dais_id = $1 AND revoked_at IS NULL`, [daisId] ); return { identity: identity.rows[0], emails: emails.rows, wallets: wallets.rows, keys: keys.rows, }; } catch (error) { logger.error(`Failed to get DAIS profile: ${daisId}`, error); throw error; } } /** * Get DAIS by agent ID */ async getByAgentId(agentId: string): Promise { try { const agent = await db.query( `SELECT dais_identity_id FROM agents WHERE id = $1`, [agentId] ); if (agent.rows.length === 0 || !agent.rows[0].dais_identity_id) { return null; } return this.getProfile(agent.rows[0].dais_identity_id); } catch (error) { logger.error(`Failed to get DAIS by agent: ${agentId}`, error); throw error; } } /** * Add email to DAIS */ async addEmail(daisId: string, email: string): Promise { try { const result = await db.query( `INSERT INTO dais_emails (dais_id, email, verified) VALUES ($1, $2, false) RETURNING *`, [daisId, email] ); logger.info(`Added email to DAIS ${daisId}: ${email}`); return result.rows[0]; } catch (error) { logger.error(`Failed to add email to DAIS: ${daisId}`, error); throw error; } } /** * Verify email */ async verifyEmail(daisId: string, email: string): Promise { try { await db.query( `UPDATE dais_emails SET verified = true, verified_at = now() WHERE dais_id = $1 AND email = $2`, [daisId, email] ); // Update trust level if this is first verified email await this.updateTrustLevel(daisId); logger.info(`Verified email for DAIS ${daisId}: ${email}`); } catch (error) { logger.error(`Failed to verify email: ${daisId}`, error); throw error; } } /** * Add wallet to DAIS */ async addWallet( daisId: string, walletAddress: string, network: 'evm' | 'ton' | 'solana' = 'evm' ): Promise { try { const result = await db.query( `INSERT INTO dais_wallets (dais_id, wallet_address, network, verified) VALUES ($1, $2, $3, false) RETURNING *`, [daisId, walletAddress, network] ); logger.info(`Added wallet to DAIS ${daisId}: ${walletAddress}`); return result.rows[0]; } catch (error) { logger.error(`Failed to add wallet to DAIS: ${daisId}`, error); throw error; } } /** * Verify wallet (after SIWE signature) */ async verifyWallet(daisId: string, walletAddress: string): Promise { try { await db.query( `UPDATE dais_wallets SET verified = true, verified_at = now() WHERE dais_id = $1 AND wallet_address = $2`, [daisId, walletAddress] ); // Update trust level await this.updateTrustLevel(daisId); logger.info(`Verified wallet for DAIS ${daisId}: ${walletAddress}`); } catch (error) { logger.error(`Failed to verify wallet: ${daisId}`, error); throw error; } } /** * Update trust level based on verified identities */ private async updateTrustLevel(daisId: string): Promise { const profile = await this.getProfile(daisId); if (!profile) return; const hasVerifiedEmail = profile.emails.some(e => e.verified); const hasVerifiedWallet = profile.wallets.some(w => w.verified); let newLevel: DaisTrustLevel = 'guest'; if (hasVerifiedEmail && hasVerifiedWallet) { newLevel = 'verified'; } else if (hasVerifiedEmail) { newLevel = 'agent'; } await db.query( `UPDATE dais_identities SET trust_level = $1, updated_at = now() WHERE id = $2`, [newLevel, daisId] ); } /** * Promote agent to orchestrator (updates DAIS trust level) */ async promoteToOrchestrator(daisId: string): Promise { try { await db.query( `UPDATE dais_identities SET trust_level = 'orchestrator', updated_at = now() WHERE id = $1`, [daisId] ); logger.info(`Promoted DAIS to orchestrator: ${daisId}`); } catch (error) { logger.error(`Failed to promote to orchestrator: ${daisId}`, error); throw error; } } } export const daisService = new DaisService();