@hashgraphonline/standards-agent-kit 0.2.136 → 0.2.138

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 (211) hide show
  1. package/README.md +3 -4
  2. package/dist/cjs/builders/hcs10/hcs10-builder.d.ts +1 -0
  3. package/dist/cjs/builders/hcs2/hcs2-builder.d.ts +8 -7
  4. package/dist/cjs/builders/hcs6/hcs6-builder.d.ts +5 -4
  5. package/dist/cjs/builders/inscriber/inscriber-builder.d.ts +32 -1
  6. package/dist/cjs/index.d.ts +4 -0
  7. package/dist/cjs/signing/bytes-registry.d.ts +17 -0
  8. package/dist/cjs/signing/signer-provider.d.ts +45 -0
  9. package/dist/cjs/standards-agent-kit.cjs +1 -1
  10. package/dist/cjs/standards-agent-kit.cjs.map +1 -1
  11. package/dist/cjs/tools/hcs10/InitiateConnectionTool.d.ts +4 -4
  12. package/dist/cjs/tools/hcs2/CreateRegistryTool.d.ts +2 -2
  13. package/dist/cjs/tools/hcs2/DeleteEntryTool.d.ts +2 -2
  14. package/dist/cjs/tools/hcs2/UpdateEntryTool.d.ts +2 -2
  15. package/dist/cjs/tools/hcs6/RegisterDynamicHashinalTool.d.ts +10 -10
  16. package/dist/cjs/tools/hcs6/UpdateDynamicHashinalTool.d.ts +8 -8
  17. package/dist/cjs/tools/inscriber/InscribeFromBufferTool.d.ts +5 -4
  18. package/dist/cjs/tools/inscriber/InscribeFromFileTool.d.ts +2 -2
  19. package/dist/cjs/tools/inscriber/InscribeFromUrlTool.d.ts +4 -4
  20. package/dist/cjs/tools/inscriber/InscribeHashinalTool.d.ts +3 -3
  21. package/dist/cjs/types/inscription-response.d.ts +8 -0
  22. package/dist/cjs/types/tx-results.d.ts +15 -0
  23. package/dist/cjs/utils/CodedError.d.ts +4 -0
  24. package/dist/cjs/utils/inscription-utils.d.ts +21 -0
  25. package/dist/cjs/validation/hip412-schemas.d.ts +2 -2
  26. package/dist/es/builders/hcs10/hcs10-builder.d.ts +1 -0
  27. package/dist/es/builders/hcs2/hcs2-builder.d.ts +8 -7
  28. package/dist/es/builders/hcs6/hcs6-builder.d.ts +5 -4
  29. package/dist/es/builders/inscriber/inscriber-builder.d.ts +32 -1
  30. package/dist/es/index.d.ts +4 -0
  31. package/dist/es/signing/bytes-registry.d.ts +17 -0
  32. package/dist/es/signing/signer-provider.d.ts +45 -0
  33. package/dist/es/standards-agent-kit.es.js +46 -42
  34. package/dist/es/standards-agent-kit.es.js.map +1 -1
  35. package/dist/es/standards-agent-kit.es10.js +24 -83
  36. package/dist/es/standards-agent-kit.es10.js.map +1 -1
  37. package/dist/es/standards-agent-kit.es11.js +224 -20
  38. package/dist/es/standards-agent-kit.es11.js.map +1 -1
  39. package/dist/es/standards-agent-kit.es12.js +78 -27
  40. package/dist/es/standards-agent-kit.es12.js.map +1 -1
  41. package/dist/es/standards-agent-kit.es13.js +26 -36
  42. package/dist/es/standards-agent-kit.es13.js.map +1 -1
  43. package/dist/es/standards-agent-kit.es14.js +17 -39
  44. package/dist/es/standards-agent-kit.es14.js.map +1 -1
  45. package/dist/es/standards-agent-kit.es15.js +36 -58
  46. package/dist/es/standards-agent-kit.es15.js.map +1 -1
  47. package/dist/es/standards-agent-kit.es16.js +45 -18
  48. package/dist/es/standards-agent-kit.es16.js.map +1 -1
  49. package/dist/es/standards-agent-kit.es17.js +53 -16
  50. package/dist/es/standards-agent-kit.es17.js.map +1 -1
  51. package/dist/es/standards-agent-kit.es18.js +18 -28
  52. package/dist/es/standards-agent-kit.es18.js.map +1 -1
  53. package/dist/es/standards-agent-kit.es19.js +26 -12
  54. package/dist/es/standards-agent-kit.es19.js.map +1 -1
  55. package/dist/es/standards-agent-kit.es20.js +38 -136
  56. package/dist/es/standards-agent-kit.es20.js.map +1 -1
  57. package/dist/es/standards-agent-kit.es21.js +13 -24
  58. package/dist/es/standards-agent-kit.es21.js.map +1 -1
  59. package/dist/es/standards-agent-kit.es22.js +136 -39
  60. package/dist/es/standards-agent-kit.es22.js.map +1 -1
  61. package/dist/es/standards-agent-kit.es23.js +25 -41
  62. package/dist/es/standards-agent-kit.es23.js.map +1 -1
  63. package/dist/es/standards-agent-kit.es24.js +49 -31
  64. package/dist/es/standards-agent-kit.es24.js.map +1 -1
  65. package/dist/es/standards-agent-kit.es25.js +34 -18
  66. package/dist/es/standards-agent-kit.es25.js.map +1 -1
  67. package/dist/es/standards-agent-kit.es26.js +35 -19
  68. package/dist/es/standards-agent-kit.es26.js.map +1 -1
  69. package/dist/es/standards-agent-kit.es27.js +45 -32
  70. package/dist/es/standards-agent-kit.es27.js.map +1 -1
  71. package/dist/es/standards-agent-kit.es28.js +54 -25
  72. package/dist/es/standards-agent-kit.es28.js.map +1 -1
  73. package/dist/es/standards-agent-kit.es29.js +35 -23
  74. package/dist/es/standards-agent-kit.es29.js.map +1 -1
  75. package/dist/es/standards-agent-kit.es3.js +41 -1545
  76. package/dist/es/standards-agent-kit.es3.js.map +1 -1
  77. package/dist/es/standards-agent-kit.es30.js +23 -39
  78. package/dist/es/standards-agent-kit.es30.js.map +1 -1
  79. package/dist/es/standards-agent-kit.es31.js +30 -28
  80. package/dist/es/standards-agent-kit.es31.js.map +1 -1
  81. package/dist/es/standards-agent-kit.es32.js +45 -32
  82. package/dist/es/standards-agent-kit.es32.js.map +1 -1
  83. package/dist/es/standards-agent-kit.es33.js +50 -89
  84. package/dist/es/standards-agent-kit.es33.js.map +1 -1
  85. package/dist/es/standards-agent-kit.es34.js +35 -228
  86. package/dist/es/standards-agent-kit.es34.js.map +1 -1
  87. package/dist/es/standards-agent-kit.es35.js +87 -212
  88. package/dist/es/standards-agent-kit.es35.js.map +1 -1
  89. package/dist/es/standards-agent-kit.es36.js +188 -128
  90. package/dist/es/standards-agent-kit.es36.js.map +1 -1
  91. package/dist/es/standards-agent-kit.es37.js +167 -561
  92. package/dist/es/standards-agent-kit.es37.js.map +1 -1
  93. package/dist/es/standards-agent-kit.es38.js +236 -31
  94. package/dist/es/standards-agent-kit.es38.js.map +1 -1
  95. package/dist/es/standards-agent-kit.es39.js +483 -206
  96. package/dist/es/standards-agent-kit.es39.js.map +1 -1
  97. package/dist/es/standards-agent-kit.es4.js +359 -81
  98. package/dist/es/standards-agent-kit.es4.js.map +1 -1
  99. package/dist/es/standards-agent-kit.es40.js +39 -135
  100. package/dist/es/standards-agent-kit.es40.js.map +1 -1
  101. package/dist/es/standards-agent-kit.es41.js +244 -28
  102. package/dist/es/standards-agent-kit.es41.js.map +1 -1
  103. package/dist/es/standards-agent-kit.es42.js +132 -418
  104. package/dist/es/standards-agent-kit.es42.js.map +1 -1
  105. package/dist/es/standards-agent-kit.es43.js +28 -184
  106. package/dist/es/standards-agent-kit.es43.js.map +1 -1
  107. package/dist/es/standards-agent-kit.es44.js +423 -3
  108. package/dist/es/standards-agent-kit.es44.js.map +1 -1
  109. package/dist/es/standards-agent-kit.es45.js +185 -24
  110. package/dist/es/standards-agent-kit.es45.js.map +1 -1
  111. package/dist/es/standards-agent-kit.es46.js +3 -3
  112. package/dist/es/standards-agent-kit.es46.js.map +1 -1
  113. package/dist/es/standards-agent-kit.es47.js +21 -50
  114. package/dist/es/standards-agent-kit.es47.js.map +1 -1
  115. package/dist/es/standards-agent-kit.es48.js +8 -3
  116. package/dist/es/standards-agent-kit.es48.js.map +1 -1
  117. package/dist/es/standards-agent-kit.es49.js +3 -39
  118. package/dist/es/standards-agent-kit.es49.js.map +1 -1
  119. package/dist/es/standards-agent-kit.es5.js +1747 -73
  120. package/dist/es/standards-agent-kit.es5.js.map +1 -1
  121. package/dist/es/standards-agent-kit.es50.js +18 -16
  122. package/dist/es/standards-agent-kit.es50.js.map +1 -1
  123. package/dist/es/standards-agent-kit.es51.js +49 -49
  124. package/dist/es/standards-agent-kit.es51.js.map +1 -1
  125. package/dist/es/standards-agent-kit.es52.js +6 -0
  126. package/dist/es/standards-agent-kit.es52.js.map +1 -0
  127. package/dist/es/standards-agent-kit.es53.js +43 -0
  128. package/dist/es/standards-agent-kit.es53.js.map +1 -0
  129. package/dist/es/standards-agent-kit.es54.js +22 -0
  130. package/dist/es/standards-agent-kit.es54.js.map +1 -0
  131. package/dist/es/standards-agent-kit.es55.js +77 -0
  132. package/dist/es/standards-agent-kit.es55.js.map +1 -0
  133. package/dist/es/standards-agent-kit.es56.js +7 -0
  134. package/dist/es/standards-agent-kit.es56.js.map +1 -0
  135. package/dist/es/standards-agent-kit.es6.js +347 -32
  136. package/dist/es/standards-agent-kit.es6.js.map +1 -1
  137. package/dist/es/standards-agent-kit.es7.js +142 -293
  138. package/dist/es/standards-agent-kit.es7.js.map +1 -1
  139. package/dist/es/standards-agent-kit.es8.js +201 -21
  140. package/dist/es/standards-agent-kit.es8.js.map +1 -1
  141. package/dist/es/standards-agent-kit.es9.js +301 -213
  142. package/dist/es/standards-agent-kit.es9.js.map +1 -1
  143. package/dist/es/tools/hcs10/InitiateConnectionTool.d.ts +4 -4
  144. package/dist/es/tools/hcs2/CreateRegistryTool.d.ts +2 -2
  145. package/dist/es/tools/hcs2/DeleteEntryTool.d.ts +2 -2
  146. package/dist/es/tools/hcs2/UpdateEntryTool.d.ts +2 -2
  147. package/dist/es/tools/hcs6/RegisterDynamicHashinalTool.d.ts +10 -10
  148. package/dist/es/tools/hcs6/UpdateDynamicHashinalTool.d.ts +8 -8
  149. package/dist/es/tools/inscriber/InscribeFromBufferTool.d.ts +5 -4
  150. package/dist/es/tools/inscriber/InscribeFromFileTool.d.ts +2 -2
  151. package/dist/es/tools/inscriber/InscribeFromUrlTool.d.ts +4 -4
  152. package/dist/es/tools/inscriber/InscribeHashinalTool.d.ts +3 -3
  153. package/dist/es/types/inscription-response.d.ts +8 -0
  154. package/dist/es/types/tx-results.d.ts +15 -0
  155. package/dist/es/utils/CodedError.d.ts +4 -0
  156. package/dist/es/utils/inscription-utils.d.ts +21 -0
  157. package/dist/es/validation/hip412-schemas.d.ts +2 -2
  158. package/dist/umd/builders/hcs10/hcs10-builder.d.ts +1 -0
  159. package/dist/umd/builders/hcs2/hcs2-builder.d.ts +8 -7
  160. package/dist/umd/builders/hcs6/hcs6-builder.d.ts +5 -4
  161. package/dist/umd/builders/inscriber/inscriber-builder.d.ts +32 -1
  162. package/dist/umd/index.d.ts +4 -0
  163. package/dist/umd/signing/bytes-registry.d.ts +17 -0
  164. package/dist/umd/signing/signer-provider.d.ts +45 -0
  165. package/dist/umd/standards-agent-kit.umd.js +1 -1
  166. package/dist/umd/standards-agent-kit.umd.js.map +1 -1
  167. package/dist/umd/tools/hcs10/InitiateConnectionTool.d.ts +4 -4
  168. package/dist/umd/tools/hcs2/CreateRegistryTool.d.ts +2 -2
  169. package/dist/umd/tools/hcs2/DeleteEntryTool.d.ts +2 -2
  170. package/dist/umd/tools/hcs2/UpdateEntryTool.d.ts +2 -2
  171. package/dist/umd/tools/hcs6/RegisterDynamicHashinalTool.d.ts +10 -10
  172. package/dist/umd/tools/hcs6/UpdateDynamicHashinalTool.d.ts +8 -8
  173. package/dist/umd/tools/inscriber/InscribeFromBufferTool.d.ts +5 -4
  174. package/dist/umd/tools/inscriber/InscribeFromFileTool.d.ts +2 -2
  175. package/dist/umd/tools/inscriber/InscribeFromUrlTool.d.ts +4 -4
  176. package/dist/umd/tools/inscriber/InscribeHashinalTool.d.ts +3 -3
  177. package/dist/umd/types/inscription-response.d.ts +8 -0
  178. package/dist/umd/types/tx-results.d.ts +15 -0
  179. package/dist/umd/utils/CodedError.d.ts +4 -0
  180. package/dist/umd/utils/inscription-utils.d.ts +21 -0
  181. package/dist/umd/validation/hip412-schemas.d.ts +2 -2
  182. package/package.json +10 -5
  183. package/src/builders/hcs10/hcs10-builder.ts +239 -6
  184. package/src/builders/hcs2/hcs2-builder.ts +302 -9
  185. package/src/builders/hcs6/hcs6-builder.ts +79 -4
  186. package/src/builders/inscriber/inscriber-builder.ts +235 -2
  187. package/src/hcs10/HCS10Client.ts +1 -1
  188. package/src/index.ts +5 -1
  189. package/src/lib/zod-render/schema-extension.ts +0 -1
  190. package/src/signing/bytes-registry.ts +501 -0
  191. package/src/signing/signer-provider.ts +120 -0
  192. package/src/tools/hcs2/CreateRegistryTool.ts +30 -5
  193. package/src/tools/hcs2/DeleteEntryTool.ts +16 -2
  194. package/src/tools/hcs2/MigrateRegistryTool.ts +16 -2
  195. package/src/tools/hcs2/QueryRegistryTool.ts +11 -2
  196. package/src/tools/hcs2/RegisterEntryTool.ts +17 -3
  197. package/src/tools/hcs2/UpdateEntryTool.ts +16 -2
  198. package/src/tools/hcs6/CreateDynamicRegistryTool.ts +17 -3
  199. package/src/tools/hcs6/RegisterDynamicHashinalTool.ts +17 -3
  200. package/src/tools/hcs6/UpdateDynamicHashinalTool.ts +17 -3
  201. package/src/tools/inscriber/InscribeFromBufferTool.ts +126 -21
  202. package/src/tools/inscriber/InscribeFromFileTool.ts +10 -13
  203. package/src/tools/inscriber/InscribeFromUrlTool.ts +15 -11
  204. package/src/tools/inscriber/InscribeHashinalTool.ts +40 -168
  205. package/src/tools/inscriber/RetrieveInscriptionTool.ts +15 -16
  206. package/src/types/inscription-response.ts +27 -0
  207. package/src/types/tx-results.ts +18 -0
  208. package/src/utils/CodedError.ts +8 -0
  209. package/src/utils/Encryption.ts +0 -2
  210. package/src/utils/ensure-agent-has-hbar.ts +4 -5
  211. package/src/utils/inscription-utils.ts +53 -0
