@hashgraphonline/standards-agent-kit 0.2.124 → 0.2.127

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hashgraphonline/standards-agent-kit",
3
- "version": "0.2.124",
3
+ "version": "0.2.127",
4
4
  "description": "A modular SDK for building on-chain autonomous agents using Hashgraph Online Standards, including HCS-10 for agent discovery and communication.",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/standards-agent-kit.cjs",
@@ -21,33 +21,6 @@
21
21
  "LICENSE",
22
22
  "README.md"
23
23
  ],
24
- "scripts": {
25
- "clean": "rimraf dist",
26
- "build:es": "BUILD_FORMAT=es vite build",
27
- "build:cjs": "BUILD_FORMAT=cjs vite build",
28
- "build:umd": "BUILD_FORMAT=umd vite build",
29
- "build": "pnpm run clean && pnpm run build:es && pnpm run build:cjs && pnpm run build:umd",
30
- "test": "jest",
31
- "lint": "eslint . --ext .ts",
32
- "lint:fix": "eslint . --ext .ts --fix",
33
- "prepare": "pnpm run build",
34
- "prepublishOnly": "pnpm run build",
35
- "release": "pnpm publish --access public",
36
- "release:canary": "pnpm run prepublishOnly && pnpm publish --tag canary --access public",
37
- "version:canary": "pnpm version prerelease --preid canary --no-git-tag-version",
38
- "publish:canary": "pnpm run version:canary && pnpm run release:canary",
39
- "demo:cli": "tsx examples/cli-demo.ts",
40
- "demo:interactive": "tsx examples/interactive-demo.ts",
41
- "demo:langchain": "tsx examples/langchain-demo.ts",
42
- "demo:plugin": "tsx examples/plugin-system-example.ts",
43
- "demo:plugin:weather": "tsx examples/plugins/weather/index.ts",
44
- "demo:plugin:defi": "tsx examples/plugins/defi/index.ts",
45
- "demo:plugin:openconvai": "tsx examples/openconvai-plugin-example.ts",
46
- "demo:inscription-quotes": "tsx examples/inscription-quote-demo.ts",
47
- "standards-agent:start": "tsx examples/standards-expert/cli.ts -- start",
48
- "standards-agent:process-docs": "tsx examples/standards-expert/cli.ts -- process-docs --all-repos",
49
- "typecheck": "tsc --noEmit"
50
- },
51
24
  "keywords": [
52
25
  "hedera",
53
26
  "hcs10",
@@ -128,5 +101,29 @@
128
101
  "vite-plugin-node-polyfills": "^0.23.0",
129
102
  "vite-plugin-string-replace": "^1.1.3"
130
103
  },
131
- "packageManager": "pnpm@10.11.1+sha512.e519b9f7639869dc8d5c3c5dfef73b3f091094b0a006d7317353c72b124e80e1afd429732e28705ad6bfa1ee879c1fce46c128ccebd3192101f43dd67c667912"
132
- }
104
+ "scripts": {
105
+ "clean": "rimraf dist",
106
+ "build:es": "BUILD_FORMAT=es vite build",
107
+ "build:cjs": "BUILD_FORMAT=cjs vite build",
108
+ "build:umd": "BUILD_FORMAT=umd vite build",
109
+ "build": "pnpm run clean && pnpm run build:es && pnpm run build:cjs && pnpm run build:umd",
110
+ "test": "jest",
111
+ "lint": "eslint . --ext .ts",
112
+ "lint:fix": "eslint . --ext .ts --fix",
113
+ "release": "pnpm publish --access public",
114
+ "release:canary": "pnpm run prepublishOnly && pnpm publish --tag canary --access public",
115
+ "version:canary": "pnpm version prerelease --preid canary --no-git-tag-version",
116
+ "publish:canary": "pnpm run version:canary && pnpm run release:canary",
117
+ "demo:cli": "tsx examples/cli-demo.ts",
118
+ "demo:interactive": "tsx examples/interactive-demo.ts",
119
+ "demo:langchain": "tsx examples/langchain-demo.ts",
120
+ "demo:plugin": "tsx examples/plugin-system-example.ts",
121
+ "demo:plugin:weather": "tsx examples/plugins/weather/index.ts",
122
+ "demo:plugin:defi": "tsx examples/plugins/defi/index.ts",
123
+ "demo:plugin:openconvai": "tsx examples/openconvai-plugin-example.ts",
124
+ "demo:inscription-quotes": "tsx examples/inscription-quote-demo.ts",
125
+ "standards-agent:start": "tsx examples/standards-expert/cli.ts -- start",
126
+ "standards-agent:process-docs": "tsx examples/standards-expert/cli.ts -- process-docs --all-repos",
127
+ "typecheck": "tsc --noEmit"
128
+ }
129
+ }
@@ -126,7 +126,7 @@ export class InscribeFromBufferTool extends BaseInscriberQueryTool<
126
126
  mimeType: resolvedMimeType,
