UNPKG

@agentek/tools

Version:

Blockchain tools for AI agents

231 lines 8.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AgentekClient = exports.isSignOperation = exports.isTypedDataSign = exports.isPersonalSign = exports.isTransactionOp = void 0; exports.createAgentekClient = createAgentekClient; exports.createTool = createTool; exports.createToolCollection = createToolCollection; const viem_1 = require("viem"); // Type guards for runtime checking const isTransactionOp = (op) => { return 'target' in op && 'value' in op && 'data' in op; }; exports.isTransactionOp = isTransactionOp; const isPersonalSign = (op) => { return 'type' in op && op.type === 'personal_sign'; }; exports.isPersonalSign = isPersonalSign; const isTypedDataSign = (op) => { return 'type' in op && op.type === 'typed_data_sign'; }; exports.isTypedDataSign = isTypedDataSign; const isSignOperation = (op) => { return (0, exports.isPersonalSign)(op) || (0, exports.isTypedDataSign)(op); }; exports.isSignOperation = isSignOperation; class AgentekClient { publicClients; walletClients; tools; chains; accountOrAddress; constructor(config) { this.publicClients = new Map(); this.walletClients = new Map(); this.chains = config.chains; this.accountOrAddress = config.accountOrAddress; config.chains.forEach((chain, index) => { const transport = config.transports[index] || config.transports[0]; // Create public client with simple configuration to avoid type issues const publicClient = (0, viem_1.createPublicClient)({ transport, chain, }); this.publicClients.set(chain.id, publicClient); // Create wallet client separately if account is provided as an object // client.ts (inside constructor) if (typeof config.accountOrAddress === "object") { const raw = (0, viem_1.createWalletClient)({ transport, chain, account: config.accountOrAddress, }); // Force‐cast so TS doesn't expand the full generic return type. const walletClient = raw; this.walletClients.set(chain.id, walletClient); } }); this.tools = new Map(config.tools.map((tool) => [tool.name, tool])); } // Get address async getAddress() { if (typeof this.accountOrAddress === "string") { return this.accountOrAddress; } return this.accountOrAddress.address; } // Get public client for specific chain getPublicClient(chainId) { if (!chainId) { const defaultClient = this.publicClients.values().next().value; if (!defaultClient) throw new Error("No public clients available"); return defaultClient; } const specificClient = this.publicClients.get(chainId); if (!specificClient) throw new Error(`No public client for chain ${chainId}`); return specificClient; } // Get all public clients getPublicClients() { return this.publicClients; } // Get wallet client for specific chain getWalletClient(chainId) { if (!chainId) { return this.walletClients.values().next().value; } return this.walletClients.get(chainId); } // Get all wallet clients getWalletClients() { return this.walletClients; } // Get all available chains getChains() { return this.chains; } // Get all tools getTools() { return this.tools; } // Method to filter supported chains filterSupportedChains(supportedChains, chainId) { let chains = this.getChains(); chains = chains.filter((chain) => supportedChains.map((c) => c.id).includes(chain.id)); if (chainId !== undefined) { chains = chains.filter((chain) => chain.id === chainId); if (chains.length === 0) { throw new Error(`Chain ${chainId} is not supported`); } } return chains; } // Method to add new tools addTools(tools) { tools.forEach((tool) => { this.tools.set(tool.name, tool); }); } async executeOps(ops, chainId) { const walletClient = this.getWalletClient(chainId); const publicClient = this.getPublicClient(chainId); if (!walletClient) { throw new Error(`No wallet client available for chain ${chainId}`); } if (!publicClient) { throw new Error(`No public client available for chain ${chainId}`); } let hash = ""; for (const op of ops) { // Remove the explicit account parameter as it's already set in the wallet client // @ts-expect-error const txHash = await walletClient.sendTransaction({ to: op.target, value: BigInt(op.value), data: op.data, }); await publicClient.waitForTransactionReceipt({ hash: txHash, }); if (ops.length > 1) { hash = hash + txHash + ";"; } else { hash = txHash; } } return hash; } async executeSign(signs, chainId) { const walletClient = this.getWalletClient(chainId); const account = await this.getAddress(); if (!walletClient) { throw new Error(`No wallet client available for chain ${chainId}`); } const signatures = []; for (const sign of signs) { let signature; if ((0, exports.isPersonalSign)(sign)) { // EIP-191 Personal Sign signature = await walletClient.signMessage({ account, message: sign.message, }); } else if ((0, exports.isTypedDataSign)(sign)) { // EIP-712 Typed Data Sign signature = await walletClient.signTypedData({ account, domain: sign.domain, types: sign.types, primaryType: sign.primaryType, message: sign.message, }); } else { throw new Error(`Unsupported sign operation type`); } signatures.push(signature); } return signatures; } // Execute mixed operations (both transactions and signatures) async executeOperations(operations, chainId) { const transactionOps = operations.filter(exports.isTransactionOp); const signOps = operations.filter(exports.isSignOperation); const results = {}; // Execute transaction operations if (transactionOps.length > 0) { results.hash = await this.executeOps(transactionOps, chainId); } // Execute signing operations if (signOps.length > 0) { results.signatures = await this.executeSign(signOps, chainId); } return results; } async execute(method, args) { const tool = this.tools.get(method); if (!tool) { throw new Error(`Tool ${method} not found`); } if (args.chainId && tool.supportedChains) { if (!tool.supportedChains.map((c) => c.id).includes(args.chainId)) { throw new Error(`Chain ${args.chainId} not supported by tool ${method}`); } } const validatedArgs = tool.parameters.safeParse(args); if (!validatedArgs.success) { throw new Error(JSON.stringify(validatedArgs.error)); } return tool.execute(this, validatedArgs.data); } } exports.AgentekClient = AgentekClient; function createAgentekClient(config) { return new AgentekClient(config); } function createTool({ name, description, parameters, execute, supportedChains, }) { return { name, description, parameters, execute, supportedChains, }; } function createToolCollection(tools) { return tools; } //# sourceMappingURL=client.js.map