@@ -1 +1 @@
1
- {"version":3,"file":"standards-agent-kit.es37.js","sources":["../../src/tools/inscriber/InscribeHashinalTool.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { z } from 'zod';\nimport { BaseInscriberQueryTool } from './base-inscriber-tools';\nimport {\n InscriptionOptions,\n InscriptionInput,\n ContentResolverRegistry,\n Logger,\n} from '@hashgraphonline/standards-sdk';\nimport { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';\nimport { validateHIP412Metadata } from '../../validation/hip412-schemas';\nimport { contentRefSchema } from '../../validation/content-ref-schemas';\nimport { generateDefaultMetadata } from '../../utils/metadata-defaults';\nimport {\n extendZodSchema,\n renderConfigs,\n} from '../../lib/zod-render/schema-extension';\nimport {\n createInscriptionSuccess,\n createInscriptionQuote,\n createInscriptionError,\n InscriptionResponse,\n} from '../../types/inscription-response';\nimport { FormValidatable } from '../../interfaces/FormValidatable';\n\n/**\n * Network-specific Hashinal block configuration for HashLink blocks\n */\nconst HASHLINK_BLOCK_CONFIG = {\n testnet: {\n blockId: '0.0.6617393',\n hashLink: 'hcs://12/0.0.6617393',\n template: '0.0.6617393',\n },\n mainnet: {\n blockId: '0.0.TBD',\n hashLink: 'hcs://12/0.0.TBD',\n template: '0.0.TBD',\n },\n};\n\n/**\n * Gets the appropriate HashLink block configuration for the specified network.\n * Provides graceful fallback to testnet for unknown networks or undeployed mainnet blocks.\n *\n * @param network The network type to get configuration for\n * @returns Network-specific block configuration with blockId, hashLink, and template\n */\n// @ts-ignore - keep untyped to satisfy mixed parser while using runtime narrowing\nfunction getHashLinkBlockId(network) {\n const config =\n network === 'mainnet'\n ? HASHLINK_BLOCK_CONFIG.mainnet\n : HASHLINK_BLOCK_CONFIG.testnet;\n if (!config || config.blockId === '0.0.TBD') {\n return HASHLINK_BLOCK_CONFIG.testnet;\n }\n return config;\n}\n\n// Note: Using inline return type annotations to avoid parser issues with interface declarations\n\n/**\n * Schema for inscribing Hashinal NFT\n */\nconst inscribeHashinalSchema = extendZodSchema(\n z.object({\n url: z\n .string()\n .optional()\n .describe(\n 'The URL of the content to inscribe as Hashinal NFT (use this OR contentRef)'\n ),\n contentRef: contentRefSchema\n .optional()\n .describe(\n 'Content reference ID in format \"content-ref:[id]\" for already stored content (use this OR url)'\n ),\n base64Data: z\n .string()\n .optional()\n .describe(\n 'Base64 encoded content data (use this if neither url nor contentRef provided)'\n ),\n fileName: z\n .string()\n .optional()\n .describe(\n 'File name for the content (required when using base64Data or contentRef)'\n ),\n mimeType: z\n .string()\n .optional()\n .describe('MIME type of the content (e.g., \"image/png\", \"image/jpeg\")'),\n name: z\n .string()\n .optional()\n .describe(\n 'Display name for the NFT (e.g., \"Sunset Landscape #42\", \"Digital Abstract Art\")'\n ),\n creator: z\n .string()\n .optional()\n .describe(\n 'Creator account ID, artist name, or brand (e.g., \"0.0.123456\", \"ArtistName\", \"StudioBrand\")'\n ),\n description: z\n .string()\n .optional()\n .describe(\n 'Meaningful description of the artwork, story, or concept behind this NFT'\n ),\n type: z\n .string()\n .optional()\n .describe(\n 'Category or genre of the NFT (e.g., \"Digital Art\", \"Photography\", \"Collectible Card\")'\n ),\n attributes: extendZodSchema(\n z.array(\n z.object({\n trait_type: z.string(),\n value: z.union([z.string(), z.number()]),\n })\n )\n )\n .withRender(renderConfigs.array('NFT Attributes', 'Attribute'))\n .optional()\n .describe(\n 'Collectible traits and characteristics (e.g., \"Rarity\": \"Epic\", \"Color\": \"Blue\", \"Style\": \"Abstract\")'\n ),\n properties: z\n .record(z.unknown())\n .optional()\n .describe('Additional properties'),\n jsonFileURL: z\n .string()\n .url()\n .optional()\n .describe('URL to JSON metadata file'),\n fileStandard: z\n .enum(['1', '6'])\n .optional()\n .default('1')\n .describe(\n 'HCS file standard: 1 for static Hashinals (HCS-5), 6 for dynamic Hashinals (HCS-6)'\n ),\n tags: z.array(z.string()).optional().describe('Tags to categorize the NFT'),\n chunkSize: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Chunk size for large files'),\n waitForConfirmation: z\n .boolean()\n .optional()\n .describe('Whether to wait for inscription confirmation'),\n timeoutMs: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\n 'Timeout in milliseconds for inscription (default: no timeout - waits until completion)'\n ),\n quoteOnly: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'If true, returns a cost quote instead of executing the inscription'\n ),\n withHashLinkBlocks: z\n .boolean()\n .optional()\n .default(true)\n .describe(\n 'If true, creates interactive HashLink blocks for the inscribed content and returns block data alongside the inscription response'\n ),\n renderForm: z\n .boolean()\n .optional()\n .default(true)\n .describe(\n 'Whether to show a form to collect metadata. Set to false only if user provided complete metadata including name, description, creator, and attributes.'\n ),\n })\n).withRender({\n fieldType: 'object',\n ui: {\n label: 'Inscribe Hashinal NFT',\n description: 'Create a Hashinal inscription for NFT minting',\n },\n});\n\n/**\n * Tool for inscribing Hashinal NFTs\n */\nexport class InscribeHashinalTool\n extends BaseInscriberQueryTool\n implements FormValidatable\n{\n name = 'inscribeHashinal';\n description =\n '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.';\n\n // Declare entity resolution preferences to preserve user-specified literal fields\n getEntityResolutionPreferences(): Record<string, string> {\n return {\n name: 'literal',\n description: 'literal',\n creator: 'literal',\n attributes: 'literal',\n properties: 'literal',\n };\n }\n\n get specificInputSchema(): z.ZodObject<z.ZodRawShape> {\n const baseSchema =\n (inscribeHashinalSchema as z.ZodType & { _def?: { schema?: z.ZodType } })\n ._def?.schema || inscribeHashinalSchema;\n return baseSchema as z.ZodObject<z.ZodRawShape>;\n }\n\n private _schemaWithRenderConfig?: z.ZodObject<z.ZodRawShape>;\n\n override get schema(): z.ZodObject<z.ZodRawShape> {\n if (!this._schemaWithRenderConfig) {\n const baseSchema = this.specificInputSchema;\n const schemaWithRender = baseSchema as z.ZodObject<z.ZodRawShape> & {\n _renderConfig?: {\n fieldType: string;\n ui: { label: string; description: string };\n };\n };\n\n if (!schemaWithRender._renderConfig) {\n schemaWithRender._renderConfig = {\n fieldType: 'object',\n ui: {\n label: 'Inscribe Hashinal NFT',\n description: 'Create a Hashinal inscription for NFT minting',\n },\n };\n }\n this._schemaWithRenderConfig = baseSchema;\n }\n return this._schemaWithRenderConfig;\n }\n\n /**\n * Implementation of FormValidatable interface\n * Determines if a form should be generated for the given input\n */\n shouldGenerateForm(input: unknown): boolean {\n const logger = new Logger({ module: 'InscribeHashinalTool' });\n const inputObj = input as Record<string, unknown>;\n\n logger.info('InscribeHashinalTool: Checking if form should be generated', {\n inputKeys: Object.keys(inputObj || {}),\n hasContent: !!(\n inputObj.url ||\n inputObj.contentRef ||\n inputObj.base64Data\n ),\n renderFormProvided: 'renderForm' in inputObj,\n renderFormValue: inputObj.renderForm,\n });\n\n const hasContentSource = !!(\n inputObj.url ||\n inputObj.contentRef ||\n inputObj.base64Data\n );\n\n if (!hasContentSource) {\n logger.info('InscribeHashinalTool: No content source provided');\n return false;\n }\n\n if ('renderForm' in inputObj && inputObj.renderForm === false) {\n logger.info(\n 'InscribeHashinalTool: renderForm=false, skipping form generation'\n );\n return false;\n }\n\n const isNonEmptyString = (v: unknown): v is string => {\n if (typeof v !== 'string') {\n return false;\n }\n if (v.trim().length === 0) {\n return false;\n }\n return true;\n };\n\n const hasRequiredMetadata =\n isNonEmptyString(inputObj.name) &&\n isNonEmptyString(inputObj.description) &&\n isNonEmptyString(inputObj.creator);\n\n if (hasRequiredMetadata) {\n logger.info(\n 'InscribeHashinalTool: Required metadata present, skipping form generation'\n );\n return false;\n }\n\n logger.info(\n 'InscribeHashinalTool: Content provided, showing form for metadata collection'\n );\n return true;\n }\n\n /**\n * Implementation of FormValidatable interface\n * Returns the focused schema for form generation\n */\n getFormSchema(): z.ZodObject<z.ZodRawShape> {\n const focusedSchema = extendZodSchema(\n z.object({\n name: z\n .string()\n .min(1, 'Name is required')\n .describe(\n 'Display name for the NFT (e.g., \"Sunset Landscape #42\", \"Digital Abstract Art\")'\n ),\n\n description: z\n .string()\n .min(1, 'Description is required')\n .describe(\n 'Meaningful description of the artwork, story, or concept behind this NFT'\n ),\n\n creator: z\n .string()\n .min(1, 'Creator is required')\n .describe(\n 'Creator account ID, artist name, or brand (e.g., \"0.0.123456\", \"ArtistName\", \"StudioBrand\")'\n ),\n\n attributes: extendZodSchema(\n z.array(\n z.object({\n trait_type: z\n .string()\n .describe('Trait name (e.g., \"Rarity\", \"Color\", \"Style\")'),\n value: z\n .union([z.string(), z.number()])\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .describe('Trait value (e.g., \"Epic\", \"Blue\", 85)'),\n })\n )\n )\n .withRender(renderConfigs.array('NFT Attributes', 'Attribute'))\n .optional()\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .describe('Collectible traits and characteristics.'),\n\n type: z\n .string()\n .optional()\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .describe(\n 'Category or genre of the NFT (e.g., \"Digital Art\", \"Photography\", \"Collectible Card)'\n ),\n })\n ).withRender({\n fieldType: 'object',\n ui: {\n label: 'Complete NFT Metadata',\n description: 'Provide meaningful metadata to create a valuable NFT',\n },\n });\n\n return focusedSchema as unknown as z.ZodObject<z.ZodRawShape>;\n }\n\n protected async executeQuery(\n params: z.infer<typeof inscribeHashinalSchema>,\n _runManager?: CallbackManagerForToolRun\n ): Promise<InscriptionResponse> {\n if (!params.url && !params.contentRef && !params.base64Data) {\n return createInscriptionError({\n code: 'MISSING_CONTENT',\n details: 'No content source provided',\n suggestions: [\n 'Provide a URL to content you want to inscribe',\n 'Upload a file and use the content reference',\n 'Provide base64-encoded content data',\n ],\n });\n }\n\n const operatorAccount =\n this.inscriberBuilder[\n 'hederaKit'\n ]?.client?.operatorAccountId?.toString() || '0.0.unknown';\n\n const rawMetadata = {\n ...generateDefaultMetadata({\n name: params.name,\n creator: params.creator,\n description: params.description,\n type: params.type,\n fileName: params.fileName,\n mimeType: params.mimeType,\n operatorAccount,\n }),\n attributes: Array.isArray(params.attributes) ? params.attributes : [],\n properties:\n (params.properties as Record<string, unknown> | undefined) || {},\n };\n\n let validatedMetadata;\n try {\n validatedMetadata = validateHIP412Metadata(rawMetadata);\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n return createInscriptionError({\n code: 'METADATA_VALIDATION_FAILED',\n details: `Metadata validation error: ${errorMessage}`,\n suggestions: [\n 'Ensure all required metadata fields are provided',\n 'Check that attribute values are valid',\n 'Verify metadata follows HIP-412 standard',\n ],\n });\n }\n\n const options: InscriptionOptions = {\n mode: 'hashinal',\n metadata: validatedMetadata,\n jsonFileURL: params.jsonFileURL,\n fileStandard: params.fileStandard,\n tags: params.tags,\n chunkSize: params.chunkSize,\n waitForConfirmation: params.quoteOnly\n ? false\n : params.waitForConfirmation ?? true,\n waitMaxAttempts: 60,\n waitIntervalMs: 5000,\n network: this.inscriberBuilder['hederaKit'].client.network\n .toString()\n .includes('mainnet')\n ? 'mainnet'\n : 'testnet',\n quoteOnly: params.quoteOnly,\n };\n\n let inscriptionData: InscriptionInput;\n\n if (params.url) {\n inscriptionData = { type: 'url', url: params.url };\n } else if (params.contentRef || params.base64Data) {\n const inputData = params.contentRef || params.base64Data || '';\n const { buffer, mimeType, fileName } = await this.resolveContent(\n inputData,\n params.mimeType,\n params.fileName\n );\n\n inscriptionData = {\n type: 'buffer' as const,\n buffer,\n fileName: fileName || params.fileName || 'hashinal-content',\n mimeType: mimeType || params.mimeType,\n };\n } else {\n throw new Error('No valid input data provided for inscription');\n }\n\n if (params.quoteOnly) {\n try {\n const quote = await this.generateInscriptionQuote(\n inscriptionData,\n options\n );\n\n return createInscriptionQuote({\n totalCostHbar: quote.totalCostHbar,\n validUntil: quote.validUntil,\n breakdown: quote.breakdown,\n content: {\n name: params.name,\n creator: params.creator,\n type: params.type,\n },\n });\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? error.message\n : 'Failed to generate inscription quote';\n return createInscriptionError({\n code: 'QUOTE_GENERATION_FAILED',\n details: `Quote generation failed: ${errorMessage}`,\n suggestions: [\n 'Check network connectivity',\n 'Verify content is accessible',\n 'Try again in a moment',\n ],\n });\n }\n }\n\n try {\n let result: Awaited<ReturnType<typeof this.inscriberBuilder.inscribe>>;\n\n if (params.timeoutMs) {\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(\n () =>\n reject(\n new Error(`Inscription timed out after ${params.timeoutMs}ms`)\n ),\n params.timeoutMs\n );\n });\n\n result = await Promise.race([\n this.inscriberBuilder.inscribe(inscriptionData, options),\n timeoutPromise,\n ]);\n } else {\n result = await this.inscriberBuilder.inscribe(inscriptionData, options);\n }\n\n if (result.confirmed && !result.quote) {\n const imageTopicId = (\n result.inscription as { topic_id?: string; jsonTopicId?: string }\n )?.topic_id;\n const jsonTopicId = (\n result.inscription as { topic_id?: string; jsonTopicId?: string }\n )?.jsonTopicId;\n const network = options.network || 'testnet';\n\n const cdnUrl = jsonTopicId\n ? `https://kiloscribe.com/api/inscription-cdn/${jsonTopicId}?network=${network}`\n : null;\n\n const fileStandard = params.fileStandard || '1';\n const hrl = jsonTopicId ? `hcs://${fileStandard}/${jsonTopicId}` : null;\n const standardType = fileStandard === '6' ? 'Dynamic' : 'Static';\n\n if (!hrl) {\n return createInscriptionError({\n code: 'MISSING_TOPIC_ID',\n details: 'Inscription completed but topic ID is missing',\n suggestions: [\n 'Try the inscription again',\n 'Contact support if the issue persists',\n ],\n });\n }\n\n const inscriptionResponse = createInscriptionSuccess({\n hrl,\n topicId: jsonTopicId || imageTopicId || 'unknown',\n standard: standardType as 'Static' | 'Dynamic',\n cdnUrl: cdnUrl || undefined,\n transactionId: (result.result as { transactionId?: string })\n ?.transactionId,\n metadata: {\n name: params.name,\n creator: params.creator,\n description: params.description,\n type: params.type,\n attributes: params.attributes,\n },\n });\n\n this.onEntityCreated?.({\n entityId: jsonTopicId || imageTopicId || 'unknown',\n entityName: params.name || 'Unnamed Inscription',\n entityType: 'topicId',\n transactionId: (result.result as { transactionId?: string })\n ?.transactionId,\n });\n\n if (params.withHashLinkBlocks) {\n try {\n const blockData = await this.createHashLinkBlock(\n inscriptionResponse,\n inscriptionData.type === 'buffer'\n ? inscriptionData.mimeType\n : undefined\n );\n\n inscriptionResponse.hashLinkBlock = blockData;\n } catch (blockError) {\n // Log error but don't fail the inscription\n const logger = new Logger({ module: 'InscribeHashinalTool' });\n logger.error('Failed to create HashLink block', {\n error: blockError,\n });\n }\n }\n\n return inscriptionResponse;\n } else if (!result.quote && !result.confirmed) {\n const imageTopicId = (\n result.inscription as { topic_id?: string; jsonTopicId?: string }\n )?.topic_id;\n const jsonTopicId = (\n result.inscription as { topic_id?: string; jsonTopicId?: string }\n )?.jsonTopicId;\n\n if (jsonTopicId || imageTopicId) {\n const network = options.network || 'testnet';\n const cdnUrl = jsonTopicId\n ? `https://kiloscribe.com/api/inscription-cdn/${jsonTopicId}?network=${network}`\n : null;\n\n const fileStandard = params.fileStandard || '1';\n const hrl = jsonTopicId\n ? `hcs://${fileStandard}/${jsonTopicId}`\n : null;\n const standardType = fileStandard === '6' ? 'Dynamic' : 'Static';\n\n if (hrl) {\n const inscriptionResponse = createInscriptionSuccess({\n hrl,\n topicId: jsonTopicId || imageTopicId || 'unknown',\n standard: standardType as 'Static' | 'Dynamic',\n cdnUrl: cdnUrl || undefined,\n transactionId: (result.result as { transactionId?: string })\n ?.transactionId,\n metadata: {\n name: params.name,\n creator: params.creator,\n description: params.description,\n type: params.type,\n attributes: params.attributes,\n },\n });\n\n this.onEntityCreated?.({\n entityId: jsonTopicId || imageTopicId || 'unknown',\n entityName: params.name || 'Unnamed Inscription',\n entityType: 'topicId',\n transactionId: (result.result as { transactionId?: string })\n ?.transactionId,\n });\n\n if (params.withHashLinkBlocks) {\n try {\n const blockData = await this.createHashLinkBlock(\n inscriptionResponse,\n inscriptionData.type === 'buffer'\n ? inscriptionData.mimeType\n : undefined\n );\n\n inscriptionResponse.hashLinkBlock = blockData;\n } catch (blockError) {\n // Log error but don't fail the inscription\n const logger = new Logger({ module: 'InscribeHashinalTool' });\n logger.error('Failed to create HashLink block', {\n error: blockError,\n });\n }\n }\n\n return inscriptionResponse;\n }\n }\n\n const transactionId =\n (result.result as { transactionId?: string })?.transactionId ||\n 'unknown';\n return createInscriptionError({\n code: 'INSCRIPTION_PENDING',\n details: `Inscription submitted but not yet confirmed. Transaction ID: ${transactionId}`,\n suggestions: [\n 'Wait a few moments for confirmation',\n 'Check the transaction status on a Hedera explorer',\n \"Try the inscription again if it doesn't confirm within 5 minutes\",\n ],\n });\n } else {\n return createInscriptionError({\n code: 'UNKNOWN_STATE',\n details: 'Inscription completed but result state is unclear',\n suggestions: [\n 'Check if the inscription was successful manually',\n 'Try the inscription again',\n ],\n });\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? error.message\n : 'Failed to inscribe Hashinal NFT';\n return createInscriptionError({\n code: 'INSCRIPTION_FAILED',\n details: `Inscription failed: ${errorMessage}`,\n suggestions: [\n 'Check network connectivity',\n 'Verify you have sufficient HBAR balance',\n 'Ensure content is accessible and valid',\n 'Try again in a moment',\n ],\n });\n }\n }\n\n /**\n * Creates HashLink block configuration for Hashinal inscriptions.\n * Automatically detects network and selects appropriate block ID configuration.\n * Uses testnet block as fallback for unknown networks or undeployed mainnet blocks.\n *\n * @param response The inscription response containing metadata and network information\n * @param _mimeType Optional MIME type (currently unused, preserved for compatibility)\n * @returns HCS12BlockResult with network-specific block configuration\n *\n * @example\n * ```typescript\n * // Testnet usage (automatic detection from client)\n * const testnetClient = Client.forTestnet();\n * const tool = new InscribeHashinalTool(testnetClient);\n * const block = await tool.createHashLinkBlock(inscriptionResponse);\n * console.log(block.blockId); // '0.0.6617393'\n * console.log(block.hashLink); // 'hcs://12/0.0.6617393'\n *\n * // Mainnet usage (automatic detection from client)\n * const mainnetClient = Client.forMainnet();\n * const tool = new InscribeHashinalTool(mainnetClient);\n * const block = await tool.createHashLinkBlock(inscriptionResponse);\n * console.log(block.blockId); // Network-specific mainnet block ID\n *\n * // HashLink Block Response Structure:\n * {\n * blockId: string; // Hedera account ID format (e.g., '0.0.6617393')\n * hashLink: string; // HCS-12 URL format: 'hcs://12/{blockId}'\n * template: string; // Block template reference matching blockId\n * attributes: { // Metadata for client-side processing\n * name: string; // Content display name\n * creator: string; // Creator account ID\n * topicId: string; // HCS topic containing the inscription\n * hrl: string; // Hedera Resource Locator\n * network: string; // Network type: 'testnet' | 'mainnet'\n * }\n * }\n *\n * // Render function usage in HashLink blocks:\n * // The block's JavaScript render function receives this structure\n * // and can access network-specific resources through attributes.network\n * ```\n */\n private async createHashLinkBlock(\n response: ReturnType<typeof createInscriptionSuccess>,\n _mimeType?: string\n ): Promise<{\n blockId: string;\n hashLink: string;\n template: string;\n attributes: Record<string, unknown>;\n }> {\n const clientNetwork = this.inscriberBuilder['hederaKit'].client.network\n .toString()\n .includes('mainnet')\n ? 'mainnet'\n : 'testnet';\n\n const cdnNetwork = response.inscription.cdnUrl?.includes('mainnet')\n ? 'mainnet'\n : 'testnet';\n\n if (clientNetwork !== cdnNetwork) {\n const logger = new Logger({ module: 'InscribeHashinalTool' });\n logger.warn(\n `Network mismatch detected: client=${clientNetwork}, cdn=${cdnNetwork}. Using client network.`\n );\n }\n\n const network = clientNetwork;\n const config = getHashLinkBlockId(network);\n\n return {\n blockId: config.blockId,\n hashLink: config.hashLink,\n template: config.template,\n attributes: {\n name: response.metadata.name || 'Untitled Content',\n creator: response.metadata.creator || '',\n topicId: response.inscription.topicId,\n hrl: response.inscription.hrl,\n network: network,\n },\n };\n }\n\n private async resolveContent(\n input: string,\n providedMimeType?: string,\n providedFileName?: string\n ): Promise<{\n buffer: Buffer;\n mimeType?: string;\n fileName?: string;\n wasReference?: boolean;\n }> {\n const trimmedInput = input.trim();\n\n const resolver =\n this.getContentResolver() || ContentResolverRegistry.getResolver();\n\n if (!resolver) {\n return this.handleDirectContent(\n trimmedInput,\n providedMimeType,\n providedFileName\n );\n }\n\n const referenceId = resolver.extractReferenceId(trimmedInput);\n\n if (referenceId) {\n try {\n const resolution = await resolver.resolveReference(referenceId);\n\n return {\n buffer: resolution.content,\n mimeType: resolution.metadata?.mimeType || providedMimeType,\n fileName: resolution.metadata?.fileName || providedFileName,\n wasReference: true,\n };\n } catch (error) {\n const errorMsg =\n error instanceof Error\n ? error.message\n : 'Unknown error resolving reference';\n throw new Error(`Reference resolution failed: ${errorMsg}`);\n }\n }\n\n return this.handleDirectContent(\n trimmedInput,\n providedMimeType,\n providedFileName\n );\n }\n\n private handleDirectContent(\n input: string,\n providedMimeType?: string,\n providedFileName?: string\n ): {\n buffer: Buffer;\n mimeType?: string;\n fileName?: string;\n wasReference?: boolean;\n } {\n const isValidBase64 = /^[A-Za-z0-9+/]*={0,2}$/.test(input);\n\n if (isValidBase64) {\n try {\n const buffer = Buffer.from(input, 'base64');\n return {\n buffer,\n mimeType: providedMimeType,\n fileName: providedFileName,\n wasReference: false,\n };\n } catch (error) {\n throw new Error(\n 'Failed to decode base64 data. Please ensure the data is properly encoded.'\n );\n }\n }\n\n const buffer = Buffer.from(input, 'utf8');\n return {\n buffer,\n mimeType: providedMimeType || 'text/plain',\n fileName: providedFileName,\n wasReference: false,\n };\n }\n\n /**\n * Implementation of FormValidatable interface\n * Returns essential fields that should always be shown in forms\n */\n getEssentialFields(): string[] {\n return ['name', 'description', 'creator', 'attributes'];\n }\n\n /**\n * Implementation of FormValidatable interface\n * Determines if a field value should be considered empty for this tool\n */\n isFieldEmpty(fieldName: string, value: unknown): boolean {\n if (value === undefined || value === null || value === '') {\n return true;\n }\n\n if (Array.isArray(value) && value.length === 0) {\n return true;\n }\n\n if (fieldName === 'attributes' && Array.isArray(value)) {\n return value.every(\n (attr) =>\n !attr ||\n (typeof attr === 'object' && (!attr.trait_type || !attr.value))\n );\n }\n\n return false;\n }\n}\n"],"names":["buffer"],"mappings":"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"}
1
+ {"version":3,"file":"standards-agent-kit.es37.js","sources":["../../src/tools/inscriber/InscribeFromFileTool.ts"],"sourcesContent":["import { z } from 'zod';\nimport { BaseInscriberQueryTool } from './base-inscriber-tools';\nimport { InscriptionOptions, InscriptionResponse } from '@hashgraphonline/standards-sdk';\nimport { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport { extractTopicIds, buildInscriptionLinks } from '../../utils/inscription-utils';\n\n/**\n * Schema for inscribing from file\n */\nconst inscribeFromFileSchema = z.object({\n filePath: z\n .string()\n .min(1, 'File path cannot be empty')\n .describe(\n 'The file path of the content to inscribe. Must point to a valid, non-empty file.'\n ),\n mode: z\n .enum(['file', 'hashinal'])\n .optional()\n .describe('Inscription mode: file or hashinal NFT'),\n metadata: z\n .record(z.unknown())\n .optional()\n .describe('Metadata to attach to the inscription'),\n tags: z\n .array(z.string())\n .optional()\n .describe('Tags to categorize the inscription'),\n chunkSize: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Chunk size for large files'),\n waitForConfirmation: z\n .boolean()\n .optional()\n .describe('Whether to wait for inscription confirmation'),\n timeoutMs: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Timeout in milliseconds for inscription (default: no timeout)'),\n apiKey: z.string().optional().describe('API key for inscription service'),\n quoteOnly: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'If true, returns a cost quote instead of executing the inscription'\n ),\n});\n\n/**\n * Tool for inscribing content from file\n */\nexport class InscribeFromFileTool extends BaseInscriberQueryTool<\n typeof inscribeFromFileSchema\n> {\n name = 'inscribeFromFile';\n description =\n 'Inscribe content from a local file to the Hedera network using a file path. IMPORTANT: Only use this tool when you have a valid file path to actual content. The file must exist and contain meaningful data (minimum 10 bytes). For files accessed through MCP filesystem tools, consider reading the file content first and using inscribeFromBuffer instead. Set quoteOnly=true to get cost estimates without executing the inscription.';\n\n get specificInputSchema(): typeof inscribeFromFileSchema {\n return inscribeFromFileSchema;\n }\n\n protected async executeQuery(\n params: z.infer<typeof inscribeFromFileSchema>,\n _runManager?: CallbackManagerForToolRun\n ): Promise<unknown> {\n let fileContent: Buffer;\n try {\n const stats = await fs.stat(params.filePath);\n if (!stats.isFile()) {\n throw new Error(`Path \"${params.filePath}\" is not a file`);\n }\n\n if (stats.size === 0) {\n throw new Error(\n `File \"${params.filePath}\" is empty (0 bytes). Cannot inscribe empty files.`\n );\n }\n\n if (stats.size < 10) {\n throw new Error(\n `File \"${params.filePath}\" is too small (${stats.size} bytes). Files must contain at least 10 bytes of meaningful content.`\n );\n }\n\n if (stats.size > 100 * 1024 * 1024) {\n this.logger?.warn(\n `Large file detected (${(\n stats.size /\n (1024 * 1024)\n ).toFixed(2)} MB)`\n );\n }\n\n this.logger?.info('Reading file content...');\n fileContent = await fs.readFile(params.filePath);\n this.logger?.info(`Read ${fileContent.length} bytes from file`);\n\n if (!fileContent || fileContent.length === 0) {\n throw new Error(\n `File \"${params.filePath}\" has no content after reading. Cannot inscribe empty files.`\n );\n }\n\n if (fileContent.length < 10) {\n throw new Error(\n `File \"${params.filePath}\" content is too small (${fileContent.length} bytes). Files must contain at least 10 bytes of meaningful content.`\n );\n }\n\n const fileName = path.basename(params.filePath);\n const mimeType = this.getMimeType(fileName);\n if (mimeType.startsWith('text/') || mimeType === 'application/json') {\n const textContent = fileContent.toString(\n 'utf8',\n 0,\n Math.min(fileContent.length, 1000)\n );\n if (textContent.trim() === '') {\n throw new Error(\n `File \"${params.filePath}\" contains only whitespace or empty content. Cannot inscribe meaningless data.`\n );\n }\n }\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('ENOENT')) {\n throw new Error(`File not found: \"${params.filePath}\"`);\n }\n throw error;\n }\n throw new Error(`Failed to read file: ${error}`);\n }\n\n const base64Data = fileContent.toString('base64');\n this.logger?.info(`Converted to base64: ${base64Data.length} characters`);\n\n const fileName = path.basename(params.filePath);\n const mimeType = this.getMimeType(fileName);\n this.logger?.info(`File: ${fileName}, MIME type: ${mimeType}`);\n\n const options: InscriptionOptions = {\n mode: params.mode,\n metadata: params.metadata,\n tags: params.tags,\n chunkSize: params.chunkSize,\n waitForConfirmation: params.quoteOnly\n ? false\n : params.waitForConfirmation ?? true,\n waitMaxAttempts: 10,\n waitIntervalMs: 3000,\n apiKey: params.apiKey,\n network: this.inscriberBuilder['hederaKit'].client.network\n .toString()\n .includes('mainnet')\n ? 'mainnet'\n : 'testnet',\n quoteOnly: params.quoteOnly,\n };\n\n if (params.quoteOnly) {\n try {\n const quote = await this.generateInscriptionQuote(\n {\n type: 'buffer',\n buffer: Buffer.from(base64Data, 'base64'),\n fileName,\n mimeType,\n },\n options\n );\n\n return {\n success: true,\n quote: {\n totalCostHbar: quote.totalCostHbar,\n validUntil: quote.validUntil,\n breakdown: quote.breakdown,\n },\n contentInfo: {\n fileName,\n mimeType,\n sizeBytes: fileContent.length,\n filePath: params.filePath,\n },\n message: `Estimated Quote for file: ${fileName} (${(\n fileContent.length / 1024\n ).toFixed(2)} KB)\\nTotal cost: ${\n quote.totalCostHbar\n } HBAR`,\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? error.message\n : 'Failed to generate inscription quote';\n throw new Error(`Quote generation failed: ${errorMessage}`);\n }\n }\n\n try {\n let result: Awaited<ReturnType<typeof this.inscriberBuilder.inscribe>>;\n\n if (params.timeoutMs) {\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(\n () =>\n reject(\n new Error(`Inscription timed out after ${params.timeoutMs}ms`)\n ),\n params.timeoutMs\n );\n });\n\n result = await Promise.race([\n this.inscriberBuilder.inscribe(\n {\n type: 'buffer',\n buffer: Buffer.from(base64Data, 'base64'),\n fileName,\n mimeType,\n },\n options\n ),\n timeoutPromise,\n ]);\n } else {\n result = await this.inscriberBuilder.inscribe(\n {\n type: 'buffer',\n buffer: Buffer.from(base64Data, 'base64'),\n fileName,\n mimeType,\n },\n options\n );\n }\n\n const inscriptionResult = result as InscriptionResponse;\n if (inscriptionResult.confirmed && !inscriptionResult.quote) {\n const ids = extractTopicIds(inscriptionResult.inscription, inscriptionResult.result);\n const network = (options.network || 'testnet') as 'mainnet' | 'testnet';\n const { topicId, cdnUrl } = buildInscriptionLinks(ids, network, '1');\n return `Successfully inscribed and confirmed content on the Hedera network!\\n\\nTransaction ID: ${\n (inscriptionResult.result as { transactionId?: string })?.transactionId ?? 'unknown'\n }\\nTopic ID: ${topicId || 'N/A'}${\n cdnUrl ? `\\nView inscription: ${cdnUrl}` : ''\n }\\n\\nThe inscription is now available.`;\n } else if (!inscriptionResult.quote && !inscriptionResult.confirmed) {\n return `Successfully submitted inscription to the Hedera network!\\n\\nTransaction ID: ${(inscriptionResult.result as { transactionId?: string })?.transactionId ?? 'unknown'}\\n\\nThe inscription is processing and will be confirmed shortly.`;\n } else {\n return 'Inscription operation completed.';\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'Failed to inscribe from file';\n throw new Error(`Inscription failed: ${errorMessage}`);\n }\n }\n\n private getMimeType(fileName: string): string {\n const ext = path.extname(fileName).toLowerCase();\n const mimeTypes: Record<string, string> = {\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.webp': 'image/webp',\n '.svg': 'image/svg+xml',\n '.pdf': 'application/pdf',\n '.json': 'application/json',\n '.txt': 'text/plain',\n '.html': 'text/html',\n '.css': 'text/css',\n '.js': 'application/javascript',\n '.ts': 'application/typescript',\n '.mp4': 'video/mp4',\n '.mp3': 'audio/mpeg',\n '.wav': 'audio/wav',\n '.zip': 'application/zip',\n };\n return mimeTypes[ext] || 'application/octet-stream';\n }\n}\n"],"names":["fileName","mimeType"],"mappings":"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"}
@@ -1,46 +1,251 @@
1
1
  import { z } from "zod";
