@agentek/tools
Version:
Blockchain tools for AI agents
231 lines • 8.3 kB
JavaScript
;
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