UNPKG

@ghostspeak/sdk

Version:

TypeScript SDK for GhostSpeak AI Agent Commerce Protocol - Production Ready Beta

343 lines (342 loc) 11.4 kB
// src/modules/credentials/CrossmintVCClient.ts var CROSSMINT_STAGING_URL = "https://staging.crossmint.com"; var CROSSMINT_PROD_URL = "https://www.crossmint.com"; var GHOSTSPEAK_CREDENTIAL_TYPES = { AGENT_IDENTITY: "GhostSpeakAgentIdentity", REPUTATION_SCORE: "GhostSpeakReputation", JOB_COMPLETION: "GhostSpeakJobCompletion" }; var CrossmintVCClient = class { apiKey; baseUrl; chain; constructor(options) { this.apiKey = options.apiKey; this.baseUrl = options.environment === "production" ? CROSSMINT_PROD_URL : CROSSMINT_STAGING_URL; this.chain = options.chain || "base-sepolia"; } // =================================== // Types & Templates // =================================== /** * Create the GhostSpeak Agent Identity credential type */ async createAgentIdentityType() { const typeName = GHOSTSPEAK_CREDENTIAL_TYPES.AGENT_IDENTITY; const schema = { $schema: "https://json-schema.org/draft/2020-12/schema", title: "GhostSpeak Agent Identity", description: "Verified AI agent identity on the GhostSpeak Protocol", type: "object", properties: { credentialSubject: { type: "object", properties: { agentId: { type: "string" }, owner: { type: "string" }, capabilities: { type: "array", items: { type: "string" } }, registeredAt: { type: "string" }, reputationScore: { type: "number" }, totalJobsCompleted: { type: "integer" }, verified: { type: "boolean" }, id: { type: "string" } // Auto-added by Crossmint }, required: ["agentId", "owner", "capabilities", "registeredAt", "verified"], additionalProperties: false } } }; return this.createCredentialType(typeName, schema); } /** * Create the GhostSpeak Reputation credential type */ async createReputationType() { const typeName = GHOSTSPEAK_CREDENTIAL_TYPES.REPUTATION_SCORE; const schema = { $schema: "https://json-schema.org/draft/2020-12/schema", title: "GhostSpeak Reputation", description: "Verified reputation score for GhostSpeak users", type: "object", properties: { credentialSubject: { type: "object", properties: { userId: { type: "string" }, walletAddress: { type: "string" }, reputationScore: { type: "number" }, totalTransactions: { type: "integer" }, disputeRate: { type: "number" }, memberSince: { type: "string" }, id: { type: "string" } }, required: ["userId", "walletAddress", "reputationScore", "memberSince"], additionalProperties: false } } }; return this.createCredentialType(typeName, schema); } /** * Create the GhostSpeak Job Completion credential type */ async createJobCompletionType() { const typeName = GHOSTSPEAK_CREDENTIAL_TYPES.JOB_COMPLETION; const schema = { $schema: "https://json-schema.org/draft/2020-12/schema", title: "GhostSpeak Job Completion", description: "Certificate of successful job completion on GhostSpeak", type: "object", properties: { credentialSubject: { type: "object", properties: { jobId: { type: "string" }, agentId: { type: "string" }, clientAddress: { type: "string" }, completedAt: { type: "string" }, amountPaid: { type: "string" }, rating: { type: "integer" }, review: { type: "string" }, id: { type: "string" } }, required: ["jobId", "agentId", "clientAddress", "completedAt", "amountPaid", "rating"], additionalProperties: false } } }; return this.createCredentialType(typeName, schema); } /** * Initialize all GhostSpeak credential types */ async initializeAllTypes() { const [agentIdentity, reputation, jobCompletion] = await Promise.all([ this.createAgentIdentityType(), this.createReputationType(), this.createJobCompletionType() ]); return { agentIdentity, reputation, jobCompletion }; } /** * Create all GhostSpeak credential templates */ async createAllTemplates(types) { const [agentIdentityTemplate, reputationTemplate, jobCompletionTemplate] = await Promise.all([ this.createTemplate(types.agentIdentity.id, { name: "GhostSpeak Agent Identity", description: "Verified AI agent identity on the GhostSpeak Protocol", imageUrl: "https://www.ghostspeak.io/assets/credential-agent.png" }), this.createTemplate(types.reputation.id, { name: "GhostSpeak Reputation", description: "Verified reputation score for GhostSpeak users", imageUrl: "https://www.ghostspeak.io/assets/credential-reputation.png" }), this.createTemplate(types.jobCompletion.id, { name: "GhostSpeak Job Completion Certificate", description: "Certificate of successful job completion on GhostSpeak", imageUrl: "https://www.ghostspeak.io/assets/credential-job.png" }) ]); return { agentIdentityTemplate, reputationTemplate, jobCompletionTemplate }; } /** * Issue an agent identity credential */ async issueAgentCredential(templateId, recipientEmail, subject, expiresAt) { return this.issueCredential(templateId, recipientEmail, subject, expiresAt); } /** * Issue a reputation credential */ async issueReputationCredential(templateId, recipientEmail, subject, expiresAt) { return this.issueCredential(templateId, recipientEmail, subject, expiresAt); } /** * Issue a job completion credential */ async issueJobCompletionCredential(templateId, recipientEmail, subject, expiresAt) { return this.issueCredential(templateId, recipientEmail, subject, expiresAt); } /** * Create a credential type (JSON Schema) */ async createCredentialType(typeName, schema) { const response = await fetch( `${this.baseUrl}/api/v1-alpha1/credentials/types/${typeName}`, { method: "PUT", headers: { "Content-Type": "application/json", "X-API-KEY": this.apiKey }, body: JSON.stringify(schema) } ); if (!response.ok) { const error = await response.json().catch(() => ({ message: response.statusText })); throw new Error(`Failed to create credential type: ${JSON.stringify(error)}`); } return response.json(); } /** * Create a credential template */ async createTemplate(typeId, metadata) { const response = await fetch( `${this.baseUrl}/api/v1-alpha1/credentials/templates/`, { method: "POST", headers: { "Content-Type": "application/json", "X-API-KEY": this.apiKey }, body: JSON.stringify({ credentials: { type: typeId, encryption: "none", storage: "crossmint" }, metadata, chain: this.chain }) } ); if (!response.ok) { const text = await response.text(); try { const error = JSON.parse(text); throw new Error(`Failed to create template: ${JSON.stringify(error)}`); } catch (e) { throw new Error(`Failed to create template (${response.status}): ${text}`); } } const action = await response.json(); const result = await this.waitForAction(action.id); if (result.data && result.data.collection) { return result.data.collection; } return result.data || result; } /** * Poll an action until completion */ async waitForAction(actionId) { let retries = 0; while (retries < 60) { await new Promise((resolve) => setTimeout(resolve, 2e3)); const response = await fetch( `${this.baseUrl}/api/2022-06-09/actions/${actionId}`, { headers: { "X-API-KEY": this.apiKey } } ); if (!response.ok) { throw new Error(`Failed to poll action: ${response.statusText}`); } const action = await response.json(); if (action.status === "succeeded") { return action; } if (action.status === "failed") { throw new Error(`Action failed: ${JSON.stringify(action)}`); } retries++; } throw new Error("Action polling timed out"); } // =================================== // Issuance // =================================== /** * Issue a credential using a template */ async issueCredential(templateId, recipientEmail, subject, expiresAt) { const response = await fetch( `${this.baseUrl}/api/v1-alpha1/credentials/templates/${templateId}/vcs`, { method: "POST", headers: { "Content-Type": "application/json", "X-API-KEY": this.apiKey }, body: JSON.stringify({ recipient: `email:${recipientEmail}:${this.chain}`, credential: { subject, expiresAt: expiresAt || this.getDefaultExpiry() } }) } ); if (!response.ok) { const error = await response.json().catch(() => ({ message: response.statusText })); throw new Error(`Failed to issue credential: ${JSON.stringify(error)}`); } return response.json(); } // =================================== // Verification & Retrieval // =================================== async getCredential(credentialId) { const response = await fetch( `${this.baseUrl}/api/v1-alpha1/credentials/${credentialId}`, { headers: { "X-API-KEY": this.apiKey } } ); if (!response.ok) { const error = await response.json().catch(() => ({ message: response.statusText })); throw new Error(`Failed to get credential: ${JSON.stringify(error)}`); } return response.json(); } async verifyCredential(credential) { const response = await fetch( `${this.baseUrl}/api/v1-alpha1/credentials/verification/verify`, { method: "POST", headers: { "Content-Type": "application/json", "X-API-KEY": this.apiKey }, body: JSON.stringify({ credential }) } ); if (!response.ok) { const error = await response.json().catch(() => ({ message: response.statusText })); throw new Error(`Failed to verify credential: ${JSON.stringify(error)}`); } return response.json(); } async revokeCredential(credentialId) { const response = await fetch( `${this.baseUrl}/api/v1-alpha1/credentials/${credentialId}`, { method: "DELETE", headers: { "X-API-KEY": this.apiKey } } ); if (!response.ok) { const error = await response.json().catch(() => ({ message: response.statusText })); throw new Error(`Failed to revoke credential: ${JSON.stringify(error)}`); } return response.json(); } getDefaultExpiry() { const date = /* @__PURE__ */ new Date(); date.setFullYear(date.getFullYear() + 1); return date.toISOString().split("T")[0]; } }; export { CrossmintVCClient, GHOSTSPEAK_CREDENTIAL_TYPES }; //# sourceMappingURL=chunk-RIZZPLLB.js.map //# sourceMappingURL=chunk-RIZZPLLB.js.map