127
127
  sizeBytes: buffer.length,
128
128
  },
129
- message: `Quote generated for buffer content: ${resolvedFileName} (${(buffer.length / 1024).toFixed(2)} KB)\nTotal cost: ${quote.totalCostHbar} HBAR`,
129
+ message: `Estimated Quote for buffer content: ${resolvedFileName} (${(buffer.length / 1024).toFixed(2)} KB)\nTotal cost: ${quote.totalCostHbar} HBAR`,
130
130
  };
131
131
  } catch (error) {
132
132
  const errorMessage =
@@ -135,16 +135,13 @@ export class InscribeFromBufferTool extends BaseInscriberQueryTool<
135
135
  }
136
136
  }
137
137
 
138
- const timeoutMs =
139
- params.timeoutMs || (options.waitForConfirmation ? 60000 : undefined);
140
-
141
138
  try {
142
139
  const result = await this.executeInscription(
143
140
  buffer,
144
141
  resolvedFileName,
145
142
  resolvedMimeType,
146
143
  options,
147
- timeoutMs
144
+ params.timeoutMs
148
145
  );
149
146
  return this.formatInscriptionResult(result, options);
150
147
  } catch (error) {
@@ -199,7 +199,7 @@ export class InscribeFromFileTool extends BaseInscriberQueryTool<
199
199
  sizeBytes: fileContent.length,
200
200
  filePath: params.filePath,
201
201
  },
