UNPKG

@ghostspeak/sdk

Version:

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

1,581 lines (1,576 loc) 57.9 kB
import { CredentialModule, BaseModule, generateDidString, validateDidString, deriveDidDocumentPda, parseDidString, didDocumentToJson, exportAsW3CDidDocument, isDidActive, createEd25519VerificationMethod, createServiceEndpoint, AgentModule, GhostModule, GovernanceModule, MultisigModule, ReputationModule, init_MultiSourceAggregator, MultiSourceAggregator_exports, StakingModule } from './chunk-63A7F2YP.js'; import { createSignedAuthorization, verifyAuthorizationSignature, isAuthorizationExpired, isAuthorizationExhausted, serializeAuthorization, deserializeAuthorization, getAuthorizationId } from './chunk-QWQTPTZ4.js'; import { PRIVACY_CONSTANTS, PrivacyPresets, init_reputation_tag_engine, reputation_tag_engine_exports } from './chunk-HIDBANFS.js'; import { GHOSTSPEAK_MARKETPLACE_PROGRAM_ADDRESS } from './chunk-AWMGX3OX.js'; import { CrossmintVCClient } from './chunk-RIZZPLLB.js'; import { __toCommonJS } from './chunk-UP2VWCW5.js'; import { address } from '@solana/addresses'; // src/modules/credentials/UnifiedCredentialService.ts var UnifiedCredentialService = class { constructor(config) { this.config = config; this.credentialModule = new CredentialModule(config.programId); if (config.crossmint) { this.crossmintClient = new CrossmintVCClient(config.crossmint); } } credentialModule; crossmintClient; /** * Issue an Agent Identity credential. * Note: logic simplified for SDK usage (mocking the on-chain part for now as per original implementation) */ async issueAgentIdentityCredential(params) { const subjectData = CredentialModule.buildAgentIdentitySubject({ agentId: params.agentId, owner: params.owner, name: params.name, capabilities: params.capabilities, serviceEndpoint: params.serviceEndpoint, frameworkOrigin: params.frameworkOrigin, x402Enabled: params.x402Enabled, registeredAt: params.registeredAt, verifiedAt: params.verifiedAt }); const credentialId = this.credentialModule.generateCredentialId( "AgentIdentity" /* AgentIdentity */, params.owner ); const subjectDataHash = this.credentialModule.hashSubjectData(subjectData); const credential = { template: "11111111111111111111111111111111", // Placeholder Address subject: params.owner, issuer: params.owner, // Self-issued for agent identity usually, or program credentialId, subjectDataHash, subjectDataUri: `ipfs://placeholder/${credentialId}`, status: "Active" /* Active */, signature: params.signature, // Use provided signature issuedAt: Math.floor(Date.now() / 1e3), expiresAt: void 0, revokedAt: void 0, crossmintCredentialId: void 0 }; const mockType = { authority: "11111111111111111111111111111111", name: "AgentIdentity", kind: "AgentIdentity" /* AgentIdentity */, schemaUri: "https://ghostspeak.io/schemas/agent-identity.json", description: "Verified AI agent identity on GhostSpeak Protocol", isActive: true, totalIssued: 1, createdAt: Math.floor(Date.now() / 1e3) }; const mockTemplate = { credentialType: "11111111111111111111111111111111", name: "GhostSpeak Agent Identity", imageUri: "https://www.ghostspeak.io/assets/credential-agent.png", issuer: params.owner, isActive: true, totalIssued: 1, createdAt: Math.floor(Date.now() / 1e3), crossmintTemplateId: this.config.crossmintTemplates?.agentIdentity }; const w3cCredential = this.credentialModule.exportAsW3CCredential( credential, mockTemplate, mockType, subjectData ); const result = { solanaCredential: { credentialId }, w3cCredential }; if (params.syncToCrossmint && this.crossmintClient && params.recipientEmail) { if (!mockTemplate.crossmintTemplateId) { result.crossmintSync = { status: "failed", error: "No template ID configured" }; } else { try { const crossmintResult = await this.crossmintClient.issueCredential( mockTemplate.crossmintTemplateId, params.recipientEmail, subjectData // enrichedSubject... logic handled here or in client? // In web it was in syncToCrossmint. ); result.crossmintSync = { status: "synced", credentialId: crossmintResult.credentialId, chain: this.config.crossmint?.chain }; } catch (error) { result.crossmintSync = { status: "failed", error: error instanceof Error ? error.message : "Unknown error" }; } } } return result; } }; var DidModule = class extends BaseModule { constructor(config) { super(config); } // ============================================================================ // DID CRUD Operations // ============================================================================ /** * Create a new DID document * * @param signer - Transaction signer (will be the controller) * @param params - DID creation parameters * @returns Transaction signature * * @example * ```typescript * const signature = await didModule.create(signer, { * controller: signer.address, * network: 'devnet', * verificationMethods: [{ * id: 'key-1', * methodType: VerificationMethodType.Ed25519VerificationKey2020, * controller: 'did:sol:devnet:...', * publicKeyMultibase: 'z...', * relationships: [VerificationRelationship.Authentication], * createdAt: Date.now() / 1000, * revoked: false * }] * }) * ``` */ async create(signer, params) { const network = params.network || "devnet"; const didString = generateDidString(network, params.controller); validateDidString(didString); const [didDocumentPda] = await deriveDidDocumentPda( this.programId, params.controller ); const instructionGetter = async () => { return this.buildCreateDidInstruction( didDocumentPda, params.controller, didString, params.verificationMethods || [], params.serviceEndpoints || [] ); }; return this.execute( "createDidDocument", instructionGetter, [signer] ); } /** * Update an existing DID document * * @param signer - Transaction signer (must be the controller) * @param params - Update parameters * @returns Transaction signature * * @example * ```typescript * const signature = await didModule.update(signer, { * didDocument: didPda, * addVerificationMethod: { * id: 'key-2', * methodType: VerificationMethodType.X25519KeyAgreementKey2020, * controller: 'did:sol:devnet:...', * publicKeyMultibase: 'z...', * relationships: [VerificationRelationship.KeyAgreement], * createdAt: Date.now() / 1000, * revoked: false * } * }) * ``` */ async update(signer, params) { const instructionGetter = async () => { return this.buildUpdateDidInstruction( params.didDocument, signer.address, params.addVerificationMethod || null, params.removeVerificationMethodId || null, params.addServiceEndpoint || null, params.removeServiceEndpointId || null ); }; return this.execute( "updateDidDocument", instructionGetter, [signer] ); } /** * Deactivate a DID document (irreversible) * * @param signer - Transaction signer (must be the controller) * @param params - Deactivation parameters * @returns Transaction signature * * @example * ```typescript * const signature = await didModule.deactivate(signer, { * didDocument: didPda * }) * ``` */ async deactivate(signer, params) { const instructionGetter = async () => { return this.buildDeactivateDidInstruction( params.didDocument, signer.address ); }; return this.execute( "deactivateDidDocument", instructionGetter, [signer] ); } /** * Resolve a DID document * * @param didOrController - DID string or controller address * @returns DID document or null if not found * * @example * ```typescript * // Resolve by controller address * const didDoc = await didModule.resolve(controllerAddress) * * // Resolve by DID string * const didDoc = await didModule.resolve('did:sol:devnet:5VKz...') * ``` */ async resolve(didOrController) { let controllerAddress; if (typeof didOrController === "string" && didOrController.startsWith("did:sol:")) { const { identifier } = parseDidString(didOrController); controllerAddress = address(identifier); } else { controllerAddress = typeof didOrController === "string" ? address(didOrController) : didOrController; } const [didDocumentPda] = await deriveDidDocumentPda( this.programId, controllerAddress ); return this.getAccount(didDocumentPda, "getDidDocumentDecoder"); } // ============================================================================ // W3C Export // ============================================================================ /** * Export a DID document as W3C-compliant JSON * * @param didOrController - DID string or controller address * @param pretty - Whether to pretty-print the JSON * @returns W3C DID document JSON string * * @example * ```typescript * const json = await didModule.exportW3C(controllerAddress, true) * console.log(json) * ``` */ async exportW3C(didOrController, pretty = true) { const didDoc = await this.resolve(didOrController); if (!didDoc) return null; return didDocumentToJson(didDoc, pretty); } /** * Get W3C DID document object * * @param didOrController - DID string or controller address * @returns W3C DID document object or null */ async getW3CDocument(didOrController) { const didDoc = await this.resolve(didOrController); if (!didDoc) return null; return exportAsW3CDidDocument(didDoc); } // ============================================================================ // Helper Methods // ============================================================================ /** * Derive DID document PDA for a controller * * @param controller - Controller address * @returns DID document PDA and bump */ async deriveDidPda(controller) { return deriveDidDocumentPda(this.programId, controller); } /** * Generate a DID string for a controller * * @param controller - Controller address * @param network - Network identifier * @returns DID string */ generateDid(controller, network = "devnet") { return generateDidString(network, controller); } /** * Validate a DID string * * @param did - DID string to validate * @returns True if valid, throws error if invalid */ validateDid(did) { validateDidString(did); return true; } /** * Check if a DID is active * * @param didOrController - DID string or controller address * @returns True if active, false if deactivated or not found */ async isActive(didOrController) { const didDoc = await this.resolve(didOrController); if (!didDoc) return false; return isDidActive(didDoc); } // ============================================================================ // Manual Instruction Builders (until code generation) // ============================================================================ /** * Build create DID instruction manually * Note: This is temporary until DID instructions are generated from IDL */ buildCreateDidInstruction(didDocument, controller, didString, verificationMethods, serviceEndpoints) { throw new Error( "DID instructions are not yet generated. Please run: bun run generate:client after adding DID instructions to the program." ); } /** * Build update DID instruction manually * Note: This is temporary until DID instructions are generated from IDL */ buildUpdateDidInstruction(didDocument, controller, addVerificationMethod, removeVerificationMethodId, addServiceEndpoint, removeServiceEndpointId) { throw new Error( "DID instructions are not yet generated. Please run: bun run generate:client after adding DID instructions to the program." ); } /** * Build deactivate DID instruction manually * Note: This is temporary until DID instructions are generated from IDL */ buildDeactivateDidInstruction(didDocument, controller) { throw new Error( "DID instructions are not yet generated. Please run: bun run generate:client after adding DID instructions to the program." ); } // ============================================================================ // Exported Helper Functions (re-export for convenience) // ============================================================================ /** * Create an Ed25519 verification method */ static createVerificationMethod = createEd25519VerificationMethod; /** * Create a service endpoint */ static createServiceEndpoint = createServiceEndpoint; }; // src/modules/privacy/privacy-helpers.ts function calculateVisibleScore(score, privacyMode, hasAccess) { if (hasAccess || privacyMode === "Public" /* Public */) { return { exactScore: score, tier: getReputationTier(score), scoreRange: getScoreRange(score) }; } switch (privacyMode) { case "TierOnly" /* TierOnly */: return { tier: getReputationTier(score) }; case "RangeOnly" /* RangeOnly */: return { scoreRange: getScoreRange(score) }; case "Confidential" /* Confidential */: return {}; case "Custom" /* Custom */: return { tier: getReputationTier(score), scoreRange: getScoreRange(score) }; default: return {}; } } function getReputationTier(score) { if (score >= PRIVACY_CONSTANTS.TIER_THRESHOLDS.PLATINUM) { return "Platinum" /* Platinum */; } else if (score >= PRIVACY_CONSTANTS.TIER_THRESHOLDS.GOLD) { return "Gold" /* Gold */; } else if (score >= PRIVACY_CONSTANTS.TIER_THRESHOLDS.SILVER) { return "Silver" /* Silver */; } else if (score >= PRIVACY_CONSTANTS.TIER_THRESHOLDS.BRONZE) { return "Bronze" /* Bronze */; } return "None" /* None */; } function getScoreRange(score) { const ranges = PRIVACY_CONSTANTS.SCORE_RANGES; if (score >= ranges.VERY_HIGH.min) { return "VeryHigh" /* VeryHigh */; } else if (score >= ranges.HIGH.min) { return "High" /* High */; } else if (score >= ranges.MEDIUM.min) { return "Medium" /* Medium */; } else if (score >= ranges.LOW.min) { return "Low" /* Low */; } return "VeryLow" /* VeryLow */; } function canViewerAccess(viewerAddress, settings, agentAddress) { if (viewerAddress === agentAddress) { return true; } return settings.authorizedViewers.includes(viewerAddress); } function filterMetricsByVisibility(reputationData, metricVisibility, hasAccess) { const result = { agent: reputationData.agent }; const isVisible = (level) => { return hasAccess || level === "Public" /* Public */; }; if (isVisible(metricVisibility.showScore)) { result.exactScore = reputationData.overallScore; } if (isVisible(metricVisibility.showJobsCompleted)) { result.totalJobsCompleted = reputationData.totalJobsCompleted; } if (isVisible(metricVisibility.showSuccessRate)) { const total = reputationData.totalJobsCompleted + reputationData.totalJobsFailed; result.successRate = total > 0 ? reputationData.totalJobsCompleted / total * 100 : 0; } if (isVisible(metricVisibility.showResponseTime)) { result.avgResponseTime = reputationData.avgResponseTime; } if (isVisible(metricVisibility.showDisputes)) { result.disputes = { total: reputationData.disputesAgainst, resolved: reputationData.disputesResolved }; } if (isVisible(metricVisibility.showEarnings) && reputationData.totalEarnings !== void 0) { result.totalEarnings = reputationData.totalEarnings; } if (isVisible(metricVisibility.showRatings) && reputationData.avgRating !== void 0) { result.avgRating = reputationData.avgRating; } if (isVisible(metricVisibility.showBadges) && reputationData.badges !== void 0) { result.badges = reputationData.badges; } result.hasFullAccess = hasAccess; return result; } function getDefaultMetricVisibility(mode) { switch (mode) { case "Public" /* Public */: return { showScore: "Public" /* Public */, showJobsCompleted: "Public" /* Public */, showSuccessRate: "Public" /* Public */, showResponseTime: "Public" /* Public */, showDisputes: "Public" /* Public */, showEarnings: "Public" /* Public */, showRatings: "Public" /* Public */, showBadges: "Public" /* Public */ }; case "TierOnly" /* TierOnly */: case "RangeOnly" /* RangeOnly */: return { showScore: "Private" /* Private */, showJobsCompleted: "Private" /* Private */, showSuccessRate: "Private" /* Private */, showResponseTime: "Private" /* Private */, showDisputes: "Private" /* Private */, showEarnings: "Private" /* Private */, showRatings: "Private" /* Private */, showBadges: "Public" /* Public */ }; case "Confidential" /* Confidential */: return { showScore: "ZKProof" /* ZKProof */, showJobsCompleted: "ZKProof" /* ZKProof */, showSuccessRate: "ZKProof" /* ZKProof */, showResponseTime: "ZKProof" /* ZKProof */, showDisputes: "ZKProof" /* ZKProof */, showEarnings: "ZKProof" /* ZKProof */, showRatings: "ZKProof" /* ZKProof */, showBadges: "ZKProof" /* ZKProof */ }; case "Custom" /* Custom */: default: return { showScore: "Private" /* Private */, showJobsCompleted: "Public" /* Public */, showSuccessRate: "Public" /* Public */, showResponseTime: "Public" /* Public */, showDisputes: "Private" /* Private */, showEarnings: "Private" /* Private */, showRatings: "Public" /* Public */, showBadges: "Public" /* Public */ }; } } function validatePrivacySettings(settings) { const errors = []; if (settings.authorizedViewers.length > PRIVACY_CONSTANTS.MAX_AUTHORIZED_VIEWERS) { errors.push( `Too many authorized viewers (max: ${PRIVACY_CONSTANTS.MAX_AUTHORIZED_VIEWERS})` ); } if (settings.mode === "Public" /* Public */) { const hasPrivateMetric = Object.values(settings.metricVisibility).some( (level) => level !== "Public" /* Public */ ); if (hasPrivateMetric) { errors.push("Public mode cannot have private metrics"); } } return { valid: errors.length === 0, errors }; } function getTierDisplayName(tier) { const names = { ["None" /* None */]: "Unranked", ["Bronze" /* Bronze */]: "Bronze", ["Silver" /* Silver */]: "Silver", ["Gold" /* Gold */]: "Gold", ["Platinum" /* Platinum */]: "Platinum" }; return names[tier]; } function getRangeDisplayString(range) { const ranges = { ["VeryLow" /* VeryLow */]: "0-2000", ["Low" /* Low */]: "2000-5000", ["Medium" /* Medium */]: "5000-7500", ["High" /* High */]: "7500-9000", ["VeryHigh" /* VeryHigh */]: "9000-10000" }; return ranges[range]; } // src/modules/privacy/PrivacyModule.ts var PrivacyModule = class extends BaseModule { constructor(config) { super(config); } /** * Initialize privacy settings for an agent * * Sets up privacy controls for an agent's reputation data. * By default, starts in Public mode with all metrics visible. * * @param signer - Transaction signer (must be agent owner) * @param params - Initialization parameters * @returns Transaction signature * * @example * ```typescript * const signature = await privacyModule.initializePrivacy(signer, { * agentAddress: agentPda, * mode: PrivacyMode.TierOnly, * metricVisibility: { * showScore: VisibilityLevel.Private, * showJobsCompleted: VisibilityLevel.Public, * // ... other metrics * } * }) * ``` */ async initializePrivacy(signer, params) { const mode = params.mode ?? "Public" /* Public */; params.metricVisibility ?? getDefaultMetricVisibility(mode); const instructionGetter = async () => { return { programAddress: this.programId, accounts: [], data: new Uint8Array([0]) // Placeholder }; }; return this.execute( "initializePrivacy", instructionGetter, [signer] ); } /** * Update privacy mode for an agent * * Changes how reputation data is displayed publicly. * * @param signer - Transaction signer (must be agent owner) * @param params - Update parameters * @returns Transaction signature * * @example * ```typescript * // Switch to tier-only mode * await privacyModule.updatePrivacyMode(signer, { * agentAddress: agentPda, * mode: PrivacyMode.TierOnly * }) * ``` */ async updatePrivacyMode(signer, params) { const instructionGetter = async () => { return { programAddress: this.programId, accounts: [], data: new Uint8Array([1]) // Placeholder }; }; return this.execute( "updatePrivacyMode", instructionGetter, [signer] ); } /** * Set metric visibility settings * * Configure selective disclosure for individual metrics. * Only works in Custom privacy mode. * * @param signer - Transaction signer (must be agent owner) * @param params - Metric visibility parameters * @returns Transaction signature * * @example * ```typescript * await privacyModule.setMetricVisibility(signer, { * agentAddress: agentPda, * metricVisibility: { * showScore: VisibilityLevel.Private, * showJobsCompleted: VisibilityLevel.Public, * showSuccessRate: VisibilityLevel.Public, * showResponseTime: VisibilityLevel.Public, * showDisputes: VisibilityLevel.Private, * showEarnings: VisibilityLevel.Private, * showRatings: VisibilityLevel.Public, * showBadges: VisibilityLevel.Public * } * }) * ``` */ async setMetricVisibility(signer, params) { const instructionGetter = async () => { return { programAddress: this.programId, accounts: [], data: new Uint8Array([2]) // Placeholder }; }; return this.execute( "setMetricVisibility", instructionGetter, [signer] ); } /** * Grant viewer access to private reputation data * * Adds an address to the authorized viewers list, giving them * full access to all private metrics. * * @param signer - Transaction signer (must be agent owner) * @param params - Grant access parameters * @returns Transaction signature * * @example * ```typescript * // Grant access to a client * await privacyModule.grantAccess(signer, { * agentAddress: agentPda, * viewer: clientAddress * }) * ``` */ async grantAccess(signer, params) { const instructionGetter = async () => { return { programAddress: this.programId, accounts: [], data: new Uint8Array([3]) // Placeholder }; }; return this.execute( "grantAccess", instructionGetter, [signer] ); } /** * Revoke viewer access to private reputation data * * Removes an address from the authorized viewers list. * * @param signer - Transaction signer (must be agent owner) * @param params - Revoke access parameters * @returns Transaction signature * * @example * ```typescript * // Revoke access from a viewer * await privacyModule.revokeAccess(signer, { * agentAddress: agentPda, * viewer: viewerAddress * }) * ``` */ async revokeAccess(signer, params) { const instructionGetter = async () => { return { programAddress: this.programId, accounts: [], data: new Uint8Array([4]) // Placeholder }; }; return this.execute( "revokeAccess", instructionGetter, [signer] ); } /** * Apply a privacy preset * * Quickly configure privacy settings using a predefined preset * (Conservative, Balanced, or Open). * * @param signer - Transaction signer (must be agent owner) * @param params - Preset parameters * @returns Transaction signature * * @example * ```typescript * // Apply balanced preset * await privacyModule.applyPreset(signer, { * agentAddress: agentPda, * preset: PrivacyPresets.BALANCED * }) * ``` */ async applyPreset(signer, params) { const { preset } = params; await this.updatePrivacyMode(signer, { agentAddress: params.agentAddress, mode: preset.mode }); return this.setMetricVisibility(signer, { agentAddress: params.agentAddress, metricVisibility: preset.metricVisibility }); } /** * Get privacy settings for an agent * * Fetches the current privacy configuration. * * @param agentAddress - Agent address * @returns Privacy settings or null if not initialized * * @example * ```typescript * const settings = await privacyModule.getPrivacySettings(agentPda) * if (settings) { * console.log('Privacy mode:', settings.mode) * console.log('Authorized viewers:', settings.authorizedViewers.length) * } * ``` */ async getPrivacySettings(agentAddress) { return { agent: agentAddress, mode: "Public" /* Public */, metricVisibility: getDefaultMetricVisibility("Public" /* Public */), authorizedViewers: [], autoGrantClients: false, updatedAt: Math.floor(Date.now() / 1e3) }; } /** * Get visible reputation data (privacy-filtered) * * Fetches reputation data and applies privacy filters based on * the viewer's access level. * * @param agentAddress - Agent address * @param viewerAddress - Viewer address (for access check) * @returns Privacy-filtered reputation data * * @example * ```typescript * // Get visible reputation for a specific viewer * const visibleRep = await privacyModule.getVisibleReputation( * agentPda, * viewerAddress * ) * * console.log('Tier:', visibleRep.tier) * console.log('Exact score:', visibleRep.exactScore) // Only if visible * console.log('Has full access:', visibleRep.hasFullAccess) * ``` */ async getVisibleReputation(agentAddress, viewerAddress) { let privacySettings = await this.getPrivacySettings(agentAddress); if (!privacySettings) { privacySettings = { agent: agentAddress, mode: "Public" /* Public */, metricVisibility: getDefaultMetricVisibility("Public" /* Public */), authorizedViewers: [], autoGrantClients: false, updatedAt: Math.floor(Date.now() / 1e3) }; } const hasAccess = canViewerAccess(viewerAddress, privacySettings, agentAddress); const reputationData = { agent: agentAddress, overallScore: 7500, // Mock data totalJobsCompleted: 100, totalJobsFailed: 5, avgResponseTime: 250, disputesAgainst: 2, disputesResolved: 2, totalEarnings: 5e4, avgRating: 4.5, badges: ["FirstJob", "TenJobs", "QuickResponder"] }; const visibleScore = calculateVisibleScore( reputationData.overallScore, privacySettings.mode, hasAccess ); const filteredMetrics = filterMetricsByVisibility( reputationData, privacySettings.metricVisibility, hasAccess ); return { ...filteredMetrics, privacyMode: privacySettings.mode, ...visibleScore, hasFullAccess: hasAccess }; } // ===================================================== // HELPER METHODS // ===================================================== /** * Validate privacy settings before applying * * @param settings - Privacy settings to validate * @returns Validation result */ validateSettings(settings) { return validatePrivacySettings(settings); } /** * Get available privacy presets * * @returns Record of available presets */ getAvailablePresets() { return PrivacyPresets; } /** * Get default metric visibility for a privacy mode * * @param mode - Privacy mode * @returns Default metric visibility */ getDefaultVisibility(mode) { return getDefaultMetricVisibility(mode); } /** * Calculate reputation tier from score * * @param score - Reputation score * @returns Reputation tier */ getTier(score) { return getReputationTier(score); } /** * Calculate score range from score * * @param score - Reputation score * @returns Score range */ getRange(score) { return getScoreRange(score); } // Private helper to derive privacy PDA (when privacy accounts are implemented) async derivePrivacyPda(agentAddress) { const { getProgramDerivedAddress, getAddressEncoder } = await import('@solana/addresses'); const addressEncoder = getAddressEncoder(); const agentBytes = addressEncoder.encode(agentAddress); const [pda] = await getProgramDerivedAddress({ programAddress: this.programId, seeds: [ new TextEncoder().encode("privacy_settings"), agentBytes ] }); return pda; } }; // src/modules/authorization/AuthorizationModule.ts var DEFAULT_STORAGE_FEE = 2000000n; var AuthorizationModule = class extends BaseModule { constructor(config) { super(config); } /** * Create a signed authorization for a facilitator * * @param params - Authorization parameters * @param agentKeypair - Agent's keypair for signing * @returns Signed authorization * * @example * ```typescript * const authorization = await client.authorization.createAuthorization({ * authorizedSource: payAIFacilitatorAddress, * indexLimit: 1000, // Allow 1000 reputation updates * expiresIn: 30 * 24 * 60 * 60, // 30 days * network: 'devnet', * }, agentKeypair) * ``` */ async createAuthorization(params, agentKeypair) { return await createSignedAuthorization(params, agentKeypair); } /** * Store authorization on-chain (optional, ~0.002 SOL fee) * * Creates a PDA account storing the authorization for on-chain verification. * This provides an immutable audit trail but costs rent (~0.002 SOL). * * **Cost vs Benefit:** * - Off-chain (default): Free, but requires sharing signed authorization * - On-chain: ~0.002 SOL, provides transparent audit trail * * **When to use on-chain storage:** * - High-value authorizations where transparency is critical * - Compliance/audit requirements * - Public agent reputation systems * * @param authorization - Authorization to store * @param agentSigner - Agent's signer (or facilitator if they pay fee) * @param config - Optional storage configuration * @returns Transaction signature * * @example * ```typescript * // Default: Agent pays ~0.002 SOL * const sig = await client.authorization.storeAuthorizationOnChain(auth, agentSigner) * * // Custom fee structure * const sig = await client.authorization.storeAuthorizationOnChain(auth, agentSigner, { * storageFee: 1500000n, // 0.0015 SOL * feePayedByAgent: false // Facilitator pays * }) * ``` */ async storeAuthorizationOnChain(authorization, agentSigner, config) { const storageFee = this.calculateStorageFee(authorization, config); const feePayedByAgent = config?.feePayedByAgent ?? true; console.log(`\u{1F4B0} On-chain storage cost: ${Number(storageFee) / 1e9} SOL`); console.log(` Fee payer: ${feePayedByAgent ? "Agent" : "Facilitator"}`); const { getCreateAgentAuthorizationInstructionAsync } = await import('./createAgentAuthorization-KGZNXZBT.js'); const { getProgramDerivedAddress, getBytesEncoder, getAddressEncoder, getUtf8Encoder } = await import('@solana/kit'); const nonce = authorization.nonce ?? "default"; const [authorizationPda] = await getProgramDerivedAddress({ programAddress: this.getProgramId(), seeds: [ getBytesEncoder().encode(new Uint8Array([97, 103, 101, 110, 116, 95, 97, 117, 116, 104])), // 'agent_auth' getAddressEncoder().encode(authorization.agentAddress), getAddressEncoder().encode(authorization.authorizedSource), getUtf8Encoder().encode(nonce) // Raw bytes, no size prefix - matches Rust .as_bytes() ] }); return await this.execute( "createAgentAuthorization", async () => { return await getCreateAgentAuthorizationInstructionAsync({ agent: authorization.agentAddress, authorization: authorizationPda, // Provide manually derived PDA authority: agentSigner, authorizedSource: authorization.authorizedSource, indexLimit: BigInt(authorization.indexLimit), expiresAt: BigInt(authorization.expiresAt), network: authorization.network === "mainnet-beta" ? 0 : authorization.network === "devnet" ? 1 : 2, signature: authorization.signature, nonce // Pass the actual nonce value }); }, [agentSigner] ); } /** * Verify authorization signature * * @param authorization - Authorization to verify * @returns True if signature is valid * * @example * ```typescript * const isValid = await client.authorization.verifySignature(authorization) * if (!isValid) { * throw new Error('Invalid authorization signature') * } * ``` */ async verifySignature(authorization) { return verifyAuthorizationSignature(authorization); } /** * Check authorization status (without on-chain call) * * @param authorization - Authorization to check * @param currentIndex - Current usage count (optional, defaults to authorization.currentIndex) * @returns Authorization status */ getAuthorizationStatus(authorization, currentIndex) { const now = Math.floor(Date.now() / 1e3); const idx = currentIndex ?? 0; if (isAuthorizationExpired(authorization, now)) { return { status: "expired", isValid: false, remainingUses: 0, reason: "Authorization has expired" }; } if (isAuthorizationExhausted(authorization, idx)) { return { status: "exhausted", isValid: false, remainingUses: 0, reason: "Index limit reached" }; } const remaining = authorization.indexLimit - idx; return { status: "active", isValid: true, remainingUses: remaining }; } /** * Fetch authorization from on-chain PDA * * @param agentAddress - Agent's address * @param authorizedSource - Authorized source address * @param nonce - Optional nonce (must match creation) * @returns Authorization with current on-chain status */ async fetchAuthorization(agentAddress, authorizedSource, nonce) { throw new Error("On-chain fetch not yet implemented - pending Codama generation"); } /** * Update reputation using authorization * * Called by facilitators (e.g., PayAI) to update agent reputation * using a pre-signed authorization. * * @param authorization - Authorization to use * @param reputationChange - Reputation change to apply * @param transactionSignature - Transaction signature for audit trail * @param usageRecord - PDA for usage record (audit trail) * @param metadata - Optional metadata * @param facilitatorSigner - Facilitator's signer * @returns Transaction signature */ async updateReputationWithAuth(authorization, reputationChange, transactionSignature, usageRecord, metadata, facilitatorSigner) { const isValid = await this.verifySignature(authorization); if (!isValid) { throw new Error("Invalid authorization signature"); } const status = this.getAuthorizationStatus(authorization); if (!status.isValid) { throw new Error(`Authorization is ${status.status}: ${status.reason}`); } const { getUpdateReputationWithAuthInstructionAsync } = await import('./updateReputationWithAuth-PCEUOCFV.js'); return await this.execute( "updateReputationWithAuth", async () => { return await getUpdateReputationWithAuthInstructionAsync({ agent: authorization.agentAddress, authorizedSource: facilitatorSigner, usageRecord, reputationChange: BigInt(reputationChange), transactionSignature, metadata: metadata ? JSON.stringify(metadata) : null, nonce: authorization.nonce ?? null }); }, [facilitatorSigner] ); } /** * Revoke authorization * * Agent can revoke an authorization before it expires or is exhausted. * * @param agentAddress - Agent's address * @param authorization - Authorization account PDA * @param nonce - Optional nonce (must match creation) * @param agentSigner - Agent's signer * @returns Transaction signature */ async revokeAuthorization(agentAddress, authorization, nonce, agentSigner) { const { getRevokeAuthorizationInstruction } = await import('./revokeAuthorization-2ZRO6GUZ.js'); return await this.execute( "revokeAuthorization", () => { return getRevokeAuthorizationInstruction({ agent: agentAddress, authorization, authority: agentSigner, nonce: nonce ?? null }); }, [agentSigner] ); } /** * List authorizations for an agent (filtering) * * @param filter - Filter criteria * @returns List of authorizations */ async listAuthorizations(filter) { throw new Error("Authorization listing not yet implemented - pending Codama generation"); } /** * Serialize authorization for storage/transmission * * @param authorization - Authorization to serialize * @returns JSON-safe object */ serializeAuthorization(authorization) { return serializeAuthorization(authorization); } /** * Deserialize authorization from storage/transmission * * @param data - Serialized authorization data * @returns Authorization object */ deserializeAuthorization(data) { return deserializeAuthorization(data); } /** * Get authorization ID (deterministic hash) * * @param authorization - Authorization to hash * @returns Base58-encoded hash */ async getAuthorizationId(authorization) { return getAuthorizationId(authorization); } /** * Helper: Create authorization for PayAI facilitator * * Convenience method with sensible defaults for PayAI integration. * * @param payAIFacilitatorAddress - PayAI facilitator address * @param agentKeypair - Agent's keypair * @param options - Optional overrides * @returns Signed authorization * * @example * ```typescript * const auth = await client.authorization.createPayAIAuthorization( * 'PayAI...FacilitatorAddress', * agentKeypair, * { indexLimit: 5000 } // Optional overrides * ) * ``` */ async createPayAIAuthorization(payAIFacilitatorAddress, agentKeypair, options) { const defaultParams = { authorizedSource: payAIFacilitatorAddress, indexLimit: 1e3, // 1000 reputation updates expiresIn: 30 * 24 * 60 * 60, // 30 days network: "devnet", // TODO: detect from client ...options }; return this.createAuthorization(defaultParams, agentKeypair); } /** * Calculate storage fee based on authorization duration and custom fees * * @param authorization - Authorization to calculate fee for * @param config - Storage configuration * @returns Fee in lamports * * @example * ```typescript * // Default fee: 0.002 SOL * const fee = module.calculateStorageFee(auth) * * // Custom fee for 30-day authorizations: 0.001 SOL * const fee = module.calculateStorageFee(auth, { * customFees: { 2592000: 1000000n } // 30 days = 0.001 SOL * }) * ``` */ calculateStorageFee(authorization, config) { if (config?.storageFee !== void 0) { return config.storageFee; } if (config?.customFees) { const now = Math.floor(Date.now() / 1e3); const duration = authorization.expiresAt - now; const durations = Object.keys(config.customFees).map(Number).sort((a, b) => a - b); for (const d of durations) { if (duration <= d) { return config.customFees[d]; } } const highestDuration = durations[durations.length - 1]; if (highestDuration && config.customFees[highestDuration]) { return config.customFees[highestDuration]; } } return DEFAULT_STORAGE_FEE; } /** * Estimate on-chain storage cost for an authorization * * @param params - Authorization parameters * @param config - Optional storage configuration * @returns Estimated cost in SOL * * @example * ```typescript * const costInSOL = await client.authorization.estimateStorageCost({ * authorizedSource: facilitatorAddress, * expiresIn: 30 * 24 * 60 * 60 // 30 days * }) * console.log(`On-chain storage will cost ${costInSOL} SOL`) * ``` */ async estimateStorageCost(params, config) { const now = Math.floor(Date.now() / 1e3); const mockAuth = { agentAddress: "11111111111111111111111111111111", // Placeholder authorizedSource: params.authorizedSource, indexLimit: params.indexLimit ?? 1e3, expiresAt: params.expiresAt ?? now + (params.expiresIn ?? 30 * 24 * 60 * 60), network: params.network ?? "devnet", signature: new Uint8Array(64), nonce: params.nonce }; const feeInLamports = this.calculateStorageFee(mockAuth, config); return Number(feeInLamports) / 1e9; } }; // src/core/GhostSpeakClient.ts var GhostSpeakClient = class { config; constructor(config) { this.config = { programId: GHOSTSPEAK_MARKETPLACE_PROGRAM_ADDRESS, commitment: "confirmed", cluster: "devnet", rpcEndpoint: config?.rpcEndpoint ?? this.getDefaultRpcEndpoint(config?.cluster ?? "devnet"), ...config, rpc: config?.rpc ?? {} }; } /** * Direct access to Agent Module for read operations */ get agents() { return new AgentModule(this.config); } /** * Direct access to Ghost Module for claiming external agents * * Ghosts are external AI agents (type 10) that exist on x402 facilitators. * They can be claimed using Solana Attestation Service (SAS) * for trustless ownership verification. */ get ghosts() { return new GhostModule(this.config); } /** * Direct access to Governance Module for read operations */ get governanceModule() { return new GovernanceModule(this.config); } /** * Direct access to Multisig Module for read operations */ get multisigModule() { return new MultisigModule(this.config); } /** * Agent operations */ agent() { return new AgentBuilder(this.config); } /** * Reputation operations */ reputation() { return new ReputationModule(this.config); } /** * Reputation Tag Engine (Pillar 2: Granular Tags) * * Automatic tag assignment and management based on agent metrics. * Features confidence scoring, evidence tracking, and tag decay. */ tagEngine() { const { ReputationTagEngine } = (init_reputation_tag_engine(), __toCommonJS(reputation_tag_engine_exports)); return new ReputationTagEngine(); } /** * Multi-Source Reputation Aggregator (Pillar 3: External Sources) * * Aggregate reputation data from multiple sources (x402, GitHub, custom webhooks) * with weighted scoring and conflict detection. */ reputationAggregator() { const { MultiSourceAggregator } = (init_MultiSourceAggregator(), __toCommonJS(MultiSourceAggregator_exports)); return new MultiSourceAggregator(); } /** * Privacy operations */ privacy() { return new PrivacyModule(this.config); } /** * Governance operations */ governance() { return new GovernanceBuilder(this.config); } /** * Multisig operations */ multisig() { return new MultisigBuilder(this.config); } /** * Unified Credential operations (Solana + Crossmint) */ credentials() { return new UnifiedCredentialService({ programId: this.config.programId, crossmint: this.config.credentials?.crossmintApiKey ? { apiKey: this.config.credentials.crossmintApiKey, environment: this.config.credentials.crossmintEnvironment, chain: this.config.credentials.crossmintChain } : void 0, crossmintTemplates: this.config.credentials?.templates }); } /** * DID operations (Decentralized Identifiers) */ did() { return new DidModule(this.config); } /** * Direct access to Authorization Module for read operations */ get authorization() { return new AuthorizationModule(this.config); } /** * Direct access to Staking Module for read operations */ get staking() { return new StakingModule(this.config); } // H2A module has been removed - use A2A (Agent-to-Agent) instructions instead /** * Enable development mode features */ enableDevMode() { console.log("\u{1F6E0}\uFE0F Development mode enabled"); console.log(" - Transaction simulation before sending"); console.log(" - Cost estimates for all operations"); console.log(" - Enhanced error messages"); this.config = { ...this.config // Add dev mode flags }; return this; } /** * Configure network */ useNetwork(cluster) { this.config.cluster = cluster; this.config.rpcEndpoint = this.getDefaultRpcEndpoint(cluster); return this; } /** * Configure custom RPC */ useRpc(endpoint, wsEndpoint) { this.config.rpcEndpoint = endpoint; this.config.wsEndpoint = wsEndpoint; return this; } /** * Get default RPC endpoint for cluster */ getDefaultRpcEndpoint(cluster) { switch (cluster) { case "mainnet-beta": return "https://api.mainnet-beta.solana.com"; case "devnet": return "https://api.devnet.solana.com"; case "testnet": return "https://api.testnet.solana.com"; case "localnet": return "http://localhost:8899"; default: return "https://api.devnet.solana.com"; } } }; var AgentBuilder = class { module; params = {}; constructor(config) { this.module = new AgentModule(config); } create(params) { this.params = { ...this.params, agentType: 0, // Default type metadataUri: JSON.stringify(params), agentId: params.name.toLowerCase().replace(/\s+/g, "-"), name: params.name, description: params.description || "" }; return this; } withDescription(description) { this.params.description = description; return this; } withType(agentType) { this.params.agentType = agentType; return this; } withIPFS() { this.params.forceIPFS = true; return this; } compressed() { this.params.compressed = true; return this; } debug() { this.module.debug(); return this; } withSigner(signer) { this.params.signer = signer; return this; } validateParams() { if (!this.params.signer) { throw new Error("Agent builder requires a signer. Call with signer first."); } if (!this.params.metadataUri) { throw new Error("Agent builder requires metadata. Call create() first."); } if (!this.params.agentId) { throw new Error("Agent builder requires agent ID. Call create() first."); } this.params.agentType ??= 0; } async getCost() { this.validateParams(); return this.module.getCost("registerAgent", () => ({ programAddress: this.module.getProgramId(), accounts: [], data: new Uint8Array() })); } async simulate() { const instruction = () => ({ // Placeholder for actual instruction generation programAddress: this.module.getProgramId(), accounts: [], data: new Uint8Array() }); this.validateParams(); return this.module.simulateInstruction("registerAgent", instruction, [this.params.signer]); } async explain() { this.validateParams(); return this.module.explain("registerAgent", () => ({ programAddress: this.module.getProgramId(), accounts: [], data: new Uint8Array() })); } async execute() { this.validateParams(); if (this.params.compressed) { console.log("Creating compressed agent (5000x cheaper)..."); } const signature = await this.module.register(this.params.signer, { agentType: this.params.agentType, name: this.params.name, description: this.params.description, metadataUri: this.params.metadataUri, agentId: this.params.agentId }); const address2 = await this.deriveAgentAddress(this.params.agentId, this.params.signer); return { address: address2, signature }; } async deriveAgentAddress(agentId, signer) { const { deriveAgentPda } = await import('./pda-4KP7CURF.js'); const [address2] = await deriveAgentPda({ programA