UNPKG

@hashgraphonline/standards-agent-kit

Version:

A modular SDK for building on-chain autonomous agents using Hashgraph Online Standards, including HCS-10 for agent discovery and communication.

135 lines (125 loc) 4.5 kB
import { z } from 'zod'; import { BaseInscriberQueryTool } from './base-inscriber-tools'; import { InscriptionOptions } from '@hashgraphonline/standards-sdk'; import { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager'; /** * Schema for inscribing Hashinal NFT */ const inscribeHashinalSchema = z.object({ url: z.string().url().describe('The URL of the content to inscribe as Hashinal NFT'), name: z.string().describe('Name of the Hashinal NFT'), creator: z.string().describe('Creator account ID or name'), description: z.string().describe('Description of the Hashinal NFT'), type: z.string().describe('Type of NFT (e.g., "image", "video", "audio")'), attributes: z .array( z.object({ trait_type: z.string(), value: z.union([z.string(), z.number()]), }) ) .optional() .describe('NFT attributes'), properties: z .record(z.unknown()) .optional() .describe('Additional properties'), jsonFileURL: z .string() .url() .optional() .describe('URL to JSON metadata file'), tags: z .array(z.string()) .optional() .describe('Tags to categorize the NFT'), chunkSize: z .number() .int() .positive() .optional() .describe('Chunk size for large files'), waitForConfirmation: z .boolean() .optional() .describe('Whether to wait for inscription confirmation'), timeoutMs: z .number() .int() .positive() .optional() .describe('Timeout in milliseconds for inscription (default: no timeout - waits until completion)'), apiKey: z .string() .optional() .describe('API key for inscription service'), }); /** * Tool for inscribing Hashinal NFTs */ export class InscribeHashinalTool extends BaseInscriberQueryTool<typeof inscribeHashinalSchema> { name = 'inscribeHashinal'; description = 'Inscribe content as a Hashinal NFT on the Hedera network'; get specificInputSchema() { return inscribeHashinalSchema; } protected async executeQuery( params: z.infer<typeof inscribeHashinalSchema>, _runManager?: CallbackManagerForToolRun ): Promise<unknown> { const metadata = { name: params.name, creator: params.creator, description: params.description, type: params.type, attributes: params.attributes, properties: params.properties, }; const options: InscriptionOptions = { mode: 'hashinal', metadata, jsonFileURL: params.jsonFileURL, tags: params.tags, chunkSize: params.chunkSize, waitForConfirmation: params.waitForConfirmation ?? true, waitMaxAttempts: 10, waitIntervalMs: 3000, apiKey: params.apiKey, network: this.inscriberBuilder['hederaKit'].client.network.toString().includes('mainnet') ? 'mainnet' : 'testnet', }; try { let result: Awaited<ReturnType<typeof this.inscriberBuilder.inscribe>>; if (params.timeoutMs) { const timeoutPromise = new Promise<never>((_, reject) => { setTimeout( () => reject(new Error(`Inscription timed out after ${params.timeoutMs}ms`)), params.timeoutMs ); }); result = await Promise.race([ this.inscriberBuilder.inscribe( { type: 'url', url: params.url }, options ), timeoutPromise ]); } else { result = await this.inscriberBuilder.inscribe( { type: 'url', url: params.url }, options ); } if (result.confirmed) { const topicId = result.inscription?.topic_id || result.result.topicId; const network = options.network || 'testnet'; const cdnUrl = topicId ? `https://kiloscribe.com/api/inscription-cdn/${topicId}?network=${network}` : null; return `Successfully inscribed and confirmed Hashinal NFT on the Hedera network!\n\nTransaction ID: ${result.result.transactionId}\nTopic ID: ${topicId || 'N/A'}${cdnUrl ? `\nView inscription: ${cdnUrl}` : ''}\n\nThe Hashinal NFT is now available.`; } else { return `Successfully submitted Hashinal NFT inscription to the Hedera network!\n\nTransaction ID: ${result.result.transactionId}\n\nThe inscription is processing and will be confirmed shortly.`; } } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Failed to inscribe Hashinal NFT'; throw new Error(`Inscription failed: ${errorMessage}`); } } }