202
- message: `Quote generated for file: ${fileName} (${(
202
+ message: `Estimated Quote for file: ${fileName} (${(
203
203
  fileContent.length / 1024
204
204
  ).toFixed(2)} KB)\nTotal cost: ${
205
205
  quote.totalCostHbar
@@ -7,7 +7,12 @@ import { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';
7
7
  * Schema for inscribing from URL
8
8
  */
9
9
  const inscribeFromUrlSchema = z.object({
10
- url: z.string().url().describe('ONLY direct file download URLs with file extensions (.pdf, .jpg, .png, .json, .zip). NEVER use for web pages, articles, or when you already have content to inscribe.'),
10
+ url: z
11
+ .string()
12
+ .url()
13
+ .describe(
14
+ 'ONLY direct file download URLs with file extensions (.pdf, .jpg, .png, .json, .zip). NEVER use for web pages, articles, or when you already have content to inscribe.'
15
+ ),
11
16
  mode: z
12
17
  .enum(['file', 'hashinal'])
13
18
  .optional()
@@ -35,25 +40,28 @@ const inscribeFromUrlSchema = z.object({
35
40
  .int()
36
41
  .positive()
37
42
  .optional()
38
- .describe('Timeout in milliseconds for inscription (default: no timeout - waits until completion)'),
39
- apiKey: z
40
- .string()
41
- .optional()
42
- .describe('API key for inscription service'),
43
+ .describe(
44
+ 'Timeout in milliseconds for inscription (default: no timeout - waits until completion)'
45
+ ),
46
+ apiKey: z.string().optional().describe('API key for inscription service'),
43
47
  quoteOnly: z
44
48
  .boolean()
45
49
  .optional()
46
50
  .default(false)
47
- .describe('If true, returns a cost quote instead of executing the inscription'),
51
+ .describe(
52
+ 'If true, returns a cost quote instead of executing the inscription'
53
+ ),
48
54
  });
49
55
 
50
-
51
56
  /**
52
57
  * Tool for inscribing content from URL
53
58
  */
54
- export class InscribeFromUrlTool extends BaseInscriberQueryTool<typeof inscribeFromUrlSchema> {
59
+ export class InscribeFromUrlTool extends BaseInscriberQueryTool<
60
+ typeof inscribeFromUrlSchema
61
+ > {
55
62
  name = 'inscribeFromUrl';
56
- description = 'ONLY for direct FILE DOWNLOAD URLs ending with file extensions (.pdf, .jpg, .png, .json, .zip). NEVER use for web pages, articles, or ANY HTML content - it WILL FAIL. If you have already retrieved content from any source (including MCP tools), you MUST use inscribeFromBuffer instead. This tool downloads files from URLs - it does NOT inscribe content you already have. When asked to "inscribe it" after retrieving content, ALWAYS use inscribeFromBuffer with the actual content. Set quoteOnly=true to get cost estimates without executing the inscription.';
63
+ description =
64
+ 'ONLY for direct FILE DOWNLOAD URLs ending with file extensions (.pdf, .jpg, .png, .json, .zip). NEVER use for web pages, articles, or ANY HTML content - it WILL FAIL. If you have already retrieved content from any source (including MCP tools), you MUST use inscribeFromBuffer instead. This tool downloads files from URLs - it does NOT inscribe content you already have. When asked to "inscribe it" after retrieving content, ALWAYS use inscribeFromBuffer with the actual content. Set quoteOnly=true to get cost estimates without executing the inscription.';
57
65
 
58
66
  get specificInputSchema() {
59
67
  return inscribeFromUrlSchema;
@@ -63,8 +71,10 @@ export class InscribeFromUrlTool extends BaseInscriberQueryTool<typeof inscribeF
63
71
  params: z.infer<typeof inscribeFromUrlSchema>,
64
72
  _runManager?: CallbackManagerForToolRun
65
73
  ): Promise<unknown> {
66
- console.log(`[DEBUG] InscribeFromUrlTool.executeQuery called with URL: ${params.url}`);
67
-
74
+ console.log(
75
+ `[DEBUG] InscribeFromUrlTool.executeQuery called with URL: ${params.url}`
76
+ );
77
+
68
78
  if (!params.url || params.url.trim() === '') {
69
79
  throw new Error('URL cannot be empty. Please provide a valid URL.');
70
80
  }
@@ -72,95 +82,137 @@ export class InscribeFromUrlTool extends BaseInscriberQueryTool<typeof inscribeF
72
82
  try {
73
83
  const urlObj = new URL(params.url);
74
84
  if (!urlObj.protocol || !urlObj.host) {
75
- throw new Error('Invalid URL format. Please provide a complete URL with protocol (http/https).');
85
+ throw new Error(
86
+ 'Invalid URL format. Please provide a complete URL with protocol (http/https).'
87
+ );
76
88
  }
77
89
  if (!['http:', 'https:'].includes(urlObj.protocol)) {
78
- throw new Error('Only HTTP and HTTPS URLs are supported for inscription.');
90
+ throw new Error(
91
+ 'Only HTTP and HTTPS URLs are supported for inscription.'
92
+ );
79
93
  }
80
-
81
94
  } catch (error) {
82
- if (error instanceof Error && error.message.includes('Cannot inscribe content from')) {
95
+ if (
96
+ error instanceof Error &&
97
+ error.message.includes('Cannot inscribe content from')
98
+ ) {
83
99
  throw error;
84
100
  }
85
- throw new Error(`Invalid URL: ${params.url}. Please provide a valid URL.`);
101
+ throw new Error(
102
+ `Invalid URL: ${params.url}. Please provide a valid URL.`
103
+ );
86
104
  }
87
105
 
88
- console.log(`[InscribeFromUrlTool] Validating URL content before inscription...`);
106
+ console.log(
107
+ `[InscribeFromUrlTool] Validating URL content before inscription...`
108
+ );
89
109
  try {
90
110
  const controller = new AbortController();
91
111
  const timeoutId = setTimeout(() => controller.abort(), 10000);
92
-
112
+
93
113
  try {
94
114
  const headResponse = await fetch(params.url, {
95
115
  method: 'HEAD',
96
116
  signal: controller.signal,
97
117
  });
98
-
118
+
99
119
  clearTimeout(timeoutId);
100
-
120
+
101
121
  if (!headResponse.ok) {
102
- throw new Error(`URL returned error status ${headResponse.status}: ${headResponse.statusText}. Cannot inscribe content from inaccessible URLs.`);
122
+ throw new Error(
123
+ `URL returned error status ${headResponse.status}: ${headResponse.statusText}. Cannot inscribe content from inaccessible URLs.`
124
+ );
103
125
  }
104
126
 
105
127
  const contentType = headResponse.headers.get('content-type') || '';
106
128
  const contentLength = headResponse.headers.get('content-length');
107
-
129
+
108
130
  const webPageContentTypes = [
109
131
  'text/html',
110
132
  'application/xhtml+xml',
111
- 'text/xml'
133
+ 'text/xml',
112
134
  ];
113
-
114
- if (webPageContentTypes.some(type => contentType.toLowerCase().includes(type))) {
115
- throw new Error(`URL returns HTML/web page content (Content-Type: ${contentType}). This tool only works with direct file URLs (PDFs, images, JSON, etc.). For web page content, first retrieve the content using the appropriate MCP tool or web scraper, then use inscribeFromBuffer to inscribe it.`);
135
+
136
+ if (
137
+ webPageContentTypes.some((type) =>
138
+ contentType.toLowerCase().includes(type)
139
+ )
140
+ ) {
141
+ throw new Error(
142
+ `URL returns HTML/web page content (Content-Type: ${contentType}). This tool only works with direct file URLs (PDFs, images, JSON, etc.). For web page content, first retrieve the content using the appropriate MCP tool or web scraper, then use inscribeFromBuffer to inscribe it.`
143
+ );
116
144
  }
117
-
145
+
118
146
  if (contentLength && parseInt(contentLength) === 0) {
119
- throw new Error('URL returns empty content (Content-Length: 0). Cannot inscribe empty content.');
147
+ throw new Error(
148
+ 'URL returns empty content (Content-Length: 0). Cannot inscribe empty content.'
149
+ );
120
150
  }
121
151
 
122
152
  if (contentLength && parseInt(contentLength) < 10) {
123
- throw new Error(`URL content is too small (${contentLength} bytes). Content must be at least 10 bytes.`);
153
+ throw new Error(
154
+ `URL content is too small (${contentLength} bytes). Content must be at least 10 bytes.`
155
+ );
124
156
  }
125
-
157
+
126
158
  if (!contentType || contentType === 'application/octet-stream') {
127
- console.log(`[InscribeFromUrlTool] Content-Type unclear, fetching first 1KB to verify...`);
128
-
159
+ console.log(
160
+ `[InscribeFromUrlTool] Content-Type unclear, fetching first 1KB to verify...`
161
+ );
162
+
129
163
  const getController = new AbortController();
130
164
  const getTimeoutId = setTimeout(() => getController.abort(), 5000);
131
-
165
+
132
166
  try {
133
167
  const getResponse = await fetch(params.url, {
134
168
  signal: getController.signal,
135
169
  headers: {
136
- 'Range': 'bytes=0-1023' // Get first 1KB
137
- }
170
+ Range: 'bytes=0-1023', // Get first 1KB
171
+ },
138
172
  });
139
-
173
+
140
174
  clearTimeout(getTimeoutId);
141
-
142
- if (getResponse.ok || getResponse.status === 206) { // 206 is partial content
175
+
176
+ if (getResponse.ok || getResponse.status === 206) {
177
+ // 206 is partial content
143
178
  const buffer = await getResponse.arrayBuffer();
144
179
  const bytes = new Uint8Array(buffer);
145
- const text = new TextDecoder('utf-8', { fatal: false }).decode(bytes.slice(0, 512));
146
-
147
- if (text.toLowerCase().includes('<!doctype html') ||
148
- text.toLowerCase().includes('<html') ||
149
- text.match(/<meta\s+[^>]*>/i) ||
150
- text.match(/<title>/i)) {
151
- throw new Error(`URL returns HTML content. This tool only works with direct file URLs. For web page content, first retrieve it using the appropriate tool, then use inscribeFromBuffer.`);
180
+ const text = new TextDecoder('utf-8', { fatal: false }).decode(
181
+ bytes.slice(0, 512)
182
+ );
183
+
184
+ if (
185
+ text.toLowerCase().includes('<!doctype html') ||
186
+ text.toLowerCase().includes('<html') ||
187
+ text.match(/<meta\s+[^>]*>/i) ||
188
+ text.match(/<title>/i)
189
+ ) {
190
+ throw new Error(
191
+ `URL returns HTML content. This tool only works with direct file URLs. For web page content, first retrieve it using the appropriate tool, then use inscribeFromBuffer.`
192
+ );
152
193
  }
153
194
  }
154
195
  } catch (getError) {
155
196
  clearTimeout(getTimeoutId);
156
- if (getError instanceof Error && getError.message.includes('HTML content')) {
197
+ if (
198
+ getError instanceof Error &&
199
+ getError.message.includes('HTML content')
200
+ ) {
157
201
  throw getError;
158
202
  }
159
- console.log(`[InscribeFromUrlTool] Could not perform partial GET validation: ${getError instanceof Error ? getError.message : 'Unknown error'}`);
203
+ console.log(
204
+ `[InscribeFromUrlTool] Could not perform partial GET validation: ${
205
+ getError instanceof Error ? getError.message : 'Unknown error'
206
+ }`
207
+ );
160
208
  }
161
209
  }
162
210
 
163
- console.log(`[InscribeFromUrlTool] URL validation passed. Content-Type: ${contentType}, Content-Length: ${contentLength || 'unknown'}`);
211
+ console.log(
212
+ `[InscribeFromUrlTool] URL validation passed. Content-Type: ${contentType}, Content-Length: ${
213
+ contentLength || 'unknown'
214
+ }`
215
+ );
164
216
  } catch (fetchError) {
165
217
  clearTimeout(timeoutId);
166
218
  throw fetchError;
@@ -168,11 +220,20 @@ export class InscribeFromUrlTool extends BaseInscriberQueryTool<typeof inscribeF
168
220
  } catch (error) {
169
221
  if (error instanceof Error) {
170
222
  if (error.name === 'AbortError') {
171
- console.log(`[InscribeFromUrlTool] Warning: URL validation timed out after 10 seconds. Proceeding with inscription attempt.`);
172
- } else if (error.message.includes('URL returned error') || error.message.includes('empty content') || error.message.includes('too small') || error.message.includes('HTML')) {
223
+ console.log(
224
+ `[InscribeFromUrlTool] Warning: URL validation timed out after 10 seconds. Proceeding with inscription attempt.`
225
+ );
226
+ } else if (
227
+ error.message.includes('URL returned error') ||
228
+ error.message.includes('empty content') ||
229
+ error.message.includes('too small') ||
230
+ error.message.includes('HTML')
231
+ ) {
173
232
  throw error;
174
233
  } else {
175
- console.log(`[InscribeFromUrlTool] Warning: Could not validate URL with HEAD request: ${error.message}. Proceeding with inscription attempt.`);
234
+ console.log(
235
+ `[InscribeFromUrlTool] Warning: Could not validate URL with HEAD request: ${error.message}. Proceeding with inscription attempt.`
236
+ );
176
237
  }
177
238
  }
178
239
  }
@@ -182,11 +243,17 @@ export class InscribeFromUrlTool extends BaseInscriberQueryTool<typeof inscribeF
182
243
  metadata: params.metadata,
183
244
  tags: params.tags,
184
245
  chunkSize: params.chunkSize,
185
- waitForConfirmation: params.quoteOnly ? false : (params.waitForConfirmation ?? true),
246
+ waitForConfirmation: params.quoteOnly
247
+ ? false
248
+ : params.waitForConfirmation ?? true,
186
249
  waitMaxAttempts: 10,
187
250
  waitIntervalMs: 3000,
188
251
  apiKey: params.apiKey,
189
- network: this.inscriberBuilder['hederaKit'].client.network.toString().includes('mainnet') ? 'mainnet' : 'testnet',
252
+ network: this.inscriberBuilder['hederaKit'].client.network
253
+ .toString()
254
+ .includes('mainnet')
255
+ ? 'mainnet'
256
+ : 'testnet',
190
257
  quoteOnly: params.quoteOnly,
191
258
  };
192
259
 
@@ -196,7 +263,7 @@ export class InscribeFromUrlTool extends BaseInscriberQueryTool<typeof inscribeF
196
263
  { type: 'url', url: params.url },
197
264
  options
198
265
  );
199
-
266
+
200
267
  return {
201
268
  success: true,
202
269
  quote: {
@@ -207,22 +274,27 @@ export class InscribeFromUrlTool extends BaseInscriberQueryTool<typeof inscribeF
207
274
  contentInfo: {
208
275
  url: params.url,
209
276
  },
210
- message: `Quote generated for URL: ${params.url}\nTotal cost: ${quote.totalCostHbar} HBAR`,
277
+ message: `Estimated Quote for URL: ${params.url}\nTotal cost: ${quote.totalCostHbar} HBAR`,
211
278
  };
212
279
  } catch (error) {
213
280
  const errorMessage =
214
- error instanceof Error ? error.message : 'Failed to generate inscription quote';
281
+ error instanceof Error
282
+ ? error.message
283
+ : 'Failed to generate inscription quote';
215
284
  throw new Error(`Quote generation failed: ${errorMessage}`);
216
285
  }
217
286
  }
218
287
 
219
288
  try {
220
289
  let result: Awaited<ReturnType<typeof this.inscriberBuilder.inscribe>>;
221
-
290
+
222
291
  if (params.timeoutMs) {
223
292
  const timeoutPromise = new Promise<never>((_, reject) => {
224
293
  setTimeout(
225
- () => reject(new Error(`Inscription timed out after ${params.timeoutMs}ms`)),
294
+ () =>
295
+ reject(
296
+ new Error(`Inscription timed out after ${params.timeoutMs}ms`)
297
+ ),
226
298
  params.timeoutMs
227
299
  );
228
300
  });
@@ -232,7 +304,7 @@ export class InscribeFromUrlTool extends BaseInscriberQueryTool<typeof inscribeF
232
304
  { type: 'url', url: params.url },
233
305
  options
234
306
  ),
235
- timeoutPromise
307
+ timeoutPromise,
236
308
  ]);
237
309
  } else {
238
310
  result = await this.inscriberBuilder.inscribe(
@@ -242,18 +314,28 @@ export class InscribeFromUrlTool extends BaseInscriberQueryTool<typeof inscribeF
242
314
  }
243
315
 
244
316
  if (result.confirmed && !result.quote) {
245
- const topicId = result.inscription?.topic_id || (result.result as any).topicId;
317
+ const topicId =
318
+ result.inscription?.topic_id || (result.result as any).topicId;
246
319
  const network = options.network || 'testnet';
247
- const cdnUrl = topicId ? `https://kiloscribe.com/api/inscription-cdn/${topicId}?network=${network}` : null;
248
- return `Successfully inscribed and confirmed content on the Hedera network!\n\nTransaction ID: ${(result.result as any).transactionId}\nTopic ID: ${topicId || 'N/A'}${cdnUrl ? `\nView inscription: ${cdnUrl}` : ''}\n\nThe inscription is now available.`;
320
+ const cdnUrl = topicId
321
+ ? `https://kiloscribe.com/api/inscription-cdn/${topicId}?network=${network}`
322
+ : null;
323
+ return `Successfully inscribed and confirmed content on the Hedera network!\n\nTransaction ID: ${
324
+ (result.result as any).transactionId
325
+ }\nTopic ID: ${topicId || 'N/A'}${
326
+ cdnUrl ? `\nView inscription: ${cdnUrl}` : ''
327
+ }\n\nThe inscription is now available.`;
249
328
  } else if (!result.quote && !result.confirmed) {
250
- return `Successfully submitted inscription to the Hedera network!\n\nTransaction ID: ${(result.result as any).transactionId}\n\nThe inscription is processing and will be confirmed shortly.`;
329
+ return `Successfully submitted inscription to the Hedera network!\n\nTransaction ID: ${
330
+ (result.result as any).transactionId
331
+ }\n\nThe inscription is processing and will be confirmed shortly.`;
251
332
  } else {
252
333
  return 'Inscription operation completed.';
253
334
  }
254
335
  } catch (error) {
255
- const errorMessage = error instanceof Error ? error.message : 'Failed to inscribe from URL';
336
+ const errorMessage =
337
+ error instanceof Error ? error.message : 'Failed to inscribe from URL';
256
338
  throw new Error(`Inscription failed: ${errorMessage}`);
257
339
  }
258
340
  }
259
- }
341
+ }
@@ -120,7 +120,7 @@ export class InscribeHashinalTool extends BaseInscriberQueryTool<typeof inscribe
120
120
  creator: params.creator,
121
121
  type: params.type,
122
122
  },
123
- message: `Quote generated for Hashinal NFT: ${params.name}\nCreator: ${params.creator}\nTotal cost: ${quote.totalCostHbar} HBAR`,
123
+ message: `Estimated Quote for Hashinal NFT: ${params.name}\nCreator: ${params.creator}\nTotal cost: ${quote.totalCostHbar} HBAR`,
124
124
  };
125
125
  } catch (error) {
126
126
  const errorMessage =