2
- import { BaseInscriberQueryTool } from "./standards-agent-kit.es33.js";
3
- const retrieveInscriptionSchema = z.object({
4
- transactionId: z.string().describe("The transaction ID of the inscription to retrieve"),
5
- apiKey: z.string().optional().describe("API key for inscription service")
2
+ import { BaseInscriberQueryTool } from "./standards-agent-kit.es35.js";
3
+ import { resolveContent } from "./standards-agent-kit.es51.js";
4
+ import { contentRefSchema } from "./standards-agent-kit.es52.js";
5
+ import { loadConfig } from "./standards-agent-kit.es2.js";
6
+ import { extractTopicIds, buildInscriptionLinks } from "./standards-agent-kit.es50.js";
7
+ const inscribeFromBufferSchema = z.object({
8
+ base64Data: z.union([z.string(), contentRefSchema]).describe(
9
+ "Content to inscribe as base64 data, plain text, or content reference"
10
+ ),
11
+ fileName: z.string().min(1).describe("Name for the inscribed content"),
12
+ mimeType: z.string().optional().describe("MIME type of the content"),
13
+ metadata: z.record(z.unknown()).optional().describe("Metadata to attach"),
14
+ tags: z.array(z.string()).optional().describe("Tags to categorize the inscription"),
15
+ chunkSize: z.number().int().positive().optional().describe("Chunk size for large files"),
16
+ waitForConfirmation: z.boolean().optional().describe("Wait for inscription confirmation"),
17
+ timeoutMs: z.number().int().positive().optional().describe("Timeout in milliseconds"),
18
+ apiKey: z.string().optional().describe("API key for inscription service"),
19
+ quoteOnly: z.boolean().optional().default(false).describe("Return cost quote only")
6
20
  });
7
- class RetrieveInscriptionTool extends BaseInscriberQueryTool {
21
+ class InscribeFromBufferTool extends BaseInscriberQueryTool {
8
22
  constructor() {
9
23
  super(...arguments);
10
- this.name = "retrieveInscription";
11
- this.description = "Retrieve details of an existing inscription from the Hedera network";
24
+ this.name = "inscribeFromBuffer";
25
+ this.description = 'Use ONLY for inscribing regular files or content (NOT for NFT/Hashinal inscriptions). When user says "inscribe it" after you showed search results or other content WITHOUT mentioning NFT/hashinal, use THIS tool. The base64Data field accepts PLAIN TEXT (not just base64) and content reference IDs in format "content-ref:[id]". Pass the EXACT content from your previous response or MCP tool output. DO NOT generate new content or create repetitive text. Content references are automatically resolved to the original content for inscription. Set quoteOnly=true to get cost estimates without executing the inscription. NEVER use this for Hashinal NFTs - always use InscribeHashinalTool instead when user mentions hashinal, NFT, dynamic, or minting.';
26
+ this.config = loadConfig();
12
27
  }
13
28
  get specificInputSchema() {
14
- return retrieveInscriptionSchema;
29
+ return inscribeFromBufferSchema;
15
30
  }
16
- async executeQuery(params, _runManager) {
17
- const result = await this.inscriberBuilder.retrieveInscription(
18
- params.transactionId,
19
- {
20
- apiKey: params.apiKey,
21
- network: this.inscriberBuilder["hederaKit"].client.network.toString().includes("mainnet") ? "mainnet" : "testnet"
31
+ async _call(args, _runManager) {
32
+ try {
33
+ const input = typeof args.base64Data === "string" ? args.base64Data : "";
34
+ const buffer = /^[A-Za-z0-9+/]*={0,2}$/.test(input) ? Buffer.from(input, "base64") : Buffer.from(input, "utf8");
35
+ const fileName = args.fileName;
36
+ const mimeType = args.mimeType;
37
+ const network = this.inscriberBuilder["hederaKit"].client.network.toString().includes("mainnet") ? "mainnet" : "testnet";
38
+ const options = {
39
+ mode: "file",
40
+ metadata: args.metadata,
41
+ tags: args.tags,
42
+ chunkSize: args.chunkSize,
43
+ waitForConfirmation: args.quoteOnly ? false : args.waitForConfirmation ?? true,
44
+ waitMaxAttempts: 60,
45
+ waitIntervalMs: 5e3,
46
+ apiKey: args.apiKey,
47
+ network,
48
+ quoteOnly: args.quoteOnly
49
+ };
50
+ const result = await this.inscriberBuilder.inscribe(
51
+ { type: "buffer", buffer, fileName, mimeType },
52
+ options
53
+ );
54
+ const typed = result;
55
+ if (typed.confirmed && !typed.quote) {
56
+ const ids = extractTopicIds(typed.inscription, typed.result);
57
+ const { topicId, cdnUrl } = buildInscriptionLinks(ids, network, "1");
58
+ return JSON.stringify({
59
+ success: true,
60
+ data: `Successfully inscribed and confirmed content on the Hedera network!
61
+
62
+ Transaction ID: ${typed.result?.transactionId ?? "unknown"}
63
+ Topic ID: ${topicId || "N/A"}${cdnUrl ? `
64
+ View inscription: ${cdnUrl}` : ""}
65
+
66
+ The inscription is now available.`
67
+ });
22
68
  }
69
+ return JSON.stringify({
70
+ success: true,
71
+ data: `Successfully submitted inscription to the Hedera network!
72
+
73
+ Transaction ID: ${typed.result?.transactionId ?? "unknown"}
74
+
75
+ The inscription is processing and will be confirmed shortly.`
76
+ });
77
+ } catch (error) {
78
+ const errorMessage = error instanceof Error ? error.message : String(error);
79
+ return JSON.stringify({ success: false, error: `Inscription failed: ${errorMessage}` });
80
+ }
81
+ }
82
+ async executeQuery(params, _runManager) {
83
+ const resolvedContent = await resolveContent(
84
+ params.base64Data,
85
+ params.mimeType,
86
+ params.fileName
23
87
  );
24
- const typedResult = result;
25
- return {
26
- inscriptionId: typedResult.inscriptionId,
27
- transactionId: result.transactionId || "unknown",
28
- topicId: typedResult.topic_id,
29
- status: result.status || "unknown",
30
- holderId: typedResult.holderId,
31
- metadata: result.metadata,
32
- tags: typedResult.tags,
33
- mode: result.mode,
34
- chunks: typedResult.chunks,
35
- createdAt: typedResult.createdAt,
36
- completedAt: typedResult.completed || typedResult.completedAt,
37
- fileUrl: result.fileUrl,
38
- mimeType: typedResult.mimeType,
39
- fileSize: typedResult.fileSize
88
+ console.log("[InscribeFromBufferTool] Resolved content bytes:", resolvedContent.buffer?.length ?? -1);
89
+ try {
90
+ this.validateContent(resolvedContent.buffer);
91
+ } catch (validationError) {
92
+ this.logger?.warn(
93
+ `Content validation warning: ${validationError instanceof Error ? validationError.message : String(validationError)}`
94
+ );
95
+ }
96
+ const buffer = resolvedContent.buffer;
97
+ const resolvedMimeType = resolvedContent.mimeType || params.mimeType;
98
+ const resolvedFileName = resolvedContent.fileName || params.fileName;
99
+ const options = {
100
+ mode: "file",
101
+ metadata: params.metadata,
102
+ tags: params.tags,
103
+ chunkSize: params.chunkSize,
104
+ waitForConfirmation: params.quoteOnly ? false : params.waitForConfirmation ?? true,
105
+ waitMaxAttempts: 60,
106
+ waitIntervalMs: 5e3,
107
+ apiKey: params.apiKey,
108
+ network: this.inscriberBuilder["hederaKit"].client.network.toString().includes("mainnet") ? "mainnet" : "testnet",
109
+ quoteOnly: params.quoteOnly
40
110
  };
111
+ if (params.quoteOnly) {
112
+ try {
113
+ const quote = await this.generateInscriptionQuote(
114
+ {
115
+ type: "buffer",
116
+ buffer,
117
+ fileName: resolvedFileName,
118
+ mimeType: resolvedMimeType
119
+ },
120
+ options
121
+ );
122
+ return {
123
+ success: true,
124
+ quote: {
125
+ totalCostHbar: quote.totalCostHbar,
126
+ validUntil: quote.validUntil,
127
+ breakdown: quote.breakdown
128
+ },
129
+ contentInfo: {
130
+ fileName: resolvedFileName,
131
+ mimeType: resolvedMimeType,
132
+ sizeBytes: buffer.length
133
+ },
134
+ message: `Estimated Quote for buffer content: ${resolvedFileName} (${(buffer.length / 1024).toFixed(2)} KB)
135
+ Total cost: ${quote.totalCostHbar} HBAR`
136
+ };
137
+ } catch (error) {
138
+ const errorMessage = error instanceof Error ? error.message : "Failed to generate inscription quote";
139
+ throw new Error(`Quote generation failed: ${errorMessage}`);
140
+ }
141
+ }
142
+ try {
143
+ console.log("[InscribeFromBufferTool] Calling inscribe with fileName:", resolvedFileName, "mime:", resolvedMimeType);
144
+ const result = await this.executeInscription(
145
+ buffer,
146
+ resolvedFileName,
147
+ resolvedMimeType,
148
+ options,
149
+ params.timeoutMs
150
+ );
151
+ console.log("[InscribeFromBufferTool] Inscribe result (confirmed):", Boolean(result?.confirmed));
152
+ return this.formatInscriptionResult(result, options);
153
+ } catch (error) {
154
+ console.warn("[InscribeFromBufferTool] Error during inscription:", error);
155
+ const errorMessage = error instanceof Error ? error.message : "Failed to inscribe from buffer";
156
+ throw new Error(`Inscription failed: ${errorMessage}`);
157
+ }
158
+ }
159
+ validateInput(params) {
160
+ if (!params.base64Data || params.base64Data.trim() === "") {
161
+ throw new Error(
162
+ "No data provided. Cannot inscribe empty content. Please provide valid content, plain text, base64 encoded data, or a content reference ID."
163
+ );
164
+ }
165
+ if (!params.fileName || params.fileName.trim() === "") {
166
+ throw new Error(
167
+ "No fileName provided. A valid fileName is required for inscription."
168
+ );
169
+ }
170
+ }
171
+ validateContent(buffer) {
172
+ if (buffer.length === 0) {
173
+ throw new Error(
174
+ "Buffer is empty after conversion. The provided data appears to be invalid or empty."
175
+ );
176
+ }
177
+ if (buffer.length > this.config.maxInscriptionSize) {
178
+ const maxSizeKB = Math.round(this.config.maxInscriptionSize / 1024);
179
+ const bufferSizeKB = Math.round(buffer.length / 1024);
180
+ throw new Error(
181
+ `Content is too large for inscription (${bufferSizeKB}KB, max ${maxSizeKB}KB). Please summarize or extract key information before inscribing.`
182
+ );
183
+ }
184
+ if (buffer.length < this.config.minContentSize) {
185
+ throw new Error(
186
+ `Buffer content is too small (${buffer.length} bytes). This may indicate empty or invalid content. Please verify the source data contains actual content.`
187
+ );
188
+ }
189
+ if (buffer.toString("utf8", 0, Math.min(buffer.length, 100)).trim() === "") {
190
+ throw new Error(
191
+ "Buffer contains only whitespace or empty content. Cannot inscribe meaningless data."
192
+ );
193
+ }
194
+ const contentStr = buffer.toString("utf8");
195
+ const emptyHtmlPattern = /<a\s+href=["'][^"']+["']\s*>\s*<\/a>/i;
196
+ const hasOnlyEmptyLinks = emptyHtmlPattern.test(contentStr) && contentStr.replace(/<[^>]+>/g, "").trim().length < 50;
197
+ if (hasOnlyEmptyLinks) {
198
+ throw new Error(
199
+ "Buffer contains empty HTML with only links and no actual content. When inscribing content from external sources, use the actual article text you retrieved, not empty HTML with links."
200
+ );
201
+ }
202
+ }
203
+ async executeInscription(buffer, fileName, mimeType, options, timeoutMs) {
204
+ const inscriptionData = {
205
+ type: "buffer",
206
+ buffer,
207
+ fileName,
208
+ mimeType
209
+ };
210
+ if (timeoutMs) {
211
+ const timeoutPromise = new Promise((_, reject) => {
212
+ setTimeout(
213
+ () => reject(new Error(`Inscription timed out after ${timeoutMs}ms`)),
214
+ timeoutMs
215
+ );
216
+ });
217
+ return Promise.race([
218
+ this.inscriberBuilder.inscribe(inscriptionData, options),
219
+ timeoutPromise
220
+ ]);
221
+ }
222
+ return this.inscriberBuilder.inscribe(inscriptionData, options);
223
+ }
224
+ formatInscriptionResult(result, options) {
225
+ const typed = result;
226
+ if (typed.confirmed && !typed.quote) {
227
+ const ids = extractTopicIds(typed.inscription, typed.result);
228
+ const network = options.network || "testnet";
229
+ const { topicId, cdnUrl } = buildInscriptionLinks(ids, network, "1");
230
+ return `Successfully inscribed and confirmed content on the Hedera network!
231
+
232
+ Transaction ID: ${typed.result?.transactionId ?? "unknown"}
233
+ Topic ID: ${topicId || "N/A"}${cdnUrl ? `
234
+ View inscription: ${cdnUrl}` : ""}
235
+
236
+ The inscription is now available.`;
237
+ }
238
+ if (!typed.quote && !typed.confirmed) {
239
+ return `Successfully submitted inscription to the Hedera network!
240
+
241
+ Transaction ID: ${typed.result?.transactionId ?? "unknown"}
242
+
243
+ The inscription is processing and will be confirmed shortly.`;
244
+ }
245
+ return "Inscription operation completed.";
41
246
  }
42
247
  }
43
248
  export {
44
- RetrieveInscriptionTool
249
+ InscribeFromBufferTool
45
250
  };
46
251
  //# sourceMappingURL=standards-agent-kit.es38.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"standards-agent-kit.es38.js","sources":["../../src/tools/inscriber/RetrieveInscriptionTool.ts"],"sourcesContent":["import { z } from 'zod';\nimport { BaseInscriberQueryTool } from './base-inscriber-tools';\nimport { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';\n\n/**\n * Schema for retrieving inscription\n */\nconst retrieveInscriptionSchema = z.object({\n transactionId: z\n .string()\n .describe('The transaction ID of the inscription to retrieve'),\n apiKey: z\n .string()\n .optional()\n .describe('API key for inscription service'),\n});\n\n/**\n * Type definition for inscription retrieval result\n */\ninterface InscriptionRetrievalResult {\n inscriptionId?: string;\n transactionId: string;\n topicId?: string;\n status?: string;\n holderId?: string;\n metadata?: unknown;\n tags?: unknown;\n mode?: string;\n chunks?: unknown;\n createdAt?: string;\n completedAt?: string;\n fileUrl?: string;\n mimeType?: string;\n fileSize?: number;\n}\n\n\n/**\n * Tool for retrieving inscriptions\n */\nexport class RetrieveInscriptionTool extends BaseInscriberQueryTool<typeof retrieveInscriptionSchema> {\n name = 'retrieveInscription';\n description = 'Retrieve details of an existing inscription from the Hedera network';\n\n get specificInputSchema() {\n return retrieveInscriptionSchema;\n }\n\n protected async executeQuery(\n params: z.infer<typeof retrieveInscriptionSchema>,\n _runManager?: CallbackManagerForToolRun\n ): Promise<InscriptionRetrievalResult> {\n const result = await this.inscriberBuilder.retrieveInscription(\n params.transactionId,\n {\n apiKey: params.apiKey,\n network: this.inscriberBuilder['hederaKit'].client.network.toString().includes('mainnet') ? 'mainnet' : 'testnet',\n }\n );\n\n const typedResult = result as unknown as Record<string, unknown>;\n\n return {\n inscriptionId: typedResult.inscriptionId as string | undefined,\n transactionId: result.transactionId || 'unknown',\n topicId: typedResult.topic_id as string | undefined,\n status: result.status || 'unknown',\n holderId: typedResult.holderId as string | undefined,\n metadata: result.metadata,\n tags: typedResult.tags,\n mode: result.mode,\n chunks: typedResult.chunks,\n createdAt: typedResult.createdAt as string | undefined,\n completedAt: (typedResult.completed || typedResult.completedAt) as string | undefined,\n fileUrl: result.fileUrl,\n mimeType: typedResult.mimeType as string | undefined,\n fileSize: typedResult.fileSize as number | undefined,\n };\n }\n}"],"names":[],"mappings":";;AAOA,MAAM,4BAA4B,EAAE,OAAO;AAAA,EACzC,eAAe,EACZ,SACA,SAAS,mDAAmD;AAAA,EAC/D,QAAQ,EACL,OAAA,EACA,SAAA,EACA,SAAS,iCAAiC;AAC/C,CAAC;AA0BM,MAAM,gCAAgC,uBAAyD;AAAA,EAA/F,cAAA;AAAA,UAAA,GAAA,SAAA;AACL,SAAA,OAAO;AACP,SAAA,cAAc;AAAA,EAAA;AAAA,EAEd,IAAI,sBAAsB;AACxB,WAAO;AAAA,EACT;AAAA,EAEA,MAAgB,aACd,QACA,aACqC;AACrC,UAAM,SAAS,MAAM,KAAK,iBAAiB;AAAA,MACzC,OAAO;AAAA,MACP;AAAA,QACE,QAAQ,OAAO;AAAA,QACf,SAAS,KAAK,iBAAiB,WAAW,EAAE,OAAO,QAAQ,WAAW,SAAS,SAAS,IAAI,YAAY;AAAA,MAAA;AAAA,IAC1G;AAGF,UAAM,cAAc;AAEpB,WAAO;AAAA,MACL,eAAe,YAAY;AAAA,MAC3B,eAAe,OAAO,iBAAiB;AAAA,MACvC,SAAS,YAAY;AAAA,MACrB,QAAQ,OAAO,UAAU;AAAA,MACzB,UAAU,YAAY;AAAA,MACtB,UAAU,OAAO;AAAA,MACjB,MAAM,YAAY;AAAA,MAClB,MAAM,OAAO;AAAA,MACb,QAAQ,YAAY;AAAA,MACpB,WAAW,YAAY;AAAA,MACvB,aAAc,YAAY,aAAa,YAAY;AAAA,MACnD,SAAS,OAAO;AAAA,MAChB,UAAU,YAAY;AAAA,MACtB,UAAU,YAAY;AAAA,IAAA;AAAA,EAE1B;AACF;"}
1
+ {"version":3,"file":"standards-agent-kit.es38.js","sources":["../../src/tools/inscriber/InscribeFromBufferTool.ts"],"sourcesContent":["import { z } from 'zod';\nimport { BaseInscriberQueryTool } from './base-inscriber-tools';\nimport {\n InscriptionOptions,\n InscriptionResponse,\n InscriptionResult,\n} from '@hashgraphonline/standards-sdk';\nimport { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';\nimport { resolveContent } from '../../utils/content-resolver';\nimport { contentRefSchema } from '../../validation/content-ref-schemas';\nimport { loadConfig } from '../../config/ContentReferenceConfig';\nimport {\n extractTopicIds,\n buildInscriptionLinks,\n} from '../../utils/inscription-utils';\n\nconst inscribeFromBufferSchema = z.object({\n base64Data: z\n .union([z.string(), contentRefSchema])\n .describe(\n 'Content to inscribe as base64 data, plain text, or content reference'\n ),\n fileName: z.string().min(1).describe('Name for the inscribed content'),\n mimeType: z.string().optional().describe('MIME type of the content'),\n metadata: z.record(z.unknown()).optional().describe('Metadata to attach'),\n tags: z\n .array(z.string())\n .optional()\n .describe('Tags to categorize the inscription'),\n chunkSize: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Chunk size for large files'),\n waitForConfirmation: z\n .boolean()\n .optional()\n .describe('Wait for inscription confirmation'),\n timeoutMs: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Timeout in milliseconds'),\n apiKey: z.string().optional().describe('API key for inscription service'),\n quoteOnly: z\n .boolean()\n .optional()\n .default(false)\n .describe('Return cost quote only'),\n});\n\nexport class InscribeFromBufferTool extends BaseInscriberQueryTool<\n typeof inscribeFromBufferSchema\n> {\n name = 'inscribeFromBuffer';\n description =\n 'Use ONLY for inscribing regular files or content (NOT for NFT/Hashinal inscriptions). When user says \"inscribe it\" after you showed search results or other content WITHOUT mentioning NFT/hashinal, use THIS tool. The base64Data field accepts PLAIN TEXT (not just base64) and content reference IDs in format \"content-ref:[id]\". Pass the EXACT content from your previous response or MCP tool output. DO NOT generate new content or create repetitive text. Content references are automatically resolved to the original content for inscription. Set quoteOnly=true to get cost estimates without executing the inscription. NEVER use this for Hashinal NFTs - always use InscribeHashinalTool instead when user mentions hashinal, NFT, dynamic, or minting.';\n\n private config = loadConfig();\n\n get specificInputSchema() {\n return inscribeFromBufferSchema;\n }\n\n protected override async _call(\n args: z.infer<typeof inscribeFromBufferSchema>,\n _runManager?: CallbackManagerForToolRun\n ): Promise<string> {\n try {\n const input = typeof args.base64Data === 'string' ? args.base64Data : '';\n const buffer = /^[A-Za-z0-9+/]*={0,2}$/.test(input)\n ? Buffer.from(input, 'base64')\n : Buffer.from(input, 'utf8');\n\n const fileName = args.fileName;\n const mimeType = args.mimeType;\n\n const network = this.inscriberBuilder['hederaKit'].client.network\n .toString()\n .includes('mainnet')\n ? 'mainnet'\n : 'testnet';\n\n const options: InscriptionOptions = {\n mode: 'file',\n metadata: args.metadata,\n tags: args.tags,\n chunkSize: args.chunkSize,\n waitForConfirmation: args.quoteOnly ? false : args.waitForConfirmation ?? true,\n waitMaxAttempts: 60,\n waitIntervalMs: 5000,\n apiKey: args.apiKey,\n network,\n quoteOnly: args.quoteOnly,\n };\n\n const result = await this.inscriberBuilder.inscribe(\n { type: 'buffer', buffer, fileName, mimeType },\n options\n );\n\n const typed = result as InscriptionResponse;\n if (typed.confirmed && !typed.quote) {\n const ids = extractTopicIds(typed.inscription, typed.result);\n const { topicId, cdnUrl } = buildInscriptionLinks(ids, network, '1');\n return JSON.stringify({\n success: true,\n data: `Successfully inscribed and confirmed content on the Hedera network!\\n\\nTransaction ID: ${\n (typed.result as InscriptionResult)?.transactionId ?? 'unknown'\n }\\nTopic ID: ${topicId || 'N/A'}${\n cdnUrl ? `\\nView inscription: ${cdnUrl}` : ''\n }\\n\\nThe inscription is now available.`,\n });\n }\n\n return JSON.stringify({\n success: true,\n data: `Successfully submitted inscription to the Hedera network!\\n\\nTransaction ID: ${\n (typed.result as InscriptionResult)?.transactionId ?? 'unknown'\n }\\n\\nThe inscription is processing and will be confirmed shortly.`,\n });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return JSON.stringify({ success: false, error: `Inscription failed: ${errorMessage}` });\n }\n }\n\n protected async executeQuery(\n params: z.infer<typeof inscribeFromBufferSchema>,\n _runManager?: CallbackManagerForToolRun\n ): Promise<unknown> {\n\n const resolvedContent = await resolveContent(\n params.base64Data,\n params.mimeType,\n params.fileName\n );\n console.log('[InscribeFromBufferTool] Resolved content bytes:', resolvedContent.buffer?.length ?? -1);\n\n try {\n this.validateContent(resolvedContent.buffer);\n } catch (validationError) {\n this.logger?.warn(\n `Content validation warning: ${\n validationError instanceof Error\n ? validationError.message\n : String(validationError)\n }`\n );\n }\n\n const buffer = resolvedContent.buffer;\n const resolvedMimeType = resolvedContent.mimeType || params.mimeType;\n const resolvedFileName = resolvedContent.fileName || params.fileName;\n\n const options: InscriptionOptions = {\n mode: 'file',\n metadata: params.metadata,\n tags: params.tags,\n chunkSize: params.chunkSize,\n waitForConfirmation: params.quoteOnly\n ? false\n : params.waitForConfirmation ?? true,\n waitMaxAttempts: 60,\n waitIntervalMs: 5000,\n apiKey: params.apiKey,\n network: this.inscriberBuilder['hederaKit'].client.network\n .toString()\n .includes('mainnet')\n ? 'mainnet'\n : 'testnet',\n quoteOnly: params.quoteOnly,\n };\n\n if (params.quoteOnly) {\n try {\n const quote = await this.generateInscriptionQuote(\n {\n type: 'buffer',\n buffer,\n fileName: resolvedFileName,\n mimeType: resolvedMimeType,\n },\n options\n );\n\n return {\n success: true,\n quote: {\n totalCostHbar: quote.totalCostHbar,\n validUntil: quote.validUntil,\n breakdown: quote.breakdown,\n },\n contentInfo: {\n fileName: resolvedFileName,\n mimeType: resolvedMimeType,\n sizeBytes: buffer.length,\n },\n message: `Estimated Quote for buffer content: ${resolvedFileName} (${(\n buffer.length / 1024\n ).toFixed(2)} KB)\\nTotal cost: ${quote.totalCostHbar} HBAR`,\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? error.message\n : 'Failed to generate inscription quote';\n throw new Error(`Quote generation failed: ${errorMessage}`);\n }\n }\n\n try {\n console.log('[InscribeFromBufferTool] Calling inscribe with fileName:', resolvedFileName, 'mime:', resolvedMimeType);\n const result = await this.executeInscription(\n buffer,\n resolvedFileName,\n resolvedMimeType,\n options,\n params.timeoutMs\n );\n console.log('[InscribeFromBufferTool] Inscribe result (confirmed):', Boolean((result as any)?.confirmed));\n return this.formatInscriptionResult(result, options);\n } catch (error) {\n console.warn('[InscribeFromBufferTool] Error during inscription:', error);\n const errorMessage =\n error instanceof Error\n ? error.message\n : 'Failed to inscribe from buffer';\n throw new Error(`Inscription failed: ${errorMessage}`);\n }\n }\n\n private validateInput(\n params: z.infer<typeof inscribeFromBufferSchema>\n ): void {\n if (!params.base64Data || params.base64Data.trim() === '') {\n throw new Error(\n 'No data provided. Cannot inscribe empty content. Please provide valid content, plain text, base64 encoded data, or a content reference ID.'\n );\n }\n\n if (!params.fileName || params.fileName.trim() === '') {\n throw new Error(\n 'No fileName provided. A valid fileName is required for inscription.'\n );\n }\n }\n\n private validateContent(buffer: Buffer): void {\n if (buffer.length === 0) {\n throw new Error(\n 'Buffer is empty after conversion. The provided data appears to be invalid or empty.'\n );\n }\n\n if (buffer.length > this.config.maxInscriptionSize) {\n const maxSizeKB = Math.round(this.config.maxInscriptionSize / 1024);\n const bufferSizeKB = Math.round(buffer.length / 1024);\n throw new Error(\n `Content is too large for inscription (${bufferSizeKB}KB, max ${maxSizeKB}KB). Please summarize or extract key information before inscribing.`\n );\n }\n\n if (buffer.length < this.config.minContentSize) {\n throw new Error(\n `Buffer content is too small (${buffer.length} bytes). This may indicate empty or invalid content. Please verify the source data contains actual content.`\n );\n }\n\n if (\n buffer.toString('utf8', 0, Math.min(buffer.length, 100)).trim() === ''\n ) {\n throw new Error(\n 'Buffer contains only whitespace or empty content. Cannot inscribe meaningless data.'\n );\n }\n\n const contentStr = buffer.toString('utf8');\n const emptyHtmlPattern = /<a\\s+href=[\"'][^\"']+[\"']\\s*>\\s*<\\/a>/i;\n const hasOnlyEmptyLinks =\n emptyHtmlPattern.test(contentStr) &&\n contentStr.replace(/<[^>]+>/g, '').trim().length < 50;\n\n if (hasOnlyEmptyLinks) {\n throw new Error(\n 'Buffer contains empty HTML with only links and no actual content. When inscribing content from external sources, use the actual article text you retrieved, not empty HTML with links.'\n );\n }\n }\n\n private async executeInscription(\n buffer: Buffer,\n fileName: string,\n mimeType: string | undefined,\n options: InscriptionOptions,\n timeoutMs?: number\n ): Promise<Awaited<ReturnType<typeof this.inscriberBuilder.inscribe>>> {\n const inscriptionData = {\n type: 'buffer' as const,\n buffer,\n fileName,\n mimeType,\n };\n\n if (timeoutMs) {\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(\n () => reject(new Error(`Inscription timed out after ${timeoutMs}ms`)),\n timeoutMs\n );\n });\n\n return Promise.race([\n this.inscriberBuilder.inscribe(inscriptionData, options),\n timeoutPromise,\n ]);\n }\n\n return this.inscriberBuilder.inscribe(inscriptionData, options);\n }\n\n private formatInscriptionResult(\n result: Awaited<ReturnType<typeof this.inscriberBuilder.inscribe>>,\n options: InscriptionOptions\n ): string {\n const typed = result as InscriptionResponse;\n\n if (typed.confirmed && !typed.quote) {\n const ids = extractTopicIds(typed.inscription, typed.result);\n const network = (options.network || 'testnet') as 'mainnet' | 'testnet';\n const { topicId, cdnUrl } = buildInscriptionLinks(ids, network, '1');\n return `Successfully inscribed and confirmed content on the Hedera network!\\n\\nTransaction ID: ${\n (typed.result as InscriptionResult)?.transactionId ?? 'unknown'\n }\\nTopic ID: ${topicId || 'N/A'}${\n cdnUrl ? `\\nView inscription: ${cdnUrl}` : ''\n }\\n\\nThe inscription is now available.`;\n }\n\n if (!typed.quote && !typed.confirmed) {\n return `Successfully submitted inscription to the Hedera network!\\n\\nTransaction ID: ${\n (typed.result as InscriptionResult)?.transactionId ?? 'unknown'\n }\\n\\nThe inscription is processing and will be confirmed shortly.`;\n }\n\n return 'Inscription operation completed.';\n }\n}\n"],"names":[],"mappings":"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"}