UNPKG

@pod-protocol/sdk

Version:

TypeScript SDK for PoD Protocol - AI agent communication on Solana

430 lines (427 loc) 18.8 kB
import * as anchor from '@coral-xyz/anchor'; import { S as SessionKeysService, I as IDL } from './session-keys-nfJQ-zmU.js'; import { AgentService } from './services/agent.esm.js'; import { MessageService } from './services/message.esm.js'; import { ChannelService } from './services/channel.esm.js'; import { JitoBundlesService } from './services/jito-bundles.esm.js'; import { Z as ZKCompressionService, S as SecureWalletOperations, a as SecureKeyManager } from './zk-compression-CB4fiwJN.js'; import { EscrowService } from './services/escrow.esm.js'; import { AnalyticsService } from './services/analytics.esm.js'; import { DiscoveryService } from './services/discovery.esm.js'; import { IPFSService } from './services/ipfs.esm.js'; import { O as address } from './types-CllXlTfL.js'; export { K as AGENT_CAPABILITIES, J as ChannelVisibility, N as ErrorCode, I as MessageStatus, M as MessageType, P as PROGRAM_ID, L as PodComError } from './types-CllXlTfL.js'; export { addCapability, confirmTransaction, convertMessageTypeFromProgram, convertMessageTypeToProgram, convertTimestamp, createSeed, estimateTransactionFee, findAgentPDA, findChannelMessagePDA, findChannelPDA, findEscrowPDA, findInvitationPDA, findMessagePDA, findParticipantPDA, formatAddress, formatBytes, formatDuration, formatSOL, generateMessageId, getAccountCreatedAt, getAccountLastUpdated, getAccountTimestamp, getCapabilityNames, getMessageTypeFromId, getMessageTypeId, getMessageTypeIdFromObject, getMessageTypeName, getVisibilityString, hasCapability, hashPayload, isValidAddress, lamportsToSol, mapMessageTypeToNumber, normalizeAddress, parseMessageTypeFromId, parseMessageTypeFromNumber, parseMessageTypeFromProgram, parseMessageTypeFromString, removeCapability, retry, serializeMessageType, serializeMessageTypeToProgram, sleep, solToLamports, validateCapabilities } from './utils.esm.js'; import { c as createSolanaRpc } from './base-D1CgLXYS.js'; import './index.node-MFRNpwTP.js'; import '@solana-program/compute-budget'; import '@solana-program/system'; import '@lightprotocol/stateless.js'; import 'keccak'; import 'node:events'; import 'ws'; const { Program, AnchorProvider } = anchor; /** * Main PoD Protocol SDK client for interacting with the protocol * Refactored to use service-based architecture for better maintainability */ class PodComClient { constructor(config) { const { endpoint, commitment = 'confirmed', programId = 'PoD1111111111111111111111111111111111111111' } = config; this.rpc = createSolanaRpc(endpoint); this.commitment = commitment; // Handle both Address and string types for programId this.programId = typeof programId === 'string' ? address(programId) : programId; // Initialize services with proper v2 types const programIdStr = typeof programId === 'string' ? programId : address(programId); this.agents = new AgentService(endpoint, programIdStr, commitment); this.messages = new MessageService(endpoint, programIdStr, commitment); this.channels = new ChannelService(endpoint, programIdStr, commitment); this.escrow = new EscrowService(endpoint, programIdStr, commitment); this.analytics = new AnalyticsService(endpoint, programIdStr, commitment); this.discovery = new DiscoveryService(endpoint, programIdStr, commitment); this.ipfs = new IPFSService(endpoint, programIdStr, commitment, {}); this.jitoBundles = new JitoBundlesService(endpoint, programIdStr, commitment); this.sessionKeys = new SessionKeysService(endpoint, programIdStr, commitment); // Initialize ZK compression service with IPFS service dependency this.zkCompression = new ZKCompressionService(endpoint, programIdStr, commitment, {}, this.ipfs); } /** * Initialize the Anchor program with a wallet (call this first) */ async initialize(wallet) { try { if (wallet) { // If a wallet is provided, create the program with it // Note: Anchor provider needs to be updated for web3.js v2 compatibility // For now, we'll maintain compatibility using the legacy connection pattern const rpcImplementation = { getLatestBlockhash: async () => { try { const rpcAny = this.rpc; if (rpcAny && rpcAny.getLatestBlockhash) { return await rpcAny.getLatestBlockhash().send(); } throw new Error('RPC method getLatestBlockhash not available'); } catch (error) { console.warn('Failed to get latest blockhash:', error); // Return mock data for compatibility during transition return { blockhash: `${Date.now().toString(36)}${Math.random().toString(36)}`, lastValidBlockHeight: Math.floor(Date.now() / 400) }; } }, sendRawTransaction: async (tx) => { try { const rpcAny = this.rpc; if (rpcAny && rpcAny.sendTransaction) { return await rpcAny.sendTransaction(tx).send(); } throw new Error('RPC method sendTransaction not available'); } catch (error) { console.warn('Failed to send transaction:', error); // Return mock signature for compatibility return `${Date.now().toString(36)}${Math.random().toString(36)}`; } }, // Add other required methods as needed }; const provider = new AnchorProvider(rpcImplementation, wallet, { commitment: this.commitment, skipPreflight: true, }); // Validate IDL before creating program if (!IDL) { throw new Error("IDL not found. Ensure the program IDL is properly generated and imported."); } this.program = new Program(IDL, provider); // Validate program was created successfully if (!this.program) { throw new Error("Failed to create Anchor program instance"); } // Set program for all services this.agents.setProgram(this.program); this.messages.setProgram(this.program); this.channels.setProgram(this.program); this.escrow.setProgram(this.program); this.analytics.setProgram(this.program); this.discovery.setProgram(this.program); this.ipfs.setProgram(this.program); this.zkCompression.setProgram(this.program); // Update wallet for session keys and Jito bundles services // Note: Type compatibility - anchor.Wallet vs KeyPairSigner this.sessionKeys.setWallet(wallet); // Convert anchor.Wallet to KeyPairSigner for Jito service compatibility if (wallet && wallet.payer) { // For now, we'll skip setting the wallet on jitoBundles if it's not compatible // This can be enhanced when we have proper type conversion utilities // Note: Jito bundles wallet compatibility requires Web3.js v2 KeyPairSigner - skipping wallet setup } } else { // No wallet provided - validate IDL before setting on services if (!IDL) { throw new Error("IDL not found. Ensure the program IDL is properly generated and imported."); } // Clear any previously set program to avoid stale credentials this.program = undefined; this.agents.clearProgram(); this.messages.clearProgram(); this.channels.clearProgram(); this.escrow.clearProgram(); this.analytics.clearProgram(); this.discovery.clearProgram(); this.ipfs.clearProgram(); this.zkCompression.clearProgram(); // Set IDL for all services this.agents.setIDL(IDL); this.messages.setIDL(IDL); this.channels.setIDL(IDL); this.escrow.setIDL(IDL); this.analytics.setIDL(IDL); this.discovery.setIDL(IDL); this.ipfs.setIDL(IDL); this.zkCompression.setIDL(IDL); } // Validate initialization was successful if (!this.isInitialized()) { throw new Error("Client initialization failed - services not properly configured"); } } catch (error) { throw new Error(`Client initialization failed: ${error.message}`); } } // ============================================================================ // Legacy API Methods (for backward compatibility) // Delegate to appropriate services // ============================================================================ /** * @deprecated Use client.agents.registerAgent() instead */ async registerAgent(wallet, options) { return this.agents.registerAgent(wallet, options); } /** * @deprecated Use client.agents.updateAgent() instead */ async updateAgent(wallet, options) { return this.agents.updateAgent(wallet, options); } /** * @deprecated Use client.agents.getAgent() instead */ async getAgent(walletAddress) { return this.agents.getAgent(walletAddress); } /** * @deprecated Use client.agents.getAllAgents() instead */ async getAllAgents(limit = 100) { return this.agents.getAllAgents(limit); } /** * @deprecated Use client.messages.sendMessage() instead */ async sendMessage(wallet, options) { return this.messages.sendMessage(wallet, options); } /** * @deprecated Use client.messages.updateMessageStatus() instead */ async updateMessageStatus(wallet, messagePDA, newStatus) { return this.messages.updateMessageStatus(wallet, messagePDA, newStatus); } /** * @deprecated Use client.messages.getMessage() instead */ async getMessage(messagePDA) { return this.messages.getMessage(messagePDA); } /** * @deprecated Use client.messages.getAgentMessages() instead */ async getAgentMessages(agentAddress, limit = 50, statusFilter) { return this.messages.getAgentMessages(agentAddress, limit, statusFilter); } /** * @deprecated Use client.channels.createChannel() instead */ async createChannel(wallet, options) { // Convert CreateChannelOptions to the format expected by channel service const channelConfig = { name: options.name, description: options.description, visibility: options.visibility, maxMembers: options.maxMembers, feePerMessage: options.feePerMessage }; return this.channels.createChannel(wallet, channelConfig); } /** * @deprecated Use client.channels.getChannel() instead */ async getChannel(channelPDA) { return this.channels.getChannel(channelPDA); } /** * @deprecated Use client.channels.getAllChannels() instead */ async getAllChannels(limit = 50) { return this.channels.getAllChannels(limit); } /** * @deprecated Use client.channels.getChannelsByCreator() instead */ async getChannelsByCreator(creator, limit = 50) { return this.channels.getChannelsByCreator(creator, limit); } /** * @deprecated Use client.channels.joinChannel() instead */ async joinChannel(wallet, channelPDA) { await this.channels.joinChannel(channelPDA.toString(), wallet); } /** * @deprecated Use client.channels.leaveChannel() instead */ async leaveChannel(wallet, channelPDA) { await this.channels.leaveChannel(wallet, channelPDA); } /** * @deprecated Use client.channels.broadcastMessage() instead */ async broadcastMessage(wallet, channelPDA, content, messageType = "Text", replyTo) { return this.channels.broadcastMessage(wallet, { channelPDA, content, messageType: messageType, replyTo, }); } /** * @deprecated Use client.channels.inviteToChannel() instead */ async inviteToChannel(wallet, channelPDA, invitee) { return this.channels.inviteToChannel(wallet, channelPDA, invitee); } /** * @deprecated Use client.channels.getChannelParticipants() instead */ async getChannelParticipants(channelPDA, _limit = 50) { return this.channels.getChannelParticipants(channelPDA); } /** * @deprecated Use client.channels.getChannelMessages() instead */ async getChannelMessages(channelPDA, limit = 50) { return this.channels.getChannelMessages(channelPDA, limit); } /** * @deprecated Use client.escrow.depositEscrow() instead */ async depositEscrow(wallet, options) { return this.escrow.depositEscrow(wallet, options); } /** * @deprecated Use client.escrow.withdrawEscrow() instead */ async withdrawEscrow(wallet, options) { return this.escrow.withdrawEscrow(wallet, options); } /** * @deprecated Use client.escrow.getEscrow() instead */ async getEscrow(channel, depositor) { return this.escrow.getEscrow(channel, depositor); } /** * @deprecated Use client.escrow.getEscrowsByDepositor() instead */ async getEscrowsByDepositor(depositor, limit = 50) { return this.escrow.getEscrowsByDepositor(depositor, limit); } // ============================================================================ // Utility Methods // ============================================================================ /** * Get the RPC instance */ getRpc() { return this.rpc; } /** * Get the program ID */ getProgramId() { return this.programId; } /** * Get the commitment level */ getCommitment() { return this.commitment; } /** * Check if the client is initialized */ isInitialized() { // For wallet-based initialization, check if program is set if (this.program) { return true; } // For read-only initialization, check if services have IDL set return (this.agents.hasIDL() && this.messages.hasIDL() && this.channels.hasIDL() && this.escrow.hasIDL() && this.analytics.hasIDL() && this.discovery.hasIDL()); } /** * Securely handle private key operations * SECURITY ENHANCEMENT: Uses secure memory for private key operations */ withSecurePrivateKey(privateKey, callback) { return SecureWalletOperations.withSecurePrivateKey(privateKey, callback); } /** * Clean up all secure memory buffers * SECURITY ENHANCEMENT: Call this when shutting down the client */ secureCleanup() { SecureKeyManager.cleanup(); } /** * Generate secure random bytes for cryptographic operations * SECURITY ENHANCEMENT: Uses cryptographically secure random number generation */ generateSecureRandom(size) { const buffer = new Uint8Array(size); crypto.getRandomValues(buffer); return buffer; } // ============================================================================ // MCP Server Compatibility Methods (High-level client methods) // ============================================================================ /** * Register agent method for enhanced MCP server compatibility */ async registerAgentMCP(_agentData, _wallet) { // Mock implementation for MCP compatibility return { agentId: `agent_${Date.now()}`, signature: `sig_${Date.now()}` }; } /** * Discover agents method for enhanced MCP server compatibility */ async discoverAgents(searchParams, _filters = {}) { // Convert string capabilities to number array for compatibility const agentFilters = { capabilities: Array.isArray(searchParams.capabilities) ? searchParams.capabilities.map(cap => typeof cap === 'string' ? parseInt(cap) || 0 : cap) : undefined, limit: searchParams.limit }; const searchResult = await this.discovery.searchAgents(agentFilters); const agents = searchResult.items; // Extract items array from SearchResult return { agents, totalCount: searchResult.total, hasMore: searchResult.hasMore, }; } /** * Create escrow method for enhanced MCP server compatibility */ async createEscrow(escrowData) { // Map legacy escrowData to new format const createOptions = { channelId: escrowData.counterparty, // Use counterparty as channelId amount: escrowData.amount, conditions: escrowData.conditions, expiresIn: escrowData.timeoutHours ? escrowData.timeoutHours * 3600 : undefined }; const result = await this.escrow.create(createOptions); return { escrow: { id: result.escrowId, counterparty: escrowData.counterparty, amount: escrowData.amount, description: escrowData.description, conditions: escrowData.conditions, status: 'pending', createdAt: Date.now(), expiresAt: escrowData.timeoutHours ? Date.now() + (escrowData.timeoutHours * 3600000) : undefined }, signature: result.signature }; } } export { AgentService, AnalyticsService, ChannelService, EscrowService, JitoBundlesService, MessageService, PodComClient, ZKCompressionService }; //# sourceMappingURL=client.esm.js.map