Skip to main content
Glama
AlyssonM

HiveAuth MCP Server

by AlyssonM
submitPresentation.ts7.4 kB
import { CallToolResult } from '@modelcontextprotocol/sdk/types.js'; import { validateAndSanitizeInput, createValidationErrorResult } from '../utils/validation.js'; import { TOOL_SCHEMAS, type SubmitPresentationInput } from '../schemas/toolSchemas.js'; /** * Submit a presentation based on evaluation results * Creates a verifiable presentation that satisfies the presentation definition requirements */ export async function submitPresentation(args: unknown): Promise<CallToolResult> { const validation = validateAndSanitizeInput( TOOL_SCHEMAS.submit_presentation, args, 'submit_presentation' ); if (!validation.success) { return createValidationErrorResult(validation.error!); } const data = validation.data!; const startTime = Date.now(); try { // First evaluate which credentials match the presentation definition const evaluationResponse = await fetch(`${process.env.HIVEAUTH_API_BASE_URL}/api/presentation/evaluate`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ presentationDefinition: data.presentationDefinition, credentials: data.credentials }) }); if (!evaluationResponse.ok) { const errorText = await evaluationResponse.text(); throw new Error(`Evaluation failed (${evaluationResponse.status}): ${errorText}`); } const evaluationResult = await evaluationResponse.json(); // Check if evaluation was successful if (!evaluationResult.success || !evaluationResult.data) { return { content: [ { type: 'text', text: `❌ **Presentation Submission Failed** **Error:** Credentials do not satisfy presentation definition requirements **Evaluation Result:** ${JSON.stringify(evaluationResult, null, 2)} **Resolution:** Ensure provided credentials match the input descriptors and constraints specified in the presentation definition.` } ], isError: true }; } // Now submit the presentation with the matching credentials const submissionResponse = await fetch(`${process.env.HIVEAUTH_API_BASE_URL}/api/presentation/submit`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ presentationDefinition: data.presentationDefinition, credentials: data.credentials, holderDid: data.holderDid, challenge: data.challenge, domain: data.domain }) }); if (!submissionResponse.ok) { const errorText = await submissionResponse.text(); throw new Error(`Submission failed (${submissionResponse.status}): ${errorText}`); } const submissionResult = await submissionResponse.json(); const processingTime = Date.now() - startTime; if (!submissionResult.success) { return { content: [ { type: 'text', text: `❌ **Presentation Submission Failed** **Error:** ${submissionResult.error || 'Unknown submission error'} **Processing Time:** ${processingTime}ms **Evaluation Results:** ${JSON.stringify(evaluationResult.data, null, 2)} **Debug Info:** Check that all required credentials are present and valid.` } ], isError: true }; } // Analyze the submitted presentation const presentation = submissionResult.data.presentation; const presentationSubmission = submissionResult.data.presentationSubmission; const credentialCount = Array.isArray(presentation.verifiableCredential) ? presentation.verifiableCredential.length : 1; const inputDescriptorIds = data.presentationDefinition.input_descriptors.map(desc => desc.id); const submittedDescriptors = presentationSubmission?.descriptor_map?.map((desc: any) => desc.id) || []; const fulfillmentStatus = inputDescriptorIds.map(id => ({ inputDescriptorId: id, fulfilled: submittedDescriptors.includes(id), descriptor: data.presentationDefinition.input_descriptors.find(desc => desc.id === id) })); const allRequirementsMet = fulfillmentStatus.every(status => status.fulfilled); return { content: [ { type: 'text', text: `✅ **Presentation Submission Successful** **Submission Status:** ${allRequirementsMet ? 'All requirements satisfied' : 'Partial fulfillment'} **Processing Time:** ${processingTime}ms **Credentials Included:** ${credentialCount} **Presentation ID:** ${presentation.id || 'Generated'} **📋 Requirement Fulfillment:** ${fulfillmentStatus.map(status => `• ${status.fulfilled ? '✅' : '❌'} **${status.inputDescriptorId}**: ${status.descriptor?.purpose || status.descriptor?.name || 'No description'}` ).join('\n')} **🎯 Presentation Submission Details:** • **Definition ID:** ${data.presentationDefinition.id} • **Definition Purpose:** ${data.presentationDefinition.purpose || 'Not specified'} • **Holder DID:** ${data.holderDid || presentation.holder || 'Not specified'} • **Challenge:** ${data.challenge ? 'Included' : 'Not provided'} • **Domain:** ${data.domain || 'Not specified'} **📊 Submission Summary:** • **Input Descriptors:** ${inputDescriptorIds.length} required • **Submitted Descriptors:** ${submittedDescriptors.length} fulfilled • **Success Rate:** ${Math.round((submittedDescriptors.length / inputDescriptorIds.length) * 100)}% **🔒 Security Features:** • **Holder Binding:** ${presentation.holder ? 'Verified' : 'Anonymous'} • **Challenge-Response:** ${data.challenge ? 'Protected' : 'Open'} • **Domain Binding:** ${data.domain ? 'Domain-specific' : 'Cross-domain'} • **Proof Type:** ${presentation.proof?.type || 'Not specified'} **📄 Generated Presentation:** \`\`\`json ${JSON.stringify(presentation, null, 2)} \`\`\` **📋 Presentation Submission:** \`\`\`json ${JSON.stringify(presentationSubmission, null, 2)} \`\`\` ${allRequirementsMet ? '🎉 **Ready for verification** - This presentation can now be submitted to verifiers for validation.' : '⚠️ **Partial fulfillment** - Some requirements may not be met. Review the fulfillment status above.'} ` } ] }; } catch (error: any) { const processingTime = Date.now() - startTime; return { content: [ { type: 'text', text: `❌ **Presentation Submission Error** **Error:** ${error.message} **Processing Time:** ${processingTime}ms **Tool:** submit_presentation **📋 Input Summary:** • **Definition ID:** ${data.presentationDefinition.id} • **Credentials Count:** ${data.credentials.length} • **Holder DID:** ${data.holderDid || 'Not specified'} **🔧 Troubleshooting:** 1. **API Connectivity:** Ensure HiveAuth API is accessible at ${process.env.HIVEAUTH_API_BASE_URL} 2. **Credential Validity:** Verify all credentials are valid and properly formatted 3. **Definition Compliance:** Check that credentials meet presentation definition requirements 4. **Network Issues:** Verify network connectivity and API endpoint availability **🌐 API Endpoints Used:** • Evaluation: \`/api/presentation/evaluate\` • Submission: \`/api/presentation/submit\` For detailed debugging, check the HiveAuth API logs and ensure all required services are running.` } ], isError: true }; } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/AlyssonM/hiveauth-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server