@hashgraphonline/standards-agent-kit 0.2.135 → 0.2.137

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.
Files changed (59) hide show
  1. package/README.md +3 -4
  2. package/dist/cjs/builders/inscriber/inscriber-builder.d.ts +32 -1
  3. package/dist/cjs/interfaces/FormValidatable.d.ts +4 -13
  4. package/dist/cjs/standards-agent-kit.cjs +1 -1
  5. package/dist/cjs/standards-agent-kit.cjs.map +1 -1
  6. package/dist/cjs/tools/inscriber/InscribeHashinalTool.d.ts +2 -10
  7. package/dist/cjs/types/inscription-response.d.ts +8 -0
  8. package/dist/cjs/utils/inscription-utils.d.ts +21 -0
  9. package/dist/es/builders/inscriber/inscriber-builder.d.ts +32 -1
  10. package/dist/es/interfaces/FormValidatable.d.ts +4 -13
  11. package/dist/es/standards-agent-kit.es3.js +4 -0
  12. package/dist/es/standards-agent-kit.es3.js.map +1 -1
  13. package/dist/es/standards-agent-kit.es34.js +12 -6
  14. package/dist/es/standards-agent-kit.es34.js.map +1 -1
  15. package/dist/es/standards-agent-kit.es35.js +5 -4
  16. package/dist/es/standards-agent-kit.es35.js.map +1 -1
  17. package/dist/es/standards-agent-kit.es36.js +13 -9
  18. package/dist/es/standards-agent-kit.es36.js.map +1 -1
  19. package/dist/es/standards-agent-kit.es37.js +32 -48
  20. package/dist/es/standards-agent-kit.es37.js.map +1 -1
  21. package/dist/es/standards-agent-kit.es38.js +9 -10
  22. package/dist/es/standards-agent-kit.es38.js.map +1 -1
  23. package/dist/es/standards-agent-kit.es44.js +1 -1
  24. package/dist/es/standards-agent-kit.es44.js.map +1 -1
  25. package/dist/es/standards-agent-kit.es47.js +17 -50
  26. package/dist/es/standards-agent-kit.es47.js.map +1 -1
  27. package/dist/es/standards-agent-kit.es48.js +54 -3
  28. package/dist/es/standards-agent-kit.es48.js.map +1 -1
  29. package/dist/es/standards-agent-kit.es49.js +2 -39
  30. package/dist/es/standards-agent-kit.es49.js.map +1 -1
  31. package/dist/es/standards-agent-kit.es50.js +38 -17
  32. package/dist/es/standards-agent-kit.es50.js.map +1 -1
  33. package/dist/es/standards-agent-kit.es51.js +16 -51
  34. package/dist/es/standards-agent-kit.es51.js.map +1 -1
  35. package/dist/es/standards-agent-kit.es52.js +77 -0
  36. package/dist/es/standards-agent-kit.es52.js.map +1 -0
  37. package/dist/es/standards-agent-kit.es6.js +160 -4
  38. package/dist/es/standards-agent-kit.es6.js.map +1 -1
  39. package/dist/es/tools/inscriber/InscribeHashinalTool.d.ts +2 -10
  40. package/dist/es/types/inscription-response.d.ts +8 -0
  41. package/dist/es/utils/inscription-utils.d.ts +21 -0
  42. package/dist/umd/builders/inscriber/inscriber-builder.d.ts +32 -1
  43. package/dist/umd/interfaces/FormValidatable.d.ts +4 -13
  44. package/dist/umd/standards-agent-kit.umd.js +1 -1
  45. package/dist/umd/standards-agent-kit.umd.js.map +1 -1
  46. package/dist/umd/tools/inscriber/InscribeHashinalTool.d.ts +2 -10
  47. package/dist/umd/types/inscription-response.d.ts +8 -0
  48. package/dist/umd/utils/inscription-utils.d.ts +21 -0
  49. package/package.json +9 -4
  50. package/src/builders/hcs10/hcs10-builder.ts +4 -0
  51. package/src/builders/inscriber/inscriber-builder.ts +235 -2
  52. package/src/interfaces/FormValidatable.ts +9 -12
  53. package/src/tools/inscriber/InscribeFromBufferTool.ts +48 -19
  54. package/src/tools/inscriber/InscribeFromFileTool.ts +10 -13
  55. package/src/tools/inscriber/InscribeFromUrlTool.ts +15 -11
  56. package/src/tools/inscriber/InscribeHashinalTool.ts +42 -90
  57. package/src/tools/inscriber/RetrieveInscriptionTool.ts +15 -16
  58. package/src/types/inscription-response.ts +27 -0
  59. package/src/utils/inscription-utils.ts +53 -0
@@ -1,4 +1,3 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
1
  import { z } from 'zod';
3
2
  import { BaseInscriberQueryTool } from './base-inscriber-tools';
4
3
  import {
@@ -6,6 +5,7 @@ import {
6
5
  InscriptionInput,
7
6
  ContentResolverRegistry,
8
7
  Logger,
8
+ InscriptionResult,
9
9
  } from '@hashgraphonline/standards-sdk';
10
10
  import { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';
11
11
  import { validateHIP412Metadata } from '../../validation/hip412-schemas';
@@ -19,9 +19,14 @@ import {
19
19
  createInscriptionSuccess,
20
20
  createInscriptionQuote,
21
21
  createInscriptionError,
22
+ createInscriptionPending,
22
23
  InscriptionResponse,
23
24
  } from '../../types/inscription-response';
24
25
  import { FormValidatable } from '../../interfaces/FormValidatable';
26
+ import {
27
+ extractTopicIds,
28
+ buildInscriptionLinks,
29
+ } from '../../utils/inscription-utils';
25
30
 
26
31
  /**
27
32
  * Network-specific Hashinal block configuration for HashLink blocks
@@ -46,7 +51,6 @@ const HASHLINK_BLOCK_CONFIG = {
46
51
  * @param network The network type to get configuration for
47
52
  * @returns Network-specific block configuration with blockId, hashLink, and template
48
53
  */
49
- // @ts-ignore - keep untyped to satisfy mixed parser while using runtime narrowing
50
54
  function getHashLinkBlockId(network) {
51
55
  const config =
52
56
  network === 'mainnet'
@@ -58,8 +62,6 @@ function getHashLinkBlockId(network) {
58
62
  return config;
59
63
  }
60
64
 
61
- // Note: Using inline return type annotations to avoid parser issues with interface declarations
62
-
63
65
  /**
64
66
  * Schema for inscribing Hashinal NFT
65
67
  */
@@ -205,7 +207,6 @@ export class InscribeHashinalTool
205
207
  description =
206
208
  'Tool for inscribing Hashinal NFTs. CRITICAL: When user provides content (url/contentRef/base64Data), call with ONLY the content parameters - DO NOT auto-generate name, description, creator, or attributes. A form will be automatically shown to collect metadata from the user. Only include metadata parameters if the user explicitly provided them in their message.';
207
209
 
208
- // Declare entity resolution preferences to preserve user-specified literal fields
209
210
  getEntityResolutionPreferences(): Record<string, string> {
210
211
  return {
211
212
  name: 'literal',
@@ -350,20 +351,17 @@ export class InscribeHashinalTool
350
351
  .describe('Trait name (e.g., "Rarity", "Color", "Style")'),
351
352
  value: z
352
353
  .union([z.string(), z.number()])
353
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
354
354
  .describe('Trait value (e.g., "Epic", "Blue", 85)'),
355
355
  })
356
356
  )
357
357
  )
358
358
  .withRender(renderConfigs.array('NFT Attributes', 'Attribute'))
359
359
  .optional()
360
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
361
360
  .describe('Collectible traits and characteristics.'),
362
361
 
363
362
  type: z
364
363
  .string()
365
364
  .optional()
366
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
367
365
  .describe(
368
366
  'Category or genre of the NFT (e.g., "Digital Art", "Photography", "Collectible Card)'
369
367
  ),
@@ -379,35 +377,6 @@ export class InscribeHashinalTool
379
377
  return focusedSchema as unknown as z.ZodObject<z.ZodRawShape>;
380
378
  }
381
379
 
382
- /**
383
- * Implementation of FormValidatable interface
384
- * Validates metadata quality and provides detailed feedback
385
- */
386
- validateMetadataQuality(input: unknown): {
387
- needsForm: boolean;
388
- reason: string;
389
- } {
390
- const inputObj = input as Record<string, unknown>;
391
- const hasRequiredMetadata = !!(
392
- inputObj.name &&
393
- inputObj.description &&
394
- inputObj.creator
395
- );
396
-
397
- if (!hasRequiredMetadata) {
398
- return {
399
- needsForm: true,
400
- reason:
401
- 'Missing essential metadata (name, description, creator) for NFT creation',
402
- };
403
- }
404
-
405
- return {
406
- needsForm: false,
407
- reason: 'All required metadata fields present',
408
- };
409
- }
410
-
411
380
  protected async executeQuery(
412
381
  params: z.infer<typeof inscribeHashinalSchema>,
413
382
  _runManager?: CallbackManagerForToolRun
@@ -552,28 +521,26 @@ export class InscribeHashinalTool
552
521
  });
553
522
 
554
523
  result = await Promise.race([
555
- this.inscriberBuilder.inscribe(inscriptionData, options),
524
+ this.inscriberBuilder.inscribeAuto
525
+ ? this.inscriberBuilder.inscribeAuto(inscriptionData, options)
526
+ : this.inscriberBuilder.inscribe(inscriptionData, options),
556
527
  timeoutPromise,
557
528
  ]);
558
529
  } else {
559
- result = await this.inscriberBuilder.inscribe(inscriptionData, options);
530
+ result = this.inscriberBuilder.inscribeAuto
531
+ ? await this.inscriberBuilder.inscribeAuto(inscriptionData, options)
532
+ : await this.inscriberBuilder.inscribe(inscriptionData, options);
560
533
  }
561
534
 
562
535
  if (result.confirmed && !result.quote) {
563
- const imageTopicId = (
564
- result.inscription as { topic_id?: string; jsonTopicId?: string }
565
- )?.topic_id;
566
- const jsonTopicId = (
567
- result.inscription as { topic_id?: string; jsonTopicId?: string }
568
- )?.jsonTopicId;
536
+ const ids = extractTopicIds(result.inscription, result.result);
569
537
  const network = options.network || 'testnet';
570
-
571
- const cdnUrl = jsonTopicId
572
- ? `https://kiloscribe.com/api/inscription-cdn/${jsonTopicId}?network=${network}`
573
- : null;
574
-
575
538
  const fileStandard = params.fileStandard || '1';
576
- const hrl = jsonTopicId ? `hcs://${fileStandard}/${jsonTopicId}` : null;
539
+ const { hrl, cdnUrl, topicId } = buildInscriptionLinks(
540
+ ids,
541
+ network,
542
+ fileStandard
543
+ );
577
544
  const standardType = fileStandard === '6' ? 'Dynamic' : 'Static';
578
545
 
579
546
  if (!hrl) {
@@ -589,11 +556,10 @@ export class InscribeHashinalTool
589
556
 
590
557
  const inscriptionResponse = createInscriptionSuccess({
591
558
  hrl,
592
- topicId: jsonTopicId || imageTopicId || 'unknown',
559
+ topicId: topicId || 'unknown',
593
560
  standard: standardType as 'Static' | 'Dynamic',
594
561
  cdnUrl: cdnUrl || undefined,
595
- transactionId: (result.result as { transactionId?: string })
596
- ?.transactionId,
562
+ transactionId: (result.result as InscriptionResult)?.transactionId,
597
563
  metadata: {
598
564
  name: params.name,
599
565
  creator: params.creator,
@@ -604,11 +570,10 @@ export class InscribeHashinalTool
604
570
  });
605
571
 
606
572
  this.onEntityCreated?.({
607
- entityId: jsonTopicId || imageTopicId || 'unknown',
573
+ entityId: topicId || 'unknown',
608
574
  entityName: params.name || 'Unnamed Inscription',
609
- entityType: 'topic',
610
- transactionId: (result.result as { transactionId?: string })
611
- ?.transactionId,
575
+ entityType: 'topicId',
576
+ transactionId: (result.result as InscriptionResult)?.transactionId,
612
577
  });
613
578
 
614
579
  if (params.withHashLinkBlocks) {
@@ -622,7 +587,6 @@ export class InscribeHashinalTool
622
587
 
623
588
  inscriptionResponse.hashLinkBlock = blockData;
624
589
  } catch (blockError) {
625
- // Log error but don't fail the inscription
626
590
  const logger = new Logger({ module: 'InscribeHashinalTool' });
627
591
  logger.error('Failed to create HashLink block', {
628
592
  error: blockError,
@@ -632,32 +596,24 @@ export class InscribeHashinalTool
632
596
 
633
597
  return inscriptionResponse;
634
598
  } else if (!result.quote && !result.confirmed) {
635
- const imageTopicId = (
636
- result.inscription as { topic_id?: string; jsonTopicId?: string }
637
- )?.topic_id;
638
- const jsonTopicId = (
639
- result.inscription as { topic_id?: string; jsonTopicId?: string }
640
- )?.jsonTopicId;
641
-
642
- if (jsonTopicId || imageTopicId) {
599
+ const ids = extractTopicIds(result.inscription, result.result);
600
+ if (ids.jsonTopicId || ids.topicId) {
643
601
  const network = options.network || 'testnet';
644
- const cdnUrl = jsonTopicId
645
- ? `https://kiloscribe.com/api/inscription-cdn/${jsonTopicId}?network=${network}`
646
- : null;
647
-
648
602
  const fileStandard = params.fileStandard || '1';
649
- const hrl = jsonTopicId
650
- ? `hcs://${fileStandard}/${jsonTopicId}`
651
- : null;
603
+ const { hrl, cdnUrl, topicId } = buildInscriptionLinks(
604
+ ids,
605
+ network,
606
+ fileStandard
607
+ );
652
608
  const standardType = fileStandard === '6' ? 'Dynamic' : 'Static';
653
609
 
654
610
  if (hrl) {
655
611
  const inscriptionResponse = createInscriptionSuccess({
656
612
  hrl,
657
- topicId: jsonTopicId || imageTopicId || 'unknown',
613
+ topicId: topicId || 'unknown',
658
614
  standard: standardType as 'Static' | 'Dynamic',
659
615
  cdnUrl: cdnUrl || undefined,
660
- transactionId: (result.result as { transactionId?: string })
616
+ transactionId: (result.result as InscriptionResult)
661
617
  ?.transactionId,
662
618
  metadata: {
663
619
  name: params.name,
@@ -669,10 +625,10 @@ export class InscribeHashinalTool
669
625
  });
670
626
 
671
627
  this.onEntityCreated?.({
672
- entityId: jsonTopicId || imageTopicId || 'unknown',
628
+ entityId: topicId || 'unknown',
673
629
  entityName: params.name || 'Unnamed Inscription',
674
- entityType: 'topic',
675
- transactionId: (result.result as { transactionId?: string })
630
+ entityType: 'topicId',
631
+ transactionId: (result.result as InscriptionResult)
676
632
  ?.transactionId,
677
633
  });
678
634
 
@@ -687,7 +643,6 @@ export class InscribeHashinalTool
687
643
 
688
644
  inscriptionResponse.hashLinkBlock = blockData;
689
645
  } catch (blockError) {
690
- // Log error but don't fail the inscription
691
646
  const logger = new Logger({ module: 'InscribeHashinalTool' });
692
647
  logger.error('Failed to create HashLink block', {
693
648
  error: blockError,
@@ -700,17 +655,14 @@ export class InscribeHashinalTool
700
655
  }
701
656
 
702
657
  const transactionId =
703
- (result.result as { transactionId?: string })?.transactionId ||
704
- 'unknown';
705
- return createInscriptionError({
706
- code: 'INSCRIPTION_PENDING',
707
- details: `Inscription submitted but not yet confirmed. Transaction ID: ${transactionId}`,
708
- suggestions: [
709
- 'Wait a few moments for confirmation',
710
- 'Check the transaction status on a Hedera explorer',
711
- "Try the inscription again if it doesn't confirm within 5 minutes",
712
- ],
658
+ (result.result as InscriptionResult)?.transactionId || 'unknown';
659
+ const pending = createInscriptionPending({
660
+ transactionId,
713
661
  });
662
+ return {
663
+ ...pending,
664
+ metadata: { transactionId },
665
+ } as unknown as InscriptionResponse;
714
666
  } else {
715
667
  return createInscriptionError({
716
668
  code: 'UNKNOWN_STATE',
@@ -1,6 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import { BaseInscriberQueryTool } from './base-inscriber-tools';
3
3
  import { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';
4
+ import type { RetrievedInscriptionResult } from '@hashgraphonline/standards-sdk';
4
5
 
5
6
  /**
6
7
  * Schema for retrieving inscription
@@ -51,7 +52,7 @@ export class RetrieveInscriptionTool extends BaseInscriberQueryTool<typeof retri
51
52
  params: z.infer<typeof retrieveInscriptionSchema>,
52
53
  _runManager?: CallbackManagerForToolRun
53
54
  ): Promise<InscriptionRetrievalResult> {
54
- const result = await this.inscriberBuilder.retrieveInscription(
55
+ const result: RetrievedInscriptionResult = await this.inscriberBuilder.retrieveInscription(
55
56
  params.transactionId,
56
57
  {
57
58
  apiKey: params.apiKey,
@@ -59,23 +60,21 @@ export class RetrieveInscriptionTool extends BaseInscriberQueryTool<typeof retri
59
60
  }
60
61
  );
61
62
 
62
- const typedResult = result as unknown as Record<string, unknown>;
63
-
64
63
  return {
65
- inscriptionId: typedResult.inscriptionId as string | undefined,
66
- transactionId: result.transactionId || 'unknown',
67
- topicId: typedResult.topic_id as string | undefined,
68
- status: result.status || 'unknown',
69
- holderId: typedResult.holderId as string | undefined,
64
+ inscriptionId: (result as unknown as { inscriptionId?: string }).inscriptionId,
65
+ transactionId: (result as unknown as { transactionId?: string }).transactionId || 'unknown',
66
+ topicId: (result as unknown as { topic_id?: string; topicId?: string }).topic_id || (result as unknown as { topicId?: string }).topicId,
67
+ status: (result as unknown as { status?: string }).status || 'unknown',
68
+ holderId: (result as unknown as { holderId?: string }).holderId,
70
69
  metadata: result.metadata,
71
- tags: typedResult.tags,
72
- mode: result.mode,
73
- chunks: typedResult.chunks,
74
- createdAt: typedResult.createdAt as string | undefined,
75
- completedAt: (typedResult.completed || typedResult.completedAt) as string | undefined,
76
- fileUrl: result.fileUrl,
77
- mimeType: typedResult.mimeType as string | undefined,
78
- fileSize: typedResult.fileSize as number | undefined,
70
+ tags: (result as unknown as { tags?: unknown }).tags,
71
+ mode: (result as unknown as { mode?: string }).mode,
72
+ chunks: (result as unknown as { chunks?: unknown }).chunks,
73
+ createdAt: (result as unknown as { createdAt?: string }).createdAt,
74
+ completedAt: (result as unknown as { completed?: string; completedAt?: string }).completed || (result as unknown as { completedAt?: string }).completedAt,
75
+ fileUrl: (result as unknown as { fileUrl?: string }).fileUrl,
76
+ mimeType: (result as unknown as { mimeType?: string }).mimeType,
77
+ fileSize: (result as unknown as { fileSize?: number }).fileSize,
79
78
  };
80
79
  }
81
80
  }
@@ -232,3 +232,30 @@ export function createInscriptionError(params: {
232
232
  },
233
233
  };
234
234
  }
235
+
236
+ /**
237
+ * Helper for pending inscription state (submitted but not yet confirmed)
238
+ */
239
+ export function createInscriptionPending(params: {
240
+ transactionId: string;
241
+ details?: string;
242
+ suggestions?: string[];
243
+ }): InscriptionErrorResponse {
244
+ const { transactionId, details, suggestions } = params;
245
+ const d = details || `Inscription submitted but not yet confirmed. Transaction ID: ${transactionId}`;
246
+ return {
247
+ success: false,
248
+ type: 'error',
249
+ title: 'Inscription Submitted (Pending)',
250
+ message: d,
251
+ error: {
252
+ code: 'INSCRIPTION_PENDING',
253
+ details: d,
254
+ suggestions: suggestions || [
255
+ 'Wait a few moments for confirmation',
256
+ 'Check the transaction status on a Hedera explorer',
257
+ "Try the inscription again if it doesn't confirm within 5 minutes",
258
+ ],
259
+ },
260
+ };
261
+ }
@@ -0,0 +1,53 @@
1
+ export type NetworkType = 'mainnet' | 'testnet';
2
+
3
+ export interface TopicIds {
4
+ jsonTopicId?: string;
5
+ topicId?: string;
6
+ }
7
+
8
+ function getStringProp(obj: unknown, key: string): string | undefined {
9
+ if (!obj || typeof obj !== 'object') return undefined;
10
+ const val = (obj as Record<string, unknown>)[key];
11
+ return typeof val === 'string' && val.trim() ? val : undefined;
12
+ }
13
+
14
+ /**
15
+ * Extract topic ids from an inscription and/or result object without using any.
16
+ * - Prefers jsonTopicId when present (for CDN linking)
17
+ * - Collects topic_id/topicId from either inscription or result
18
+ */
19
+ export function extractTopicIds(
20
+ inscription: unknown,
21
+ result?: unknown
22
+ ): TopicIds {
23
+ const jsonTopicId = getStringProp(inscription, 'jsonTopicId');
24
+
25
+ const imageTopicId =
26
+ getStringProp(inscription, 'topic_id') ||
27
+ getStringProp(inscription, 'topicId') ||
28
+ getStringProp(result, 'topicId') ||
29
+ getStringProp(result, 'topic_id');
30
+
31
+ return {
32
+ jsonTopicId: jsonTopicId,
33
+ topicId: imageTopicId,
34
+ };
35
+ }
36
+
37
+ /**
38
+ * Build HRL/CDN URLs from extracted topic ids.
39
+ * - HRL prefers jsonTopicId, falls back to topicId
40
+ * - CDN URL only provided when jsonTopicId is present
41
+ */
42
+ export function buildInscriptionLinks(
43
+ ids: TopicIds,
44
+ network: NetworkType,
45
+ fileStandard: string = '1'
46
+ ): { hrl?: string; cdnUrl?: string; topicId?: string } {
47
+ const chosen = ids.jsonTopicId || ids.topicId;
48
+ const hrl = chosen ? `hcs://${fileStandard}/${chosen}` : undefined;
49
+ const cdnUrl = ids.jsonTopicId
50
+ ? `https://kiloscribe.com/api/inscription-cdn/${ids.jsonTopicId}?network=${network}`
51
+ : undefined;
52
+ return { hrl, cdnUrl, topicId: chosen };
53
+ }