@hashgraphonline/standards-agent-kit 0.2.110 → 0.2.113

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 (138) hide show
  1. package/dist/cjs/builders/hcs6/hcs6-builder.d.ts +47 -0
  2. package/dist/cjs/builders/hcs6/index.d.ts +1 -0
  3. package/dist/cjs/builders/index.d.ts +1 -0
  4. package/dist/cjs/index.d.ts +1 -1
  5. package/dist/cjs/standards-agent-kit.cjs +1 -1
  6. package/dist/cjs/standards-agent-kit.cjs.map +1 -1
  7. package/dist/cjs/tools/hcs6/CreateDynamicRegistryTool.d.ts +44 -0
  8. package/dist/cjs/tools/hcs6/QueryDynamicRegistryTool.d.ts +50 -0
  9. package/dist/cjs/tools/hcs6/RegisterDynamicHashinalTool.d.ts +102 -0
  10. package/dist/cjs/tools/hcs6/UpdateDynamicHashinalTool.d.ts +96 -0
  11. package/dist/cjs/tools/hcs6/base-hcs6-tools.d.ts +28 -0
  12. package/dist/cjs/tools/hcs6/hcs6-tool-params.d.ts +18 -0
  13. package/dist/cjs/tools/hcs6/index.d.ts +6 -0
  14. package/dist/cjs/tools/index.d.ts +1 -0
  15. package/dist/cjs/tools/inscriber/InscribeFromBufferTool.d.ts +4 -4
  16. package/dist/es/builders/hcs6/hcs6-builder.d.ts +47 -0
  17. package/dist/es/builders/hcs6/index.d.ts +1 -0
  18. package/dist/es/builders/index.d.ts +1 -0
  19. package/dist/es/index.d.ts +1 -1
  20. package/dist/es/standards-agent-kit.es.js +44 -31
  21. package/dist/es/standards-agent-kit.es.js.map +1 -1
  22. package/dist/es/standards-agent-kit.es10.js +27 -27
  23. package/dist/es/standards-agent-kit.es10.js.map +1 -1
  24. package/dist/es/standards-agent-kit.es11.js +20 -30
  25. package/dist/es/standards-agent-kit.es11.js.map +1 -1
  26. package/dist/es/standards-agent-kit.es12.js +27 -37
  27. package/dist/es/standards-agent-kit.es12.js.map +1 -1
  28. package/dist/es/standards-agent-kit.es13.js +48 -60
  29. package/dist/es/standards-agent-kit.es13.js.map +1 -1
  30. package/dist/es/standards-agent-kit.es14.js +60 -23
  31. package/dist/es/standards-agent-kit.es14.js.map +1 -1
  32. package/dist/es/standards-agent-kit.es15.js +23 -23
  33. package/dist/es/standards-agent-kit.es15.js.map +1 -1
  34. package/dist/es/standards-agent-kit.es16.js +23 -33
  35. package/dist/es/standards-agent-kit.es16.js.map +1 -1
  36. package/dist/es/standards-agent-kit.es17.js +34 -10
  37. package/dist/es/standards-agent-kit.es17.js.map +1 -1
  38. package/dist/es/standards-agent-kit.es18.js +16 -155
  39. package/dist/es/standards-agent-kit.es18.js.map +1 -1
  40. package/dist/es/standards-agent-kit.es19.js +150 -22
  41. package/dist/es/standards-agent-kit.es19.js.map +1 -1
  42. package/dist/es/standards-agent-kit.es20.js +25 -39
  43. package/dist/es/standards-agent-kit.es20.js.map +1 -1
  44. package/dist/es/standards-agent-kit.es21.js +26 -28
  45. package/dist/es/standards-agent-kit.es21.js.map +1 -1
  46. package/dist/es/standards-agent-kit.es22.js +16 -19
  47. package/dist/es/standards-agent-kit.es22.js.map +1 -1
  48. package/dist/es/standards-agent-kit.es23.js +21 -15
  49. package/dist/es/standards-agent-kit.es23.js.map +1 -1
  50. package/dist/es/standards-agent-kit.es24.js +18 -21
  51. package/dist/es/standards-agent-kit.es24.js.map +1 -1
  52. package/dist/es/standards-agent-kit.es25.js +35 -32
  53. package/dist/es/standards-agent-kit.es25.js.map +1 -1
  54. package/dist/es/standards-agent-kit.es26.js +38 -25
  55. package/dist/es/standards-agent-kit.es26.js.map +1 -1
  56. package/dist/es/standards-agent-kit.es27.js +25 -116
  57. package/dist/es/standards-agent-kit.es27.js.map +1 -1
  58. package/dist/es/standards-agent-kit.es28.js +33 -166
  59. package/dist/es/standards-agent-kit.es28.js.map +1 -1
  60. package/dist/es/standards-agent-kit.es29.js +42 -121
  61. package/dist/es/standards-agent-kit.es29.js.map +1 -1
  62. package/dist/es/standards-agent-kit.es30.js +40 -77
  63. package/dist/es/standards-agent-kit.es30.js.map +1 -1
  64. package/dist/es/standards-agent-kit.es31.js +42 -37
  65. package/dist/es/standards-agent-kit.es31.js.map +1 -1
  66. package/dist/es/standards-agent-kit.es32.js +20 -237
  67. package/dist/es/standards-agent-kit.es32.js.map +1 -1
  68. package/dist/es/standards-agent-kit.es33.js +154 -135
  69. package/dist/es/standards-agent-kit.es33.js.map +1 -1
  70. package/dist/es/standards-agent-kit.es34.js +168 -23
  71. package/dist/es/standards-agent-kit.es34.js.map +1 -1
  72. package/dist/es/standards-agent-kit.es35.js +126 -21
  73. package/dist/es/standards-agent-kit.es35.js.map +1 -1
  74. package/dist/es/standards-agent-kit.es36.js +86 -3
  75. package/dist/es/standards-agent-kit.es36.js.map +1 -1
  76. package/dist/es/standards-agent-kit.es37.js +45 -0
  77. package/dist/es/standards-agent-kit.es37.js.map +1 -0
  78. package/dist/es/standards-agent-kit.es38.js +249 -0
  79. package/dist/es/standards-agent-kit.es38.js.map +1 -0
  80. package/dist/es/standards-agent-kit.es39.js +141 -0
  81. package/dist/es/standards-agent-kit.es39.js.map +1 -0
  82. package/dist/es/standards-agent-kit.es4.js +65 -32
  83. package/dist/es/standards-agent-kit.es4.js.map +1 -1
  84. package/dist/es/standards-agent-kit.es40.js +33 -0
  85. package/dist/es/standards-agent-kit.es40.js.map +1 -0
  86. package/dist/es/standards-agent-kit.es41.js +28 -0
  87. package/dist/es/standards-agent-kit.es41.js.map +1 -0
  88. package/dist/es/standards-agent-kit.es42.js +7 -0
  89. package/dist/es/standards-agent-kit.es42.js.map +1 -0
  90. package/dist/es/standards-agent-kit.es5.js +35 -311
  91. package/dist/es/standards-agent-kit.es5.js.map +1 -1
  92. package/dist/es/standards-agent-kit.es6.js +320 -20
  93. package/dist/es/standards-agent-kit.es6.js.map +1 -1
  94. package/dist/es/standards-agent-kit.es7.js +19 -227
  95. package/dist/es/standards-agent-kit.es7.js.map +1 -1
  96. package/dist/es/standards-agent-kit.es8.js +216 -65
  97. package/dist/es/standards-agent-kit.es8.js.map +1 -1
  98. package/dist/es/standards-agent-kit.es9.js +72 -23
  99. package/dist/es/standards-agent-kit.es9.js.map +1 -1
  100. package/dist/es/tools/hcs6/CreateDynamicRegistryTool.d.ts +44 -0
  101. package/dist/es/tools/hcs6/QueryDynamicRegistryTool.d.ts +50 -0
  102. package/dist/es/tools/hcs6/RegisterDynamicHashinalTool.d.ts +102 -0
  103. package/dist/es/tools/hcs6/UpdateDynamicHashinalTool.d.ts +96 -0
  104. package/dist/es/tools/hcs6/base-hcs6-tools.d.ts +28 -0
  105. package/dist/es/tools/hcs6/hcs6-tool-params.d.ts +18 -0
  106. package/dist/es/tools/hcs6/index.d.ts +6 -0
  107. package/dist/es/tools/index.d.ts +1 -0
  108. package/dist/es/tools/inscriber/InscribeFromBufferTool.d.ts +4 -4
  109. package/dist/umd/builders/hcs6/hcs6-builder.d.ts +47 -0
  110. package/dist/umd/builders/hcs6/index.d.ts +1 -0
  111. package/dist/umd/builders/index.d.ts +1 -0
  112. package/dist/umd/index.d.ts +1 -1
  113. package/dist/umd/standards-agent-kit.umd.js +1 -1
  114. package/dist/umd/standards-agent-kit.umd.js.map +1 -1
  115. package/dist/umd/tools/hcs6/CreateDynamicRegistryTool.d.ts +44 -0
  116. package/dist/umd/tools/hcs6/QueryDynamicRegistryTool.d.ts +50 -0
  117. package/dist/umd/tools/hcs6/RegisterDynamicHashinalTool.d.ts +102 -0
  118. package/dist/umd/tools/hcs6/UpdateDynamicHashinalTool.d.ts +96 -0
  119. package/dist/umd/tools/hcs6/base-hcs6-tools.d.ts +28 -0
  120. package/dist/umd/tools/hcs6/hcs6-tool-params.d.ts +18 -0
  121. package/dist/umd/tools/hcs6/index.d.ts +6 -0
  122. package/dist/umd/tools/index.d.ts +1 -0
  123. package/dist/umd/tools/inscriber/InscribeFromBufferTool.d.ts +4 -4
  124. package/package.json +2 -2
  125. package/src/builders/hcs6/hcs6-builder.ts +136 -0
  126. package/src/builders/hcs6/index.ts +1 -0
  127. package/src/builders/index.ts +1 -0
  128. package/src/index.ts +1 -1
  129. package/src/tools/hcs6/CreateDynamicRegistryTool.ts +66 -0
  130. package/src/tools/hcs6/QueryDynamicRegistryTool.ts +72 -0
  131. package/src/tools/hcs6/RegisterDynamicHashinalTool.ts +79 -0
  132. package/src/tools/hcs6/UpdateDynamicHashinalTool.ts +74 -0
  133. package/src/tools/hcs6/base-hcs6-tools.ts +63 -0
  134. package/src/tools/hcs6/hcs6-tool-params.ts +21 -0
  135. package/src/tools/hcs6/index.ts +6 -0
  136. package/src/tools/index.ts +1 -0
  137. package/src/tools/inscriber/InscribeFromBufferTool.ts +1 -1
  138. package/src/tools/inscriber/InscribeFromUrlTool.ts +60 -7
@@ -1,32 +1,45 @@
1
- import { BaseHederaTransactionTool, BaseHederaQueryTool } from "hedera-agent-kit";
2
- class BaseInscriberTransactionTool extends BaseHederaTransactionTool {
3
- constructor(params) {
4
- super(params);
5
- this.namespace = "inscriber";
6
- this.inscriberBuilder = params.inscriberBuilder;
1
+ import { z } from "zod";
2
+ import { BaseHCS2QueryTool } from "./standards-agent-kit.es20.js";
3
+ const queryRegistrySchema = z.object({
4
+ topicId: z.string().regex(/^\d+\.\d+\.\d+$/).describe("The HCS-2 registry topic ID to query"),
5
+ limit: z.number().int().positive().optional().describe("Maximum number of entries to return"),
6
+ order: z.enum(["asc", "desc"]).optional().describe("Order of results (ascending or descending)"),
7
+ skip: z.number().int().min(0).optional().describe("Number of entries to skip")
8
+ });
9
+ class QueryRegistryTool extends BaseHCS2QueryTool {
10
+ constructor() {
11
+ super(...arguments);
12
+ this.name = "queryHCS2Registry";
13
+ this.description = "Query entries from an HCS-2 registry";
7
14
  }
8
- /**
9
- * Override to return the InscriberBuilder
10
- */
11
- getServiceBuilder() {
12
- return this.inscriberBuilder;
15
+ get specificInputSchema() {
16
+ return queryRegistrySchema;
13
17
  }
14
- }
15
- class BaseInscriberQueryTool extends BaseHederaQueryTool {
16
- constructor(params) {
17
- super(params);
18
- this.namespace = "inscriber";
19
- this.inscriberBuilder = params.inscriberBuilder;
20
- }
21
- /**
22
- * Override to return the InscriberBuilder
23
- */
24
- getServiceBuilder() {
25
- return this.inscriberBuilder;
18
+ async executeQuery(params, _runManager) {
19
+ const registry = await this.hcs2Builder.getRegistry(params.topicId, {
20
+ limit: params.limit,
21
+ order: params.order,
22
+ skip: params.skip
23
+ });
24
+ return {
25
+ topicId: registry.topicId,
26
+ registryType: registry.registryType === 0 ? "indexed" : "non-indexed",
27
+ ttl: registry.ttl,
28
+ totalEntries: registry.entries.length,
29
+ entries: registry.entries.map((entry) => ({
30
+ sequence: entry.sequence,
31
+ timestamp: entry.timestamp,
32
+ payer: entry.payer,
33
+ operation: entry.message.op,
34
+ targetTopicId: entry.message.t_id,
35
+ uid: entry.message.uid,
36
+ metadata: entry.message.metadata,
37
+ memo: entry.message.m
38
+ }))
39
+ };
26
40
  }
27
41
  }
28
42
  export {
29
- BaseInscriberQueryTool,
30
- BaseInscriberTransactionTool
43
+ QueryRegistryTool
31
44
  };
32
45
  //# sourceMappingURL=standards-agent-kit.es26.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"standards-agent-kit.es26.js","sources":["../../src/tools/inscriber/base-inscriber-tools.ts"],"sourcesContent":["import {\n BaseHederaTransactionTool,\n BaseHederaQueryTool,\n BaseServiceBuilder,\n} from 'hedera-agent-kit';\nimport { InscriberBuilder } from '../../builders/inscriber/inscriber-builder';\nimport {\n InscriberTransactionToolParams,\n InscriberQueryToolParams,\n} from './inscriber-tool-params';\nimport { z } from 'zod';\n\n/**\n * Base class for Inscriber transaction tools\n */\nexport abstract class BaseInscriberTransactionTool<\n T extends z.ZodObject<\n z.ZodRawShape,\n z.UnknownKeysParam,\n z.ZodTypeAny\n > = z.ZodObject<z.ZodRawShape>\n> extends BaseHederaTransactionTool<T> {\n protected inscriberBuilder: InscriberBuilder;\n namespace = 'inscriber' as const;\n\n constructor(params: InscriberTransactionToolParams) {\n super(params);\n this.inscriberBuilder = params.inscriberBuilder;\n }\n\n /**\n * Override to return the InscriberBuilder\n */\n protected getServiceBuilder(): BaseServiceBuilder {\n return this.inscriberBuilder;\n }\n}\n\n/**\n * Base class for Inscriber query tools\n */\nexport abstract class BaseInscriberQueryTool<\n T extends z.ZodObject<\n z.ZodRawShape,\n z.UnknownKeysParam,\n z.ZodTypeAny\n > = z.ZodObject<z.ZodRawShape>\n> extends BaseHederaQueryTool<T> {\n protected inscriberBuilder: InscriberBuilder;\n namespace = 'inscriber' as const;\n\n constructor(params: InscriberQueryToolParams) {\n super(params);\n this.inscriberBuilder = params.inscriberBuilder;\n }\n\n /**\n * Override to return the InscriberBuilder\n */\n protected getServiceBuilder(): BaseServiceBuilder {\n return this.inscriberBuilder;\n }\n}"],"names":[],"mappings":";AAeO,MAAe,qCAMZ,0BAA6B;AAAA,EAIrC,YAAY,QAAwC;AAClD,UAAM,MAAM;AAHd,SAAA,YAAY;AAIV,SAAK,mBAAmB,OAAO;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKU,oBAAwC;AAChD,WAAO,KAAK;AAAA,EACd;AACF;AAKO,MAAe,+BAMZ,oBAAuB;AAAA,EAI/B,YAAY,QAAkC;AAC5C,UAAM,MAAM;AAHd,SAAA,YAAY;AAIV,SAAK,mBAAmB,OAAO;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKU,oBAAwC;AAChD,WAAO,KAAK;AAAA,EACd;AACF;"}
1
+ {"version":3,"file":"standards-agent-kit.es26.js","sources":["../../src/tools/hcs2/QueryRegistryTool.ts"],"sourcesContent":["import { z } from 'zod';\nimport { BaseHCS2QueryTool } from './base-hcs2-tools';\nimport { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';\n\n/**\n * Schema for querying HCS-2 registry\n */\nconst queryRegistrySchema = z.object({\n topicId: z\n .string()\n .regex(/^\\d+\\.\\d+\\.\\d+$/)\n .describe('The HCS-2 registry topic ID to query'),\n limit: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Maximum number of entries to return'),\n order: z\n .enum(['asc', 'desc'])\n .optional()\n .describe('Order of results (ascending or descending)'),\n skip: z\n .number()\n .int()\n .min(0)\n .optional()\n .describe('Number of entries to skip'),\n});\n\n\n/**\n * Tool for querying HCS-2 registries\n */\nexport class QueryRegistryTool extends BaseHCS2QueryTool<typeof queryRegistrySchema> {\n name = 'queryHCS2Registry';\n description = 'Query entries from an HCS-2 registry';\n\n get specificInputSchema() {\n return queryRegistrySchema;\n }\n\n protected async executeQuery(\n params: z.infer<typeof queryRegistrySchema>,\n _runManager?: CallbackManagerForToolRun\n ): Promise<unknown> {\n const registry = await this.hcs2Builder.getRegistry(params.topicId, {\n limit: params.limit,\n order: params.order,\n skip: params.skip,\n });\n\n return {\n topicId: registry.topicId,\n registryType: registry.registryType === 0 ? 'indexed' : 'non-indexed',\n ttl: registry.ttl,\n totalEntries: registry.entries.length,\n entries: registry.entries.map(entry => ({\n sequence: entry.sequence,\n timestamp: entry.timestamp,\n payer: entry.payer,\n operation: entry.message.op,\n targetTopicId: entry.message.t_id,\n uid: entry.message.uid,\n metadata: entry.message.metadata,\n memo: entry.message.m,\n })),\n };\n }\n}"],"names":[],"mappings":";;AAOA,MAAM,sBAAsB,EAAE,OAAO;AAAA,EACnC,SAAS,EACN,OAAA,EACA,MAAM,iBAAiB,EACvB,SAAS,sCAAsC;AAAA,EAClD,OAAO,EACJ,OAAA,EACA,IAAA,EACA,SAAA,EACA,SAAA,EACA,SAAS,qCAAqC;AAAA,EACjD,OAAO,EACJ,KAAK,CAAC,OAAO,MAAM,CAAC,EACpB,SAAA,EACA,SAAS,4CAA4C;AAAA,EACxD,MAAM,EACH,OAAA,EACA,IAAA,EACA,IAAI,CAAC,EACL,WACA,SAAS,2BAA2B;AACzC,CAAC;AAMM,MAAM,0BAA0B,kBAA8C;AAAA,EAA9E,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,aACkB;AAClB,UAAM,WAAW,MAAM,KAAK,YAAY,YAAY,OAAO,SAAS;AAAA,MAClE,OAAO,OAAO;AAAA,MACd,OAAO,OAAO;AAAA,MACd,MAAM,OAAO;AAAA,IAAA,CACd;AAED,WAAO;AAAA,MACL,SAAS,SAAS;AAAA,MAClB,cAAc,SAAS,iBAAiB,IAAI,YAAY;AAAA,MACxD,KAAK,SAAS;AAAA,MACd,cAAc,SAAS,QAAQ;AAAA,MAC/B,SAAS,SAAS,QAAQ,IAAI,CAAA,WAAU;AAAA,QACtC,UAAU,MAAM;AAAA,QAChB,WAAW,MAAM;AAAA,QACjB,OAAO,MAAM;AAAA,QACb,WAAW,MAAM,QAAQ;AAAA,QACzB,eAAe,MAAM,QAAQ;AAAA,QAC7B,KAAK,MAAM,QAAQ;AAAA,QACnB,UAAU,MAAM,QAAQ;AAAA,QACxB,MAAM,MAAM,QAAQ;AAAA,MAAA,EACpB;AAAA,IAAA;AAAA,EAEN;AACF;"}
@@ -1,123 +1,32 @@
1
- import { z } from "zod";
2
- import { BaseInscriberQueryTool } from "./standards-agent-kit.es26.js";
3
- const inscribeFromUrlSchema = z.object({
4
- url: z.string().url().describe("The URL of the content to inscribe"),
5
- mode: z.enum(["file", "hashinal"]).optional().describe("Inscription mode: file or hashinal NFT"),
6
- metadata: z.record(z.unknown()).optional().describe("Metadata to attach to the inscription"),
7
- tags: z.array(z.string()).optional().describe("Tags to categorize the inscription"),
8
- chunkSize: z.number().int().positive().optional().describe("Chunk size for large files"),
9
- waitForConfirmation: z.boolean().optional().describe("Whether to wait for inscription confirmation"),
10
- apiKey: z.string().optional().describe("API key for inscription service")
11
- });
12
- class InscribeFromUrlTool extends BaseInscriberQueryTool {
13
- constructor() {
14
- super(...arguments);
15
- this.name = "inscribeFromUrl";
16
- this.description = "Inscribe content from a URL to the Hedera network. IMPORTANT: Only use this tool when you have a valid URL pointing to actual content. The URL must be accessible and return meaningful data. The tool will validate that the content exists and is not empty before inscription.";
1
+ import { BaseHederaTransactionTool, BaseHederaQueryTool } from "hedera-agent-kit";
2
+ class BaseHCS6TransactionTool extends BaseHederaTransactionTool {
3
+ constructor(params) {
4
+ super(params);
5
+ this.namespace = "hcs6";
6
+ this.hcs6Builder = params.hcs6Builder;
17
7
  }
18
- get specificInputSchema() {
19
- return inscribeFromUrlSchema;
8
+ /**
9
+ * Override to return the HCS6Builder
10
+ */
11
+ getServiceBuilder() {
12
+ return this.hcs6Builder;
20
13
  }
21
- async executeQuery(params, _runManager) {
22
- console.log(`[DEBUG] InscribeFromUrlTool.executeQuery called with URL: ${params.url}`);
23
- if (!params.url || params.url.trim() === "") {
24
- throw new Error("URL cannot be empty. Please provide a valid URL.");
25
- }
26
- try {
27
- const urlObj = new URL(params.url);
28
- if (!urlObj.protocol || !urlObj.host) {
29
- throw new Error("Invalid URL format. Please provide a complete URL with protocol (http/https).");
30
- }
31
- if (!["http:", "https:"].includes(urlObj.protocol)) {
32
- throw new Error("Only HTTP and HTTPS URLs are supported for inscription.");
33
- }
34
- } catch (error) {
35
- throw new Error(`Invalid URL: ${params.url}. Please provide a valid URL.`);
36
- }
37
- console.log(`[InscribeFromUrlTool] Validating URL content before inscription...`);
38
- try {
39
- const controller = new AbortController();
40
- const timeoutId = setTimeout(() => controller.abort(), 1e4);
41
- try {
42
- const response = await fetch(params.url, {
43
- method: "HEAD",
44
- signal: controller.signal
45
- });
46
- clearTimeout(timeoutId);
47
- if (!response.ok) {
48
- throw new Error(`URL returned error status ${response.status}: ${response.statusText}. Cannot inscribe content from inaccessible URLs.`);
49
- }
50
- const contentLength = response.headers.get("content-length");
51
- if (contentLength && parseInt(contentLength) === 0) {
52
- throw new Error("URL returns empty content (Content-Length: 0). Cannot inscribe empty content.");
53
- }
54
- if (contentLength && parseInt(contentLength) < 10) {
55
- throw new Error(`URL content is too small (${contentLength} bytes). Content must be at least 10 bytes.`);
56
- }
57
- const contentType = response.headers.get("content-type");
58
- console.log(`[InscribeFromUrlTool] URL validation passed. Content-Type: ${contentType}, Content-Length: ${contentLength || "unknown"}`);
59
- } catch (fetchError) {
60
- clearTimeout(timeoutId);
61
- throw fetchError;
62
- }
63
- } catch (error) {
64
- if (error instanceof Error) {
65
- if (error.name === "AbortError") {
66
- console.log(`[InscribeFromUrlTool] Warning: URL validation timed out after 10 seconds. Proceeding with inscription attempt.`);
67
- } else if (error.message.includes("URL returned error") || error.message.includes("empty content") || error.message.includes("too small")) {
68
- throw error;
69
- } else {
70
- console.log(`[InscribeFromUrlTool] Warning: Could not validate URL with HEAD request: ${error.message}. Proceeding with inscription attempt.`);
71
- }
72
- }
73
- }
74
- const options = {
75
- mode: params.mode,
76
- metadata: params.metadata,
77
- tags: params.tags,
78
- chunkSize: params.chunkSize,
79
- waitForConfirmation: params.waitForConfirmation ?? true,
80
- waitMaxAttempts: 10,
81
- waitIntervalMs: 3e3,
82
- apiKey: params.apiKey,
83
- network: this.inscriberBuilder["hederaKit"].client.network.toString().includes("mainnet") ? "mainnet" : "testnet"
84
- };
85
- try {
86
- const timeoutPromise = new Promise((_, reject) => {
87
- setTimeout(() => reject(new Error("Inscription timed out after 30 seconds")), 3e4);
88
- });
89
- const result = await Promise.race([
90
- this.inscriberBuilder.inscribe(
91
- { type: "url", url: params.url },
92
- options
93
- ),
94
- timeoutPromise
95
- ]);
96
- if (result.confirmed) {
97
- const topicId = result.inscription?.topic_id || result.result.topicId;
98
- const network = options.network || "testnet";
99
- const cdnUrl = topicId ? `https://kiloscribe.com/api/inscription-cdn/${topicId}?network=${network}` : null;
100
- return `Successfully inscribed and confirmed content on the Hedera network!
101
-
102
- Transaction ID: ${result.result.transactionId}
103
- Topic ID: ${topicId || "N/A"}${cdnUrl ? `
104
- View inscription: ${cdnUrl}` : ""}
105
-
106
- The inscription is now available.`;
107
- } else {
108
- return `Successfully submitted inscription to the Hedera network!
109
-
110
- Transaction ID: ${result.result.transactionId}
111
-
112
- The inscription is processing and will be confirmed shortly.`;
113
- }
114
- } catch (error) {
115
- const errorMessage = error instanceof Error ? error.message : "Failed to inscribe from URL";
116
- throw new Error(`Inscription failed: ${errorMessage}`);
117
- }
14
+ }
15
+ class BaseHCS6QueryTool extends BaseHederaQueryTool {
16
+ constructor(params) {
17
+ super(params);
18
+ this.namespace = "hcs6";
19
+ this.hcs6Builder = params.hcs6Builder;
20
+ }
21
+ /**
22
+ * Override to return the HCS6Builder
23
+ */
24
+ getServiceBuilder() {
25
+ return this.hcs6Builder;
118
26
  }
119
27
  }
120
28
  export {
121
- InscribeFromUrlTool
29
+ BaseHCS6QueryTool,
30
+ BaseHCS6TransactionTool
122
31
  };
123
32
  //# sourceMappingURL=standards-agent-kit.es27.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"standards-agent-kit.es27.js","sources":["../../src/tools/inscriber/InscribeFromUrlTool.ts"],"sourcesContent":["import { z } from 'zod';\nimport { BaseInscriberQueryTool } from './base-inscriber-tools';\nimport { InscriptionOptions } from '@hashgraphonline/standards-sdk';\nimport { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';\n\n/**\n * Schema for inscribing from URL\n */\nconst inscribeFromUrlSchema = z.object({\n url: z.string().url().describe('The URL of the content to inscribe'),\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 apiKey: z\n .string()\n .optional()\n .describe('API key for inscription service'),\n});\n\n\n/**\n * Tool for inscribing content from URL\n */\nexport class InscribeFromUrlTool extends BaseInscriberQueryTool<typeof inscribeFromUrlSchema> {\n name = 'inscribeFromUrl';\n description = 'Inscribe content from a URL to the Hedera network. IMPORTANT: Only use this tool when you have a valid URL pointing to actual content. The URL must be accessible and return meaningful data. The tool will validate that the content exists and is not empty before inscription.';\n\n get specificInputSchema() {\n return inscribeFromUrlSchema;\n }\n\n protected async executeQuery(\n params: z.infer<typeof inscribeFromUrlSchema>,\n _runManager?: CallbackManagerForToolRun\n ): Promise<unknown> {\n console.log(`[DEBUG] InscribeFromUrlTool.executeQuery called with URL: ${params.url}`);\n \n if (!params.url || params.url.trim() === '') {\n throw new Error('URL cannot be empty. Please provide a valid URL.');\n }\n\n try {\n const urlObj = new URL(params.url);\n if (!urlObj.protocol || !urlObj.host) {\n throw new Error('Invalid URL format. Please provide a complete URL with protocol (http/https).');\n }\n if (!['http:', 'https:'].includes(urlObj.protocol)) {\n throw new Error('Only HTTP and HTTPS URLs are supported for inscription.');\n }\n } catch (error) {\n throw new Error(`Invalid URL: ${params.url}. Please provide a valid URL.`);\n }\n\n console.log(`[InscribeFromUrlTool] Validating URL content before inscription...`);\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 10000);\n \n try {\n const response = await fetch(params.url, {\n method: 'HEAD',\n signal: controller.signal,\n });\n \n clearTimeout(timeoutId);\n \n if (!response.ok) {\n throw new Error(`URL returned error status ${response.status}: ${response.statusText}. Cannot inscribe content from inaccessible URLs.`);\n }\n\n const contentLength = response.headers.get('content-length');\n if (contentLength && parseInt(contentLength) === 0) {\n throw new Error('URL returns empty content (Content-Length: 0). Cannot inscribe empty content.');\n }\n\n if (contentLength && parseInt(contentLength) < 10) {\n throw new Error(`URL content is too small (${contentLength} bytes). Content must be at least 10 bytes.`);\n }\n\n const contentType = response.headers.get('content-type');\n console.log(`[InscribeFromUrlTool] URL validation passed. Content-Type: ${contentType}, Content-Length: ${contentLength || 'unknown'}`);\n } catch (fetchError) {\n clearTimeout(timeoutId);\n throw fetchError;\n }\n } catch (error) {\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n console.log(`[InscribeFromUrlTool] Warning: URL validation timed out after 10 seconds. Proceeding with inscription attempt.`);\n } else if (error.message.includes('URL returned error') || error.message.includes('empty content') || error.message.includes('too small')) {\n throw error;\n } else {\n console.log(`[InscribeFromUrlTool] Warning: Could not validate URL with HEAD request: ${error.message}. Proceeding with inscription attempt.`);\n }\n }\n }\n\n const options: InscriptionOptions = {\n mode: params.mode,\n metadata: params.metadata,\n tags: params.tags,\n chunkSize: params.chunkSize,\n waitForConfirmation: params.waitForConfirmation ?? true,\n waitMaxAttempts: 10,\n waitIntervalMs: 3000,\n apiKey: params.apiKey,\n network: this.inscriberBuilder['hederaKit'].client.network.toString().includes('mainnet') ? 'mainnet' : 'testnet',\n };\n\n try {\n const timeoutPromise = new Promise((_, reject) => {\n setTimeout(() => reject(new Error('Inscription timed out after 30 seconds')), 30000);\n });\n\n const result = await Promise.race([\n this.inscriberBuilder.inscribe(\n { type: 'url', url: params.url },\n options\n ),\n timeoutPromise\n ]) as any;\n\n if (result.confirmed) {\n const topicId = result.inscription?.topic_id || result.result.topicId;\n const network = options.network || 'testnet';\n const cdnUrl = topicId ? `https://kiloscribe.com/api/inscription-cdn/${topicId}?network=${network}` : null;\n return `Successfully inscribed and confirmed content on the Hedera network!\\n\\nTransaction ID: ${result.result.transactionId}\\nTopic ID: ${topicId || 'N/A'}${cdnUrl ? `\\nView inscription: ${cdnUrl}` : ''}\\n\\nThe inscription is now available.`;\n } else {\n return `Successfully submitted inscription to the Hedera network!\\n\\nTransaction ID: ${result.result.transactionId}\\n\\nThe inscription is processing and will be confirmed shortly.`;\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Failed to inscribe from URL';\n throw new Error(`Inscription failed: ${errorMessage}`);\n }\n }\n}"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"standards-agent-kit.es27.js","sources":["../../src/tools/hcs6/base-hcs6-tools.ts"],"sourcesContent":["import {\n BaseHederaTransactionTool,\n BaseHederaQueryTool,\n BaseServiceBuilder,\n} from 'hedera-agent-kit';\nimport { HCS6Builder } from '../../builders/hcs6/hcs6-builder';\nimport {\n HCS6TransactionToolParams,\n HCS6QueryToolParams,\n} from './hcs6-tool-params';\nimport { z } from 'zod';\n\n/**\n * Base class for HCS6 transaction tools\n */\nexport abstract class BaseHCS6TransactionTool<\n T extends z.ZodObject<\n z.ZodRawShape,\n z.UnknownKeysParam,\n z.ZodTypeAny\n > = z.ZodObject<z.ZodRawShape>\n> extends BaseHederaTransactionTool<T> {\n protected hcs6Builder: HCS6Builder;\n namespace = 'hcs6' as const;\n\n constructor(params: HCS6TransactionToolParams) {\n super(params);\n this.hcs6Builder = params.hcs6Builder;\n }\n\n /**\n * Override to return the HCS6Builder\n */\n protected getServiceBuilder(): BaseServiceBuilder {\n return this.hcs6Builder;\n }\n}\n\n/**\n * Base class for HCS6 query tools\n */\nexport abstract class BaseHCS6QueryTool<\n T extends z.ZodObject<\n z.ZodRawShape,\n z.UnknownKeysParam,\n z.ZodTypeAny\n > = z.ZodObject<z.ZodRawShape>\n> extends BaseHederaQueryTool<T> {\n protected hcs6Builder: HCS6Builder;\n namespace = 'hcs6' as const;\n\n constructor(params: HCS6QueryToolParams) {\n super(params);\n this.hcs6Builder = params.hcs6Builder;\n }\n\n /**\n * Override to return the HCS6Builder\n */\n protected getServiceBuilder(): BaseServiceBuilder {\n return this.hcs6Builder;\n }\n}"],"names":[],"mappings":";AAeO,MAAe,gCAMZ,0BAA6B;AAAA,EAIrC,YAAY,QAAmC;AAC7C,UAAM,MAAM;AAHd,SAAA,YAAY;AAIV,SAAK,cAAc,OAAO;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKU,oBAAwC;AAChD,WAAO,KAAK;AAAA,EACd;AACF;AAKO,MAAe,0BAMZ,oBAAuB;AAAA,EAI/B,YAAY,QAA6B;AACvC,UAAM,MAAM;AAHd,SAAA,YAAY;AAIV,SAAK,cAAc,OAAO;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKU,oBAAwC;AAChD,WAAO,KAAK;AAAA,EACd;AACF;"}
@@ -1,178 +1,45 @@
1
1
  import { z } from "zod";
2
- import { BaseInscriberQueryTool } from "./standards-agent-kit.es26.js";
3
- import * as fs from "fs/promises";
4
- import * as path from "path";
5
- const inscribeFromFileSchema = z.object({
6
- filePath: z.string().min(1, "File path cannot be empty").describe("The file path of the content to inscribe. Must point to a valid, non-empty file."),
7
- mode: z.enum(["file", "hashinal"]).optional().describe("Inscription mode: file or hashinal NFT"),
8
- metadata: z.record(z.unknown()).optional().describe("Metadata to attach to the inscription"),
9
- tags: z.array(z.string()).optional().describe("Tags to categorize the inscription"),
10
- chunkSize: z.number().int().positive().optional().describe("Chunk size for large files"),
11
- waitForConfirmation: z.boolean().optional().describe("Whether to wait for inscription confirmation"),
12
- timeoutMs: z.number().int().positive().optional().describe("Timeout in milliseconds for inscription (default: no timeout)"),
13
- apiKey: z.string().optional().describe("API key for inscription service")
2
+ import { BaseHCS6TransactionTool } from "./standards-agent-kit.es27.js";
3
+ const CreateDynamicRegistrySchema = z.object({
4
+ ttl: z.number().min(3600).default(86400).describe("Time-to-live in seconds (minimum 3600 seconds/1 hour)"),
5
+ adminKey: z.union([z.boolean(), z.string()]).optional().describe("Admin key for the registry topic. Can be boolean (use operator key) or a public key string"),
6
+ submitKey: z.union([z.boolean(), z.string()]).optional().describe("Submit key for the registry topic. Can be boolean (use operator key) or a public key string")
14
7
  });
15
- class InscribeFromFileTool extends BaseInscriberQueryTool {
16
- constructor() {
17
- super(...arguments);
18
- this.name = "inscribeFromFile";
19
- this.description = "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.";
8
+ class CreateDynamicRegistryTool extends BaseHCS6TransactionTool {
9
+ constructor(params) {
10
+ super(params);
11
+ this.name = "createDynamicRegistry";
12
+ this.description = "Create a new HCS-6 dynamic registry for managing evolving content";
13
+ this.schema = CreateDynamicRegistrySchema;
20
14
  }
21
- get specificInputSchema() {
22
- return inscribeFromFileSchema;
23
- }
24
- async executeQuery(params, _runManager) {
25
- console.log(`[DEBUG] InscribeFromFileTool.executeQuery called with: ${params.filePath}`);
26
- let fileContent;
15
+ async _call(params) {
27
16
  try {
28
- console.log(`[DEBUG] Checking file: ${params.filePath}`);
29
- console.log(`[DEBUG] Current working directory: ${process.cwd()}`);
30
- const stats = await fs.stat(params.filePath);
31
- if (!stats.isFile()) {
32
- throw new Error(`Path "${params.filePath}" is not a file`);
33
- }
34
- console.log(`[DEBUG] File size: ${stats.size} bytes`);
35
- if (stats.size === 0) {
36
- throw new Error(
37
- `File "${params.filePath}" is empty (0 bytes). Cannot inscribe empty files.`
38
- );
39
- }
40
- if (stats.size < 10) {
41
- throw new Error(
42
- `File "${params.filePath}" is too small (${stats.size} bytes). Files must contain at least 10 bytes of meaningful content.`
43
- );
44
- }
45
- if (stats.size > 100 * 1024 * 1024) {
46
- console.log(`[InscribeFromFileTool] WARNING: Large file detected (${(stats.size / (1024 * 1024)).toFixed(2)} MB)`);
47
- }
48
- this.logger?.info("Reading file content...");
49
- fileContent = await fs.readFile(params.filePath);
50
- this.logger?.info(`Read ${fileContent.length} bytes from file`);
51
- if (!fileContent || fileContent.length === 0) {
52
- throw new Error(
53
- `File "${params.filePath}" has no content after reading. Cannot inscribe empty files.`
54
- );
55
- }
56
- if (fileContent.length < 10) {
57
- throw new Error(
58
- `File "${params.filePath}" content is too small (${fileContent.length} bytes). Files must contain at least 10 bytes of meaningful content.`
59
- );
60
- }
61
- const fileName2 = path.basename(params.filePath);
62
- const mimeType2 = this.getMimeType(fileName2);
63
- if (mimeType2.startsWith("text/") || mimeType2 === "application/json") {
64
- const textContent = fileContent.toString("utf8", 0, Math.min(fileContent.length, 1e3));
65
- if (textContent.trim() === "") {
66
- throw new Error(
67
- `File "${params.filePath}" contains only whitespace or empty content. Cannot inscribe meaningless data.`
68
- );
69
- }
70
- }
71
- } catch (error) {
72
- if (error instanceof Error) {
73
- if (error.message.includes("ENOENT")) {
74
- throw new Error(`File not found: "${params.filePath}"`);
17
+ const result = await this.hcs6Builder.createRegistry({
18
+ ttl: params.ttl,
19
+ adminKey: params.adminKey,
20
+ submitKey: params.submitKey
21
+ });
22
+ if (!result.success) {
23
+ throw new Error(result.error || "Failed to create dynamic registry");
24
+ }
25
+ return {
26
+ status: "success",
27
+ data: {
28
+ topicId: result.topicId,
29
+ transactionId: result.transactionId,
30
+ ttl: params.ttl,
31
+ memo: `hcs-6:1:${params.ttl}`
75
32
  }
76
- throw error;
77
- }
78
- throw new Error(`Failed to read file: ${error}`);
79
- }
80
- const base64Data = fileContent.toString("base64");
81
- this.logger?.info(`Converted to base64: ${base64Data.length} characters`);
82
- const fileName = path.basename(params.filePath);
83
- const mimeType = this.getMimeType(fileName);
84
- this.logger?.info(`File: ${fileName}, MIME type: ${mimeType}`);
85
- const options = {
86
- mode: params.mode,
87
- metadata: params.metadata,
88
- tags: params.tags,
89
- chunkSize: params.chunkSize,
90
- waitForConfirmation: params.waitForConfirmation ?? true,
91
- waitMaxAttempts: 10,
92
- waitIntervalMs: 3e3,
93
- apiKey: params.apiKey,
94
- network: this.inscriberBuilder["hederaKit"].client.network.toString().includes("mainnet") ? "mainnet" : "testnet"
95
- };
96
- try {
97
- let result;
98
- if (params.timeoutMs) {
99
- const timeoutPromise = new Promise((_, reject) => {
100
- setTimeout(
101
- () => reject(new Error(`Inscription timed out after ${params.timeoutMs}ms`)),
102
- params.timeoutMs
103
- );
104
- });
105
- result = await Promise.race([
106
- this.inscriberBuilder.inscribe(
107
- {
108
- type: "buffer",
109
- buffer: Buffer.from(base64Data, "base64"),
110
- fileName,
111
- mimeType
112
- },
113
- options
114
- ),
115
- timeoutPromise
116
- ]);
117
- } else {
118
- result = await this.inscriberBuilder.inscribe(
119
- {
120
- type: "buffer",
121
- buffer: Buffer.from(base64Data, "base64"),
122
- fileName,
123
- mimeType
124
- },
125
- options
126
- );
127
- }
128
- if (result.confirmed) {
129
- const topicId = result.inscription?.topic_id || result.result.topicId;
130
- const network = options.network || "testnet";
131
- const cdnUrl = topicId ? `https://kiloscribe.com/api/inscription-cdn/${topicId}?network=${network}` : null;
132
- return `Successfully inscribed and confirmed content on the Hedera network!
133
-
134
- Transaction ID: ${result.result.transactionId}
135
- Topic ID: ${topicId || "N/A"}${cdnUrl ? `
136
- View inscription: ${cdnUrl}` : ""}
137
-
138
- The inscription is now available.`;
139
- } else {
140
- return `Successfully submitted inscription to the Hedera network!
141
-
142
- Transaction ID: ${result.result.transactionId}
143
-
144
- The inscription is processing and will be confirmed shortly.`;
145
- }
33
+ };
146
34
  } catch (error) {
147
- const errorMessage = error instanceof Error ? error.message : "Failed to inscribe from file";
148
- throw new Error(`Inscription failed: ${errorMessage}`);
35
+ return {
36
+ status: "error",
37
+ message: error instanceof Error ? error.message : "Unknown error"
38
+ };
149
39
  }
150
40
  }
151
- getMimeType(fileName) {
152
- const ext = path.extname(fileName).toLowerCase();
153
- const mimeTypes = {
154
- ".png": "image/png",
155
- ".jpg": "image/jpeg",
156
- ".jpeg": "image/jpeg",
157
- ".gif": "image/gif",
158
- ".webp": "image/webp",
159
- ".svg": "image/svg+xml",
160
- ".pdf": "application/pdf",
161
- ".json": "application/json",
162
- ".txt": "text/plain",
163
- ".html": "text/html",
164
- ".css": "text/css",
165
- ".js": "application/javascript",
166
- ".ts": "application/typescript",
167
- ".mp4": "video/mp4",
168
- ".mp3": "audio/mpeg",
169
- ".wav": "audio/wav",
170
- ".zip": "application/zip"
171
- };
172
- return mimeTypes[ext] || "application/octet-stream";
173
- }
174
41
  }
175
42
  export {
176
- InscribeFromFileTool
43
+ CreateDynamicRegistryTool
177
44
  };
178
45
  //# sourceMappingURL=standards-agent-kit.es28.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"standards-agent-kit.es28.js","sources":["../../src/tools/inscriber/InscribeFromFileTool.ts"],"sourcesContent":["import { z } from 'zod';\nimport { BaseInscriberQueryTool } from './base-inscriber-tools';\nimport { InscriptionOptions } from '@hashgraphonline/standards-sdk';\nimport { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\n\n/**\n * Schema for inscribing from file\n */\nconst inscribeFromFileSchema = z.object({\n filePath: z.string().min(1, 'File path cannot be empty').describe('The file path of the content to inscribe. Must point to a valid, non-empty file.'),\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});\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.';\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 console.log(`[DEBUG] InscribeFromFileTool.executeQuery called with: ${params.filePath}`);\n \n // File validation\n let fileContent: Buffer;\n try {\n console.log(`[DEBUG] Checking file: ${params.filePath}`);\n console.log(`[DEBUG] Current working directory: ${process.cwd()}`);\n\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 console.log(`[DEBUG] File size: ${stats.size} bytes`);\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 console.log(`[InscribeFromFileTool] WARNING: Large file detected (${(stats.size / (1024 * 1024)).toFixed(2)} MB)`);\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('utf8', 0, Math.min(fileContent.length, 1000));\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.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 };\n\n try {\n let result: any;\n \n if (params.timeoutMs) {\n const timeoutPromise = new Promise((_, reject) => {\n setTimeout(\n () => reject(new Error(`Inscription timed out after ${params.timeoutMs}ms`)),\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 if (result.confirmed) {\n const topicId = result.inscription?.topic_id || result.result.topicId;\n const network = options.network || 'testnet';\n const cdnUrl = topicId\n ? `https://kiloscribe.com/api/inscription-cdn/${topicId}?network=${network}`\n : null;\n return `Successfully inscribed and confirmed content on the Hedera network!\\n\\nTransaction ID: ${\n result.result.transactionId\n }\\nTopic ID: ${topicId || 'N/A'}${\n cdnUrl ? `\\nView inscription: ${cdnUrl}` : ''\n }\\n\\nThe inscription is now available.`;\n } else {\n return `Successfully submitted inscription to the Hedera network!\\n\\nTransaction ID: ${result.result.transactionId}\\n\\nThe inscription is processing and will be confirmed shortly.`;\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
+ {"version":3,"file":"standards-agent-kit.es28.js","sources":["../../src/tools/hcs6/CreateDynamicRegistryTool.ts"],"sourcesContent":["import { z } from 'zod';\nimport { BaseHCS6TransactionTool } from './base-hcs6-tools';\nimport { HCS6TransactionToolParams } from './hcs6-tool-params';\nimport type { TransactionResponse } from 'hedera-agent-kit';\n\n/**\n * Schema for creating a dynamic hashinal registry\n */\nconst CreateDynamicRegistrySchema = z.object({\n ttl: z.number()\n .min(3600)\n .default(86400)\n .describe('Time-to-live in seconds (minimum 3600 seconds/1 hour)'),\n adminKey: z.union([z.boolean(), z.string()])\n .optional()\n .describe('Admin key for the registry topic. Can be boolean (use operator key) or a public key string'),\n submitKey: z.union([z.boolean(), z.string()])\n .optional()\n .describe('Submit key for the registry topic. Can be boolean (use operator key) or a public key string'),\n});\n\nexport type CreateDynamicRegistryInput = z.infer<typeof CreateDynamicRegistrySchema>;\n\n/**\n * Tool for creating HCS-6 dynamic registries\n */\nexport class CreateDynamicRegistryTool extends BaseHCS6TransactionTool<typeof CreateDynamicRegistrySchema> {\n name = 'createDynamicRegistry';\n description = 'Create a new HCS-6 dynamic registry for managing evolving content';\n schema = CreateDynamicRegistrySchema;\n\n constructor(params: HCS6TransactionToolParams) {\n super(params);\n }\n\n protected async _call(\n params: CreateDynamicRegistryInput\n ): Promise<TransactionResponse> {\n try {\n const result = await this.hcs6Builder.createRegistry({\n ttl: params.ttl,\n adminKey: params.adminKey,\n submitKey: params.submitKey,\n });\n\n if (!result.success) {\n throw new Error(result.error || 'Failed to create dynamic registry');\n }\n\n return {\n status: 'success',\n data: {\n topicId: result.topicId,\n transactionId: result.transactionId,\n ttl: params.ttl,\n memo: `hcs-6:1:${params.ttl}`,\n },\n };\n } catch (error) {\n return {\n status: 'error',\n message: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n }\n}"],"names":[],"mappings":";;AAQA,MAAM,8BAA8B,EAAE,OAAO;AAAA,EAC3C,KAAK,EAAE,OAAA,EACJ,IAAI,IAAI,EACR,QAAQ,KAAK,EACb,SAAS,uDAAuD;AAAA,EACnE,UAAU,EAAE,MAAM,CAAC,EAAE,QAAA,GAAW,EAAE,OAAA,CAAQ,CAAC,EACxC,SAAA,EACA,SAAS,4FAA4F;AAAA,EACxG,WAAW,EAAE,MAAM,CAAC,EAAE,QAAA,GAAW,EAAE,OAAA,CAAQ,CAAC,EACzC,SAAA,EACA,SAAS,6FAA6F;AAC3G,CAAC;AAOM,MAAM,kCAAkC,wBAA4D;AAAA,EAKzG,YAAY,QAAmC;AAC7C,UAAM,MAAM;AALd,SAAA,OAAO;AACP,SAAA,cAAc;AACd,SAAA,SAAS;AAAA,EAIT;AAAA,EAEA,MAAgB,MACd,QAC8B;AAC9B,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,YAAY,eAAe;AAAA,QACnD,KAAK,OAAO;AAAA,QACZ,UAAU,OAAO;AAAA,QACjB,WAAW,OAAO;AAAA,MAAA,CACnB;AAED,UAAI,CAAC,OAAO,SAAS;AACnB,cAAM,IAAI,MAAM,OAAO,SAAS,mCAAmC;AAAA,MACrE;AAEA,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,MAAM;AAAA,UACJ,SAAS,OAAO;AAAA,UAChB,eAAe,OAAO;AAAA,UACtB,KAAK,OAAO;AAAA,UACZ,MAAM,WAAW,OAAO,GAAG;AAAA,QAAA;AAAA,MAC7B;AAAA,IAEJ,SAAS,OAAO;AACd,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,SAAS,iBAAiB,QAAQ,MAAM,UAAU;AAAA,MAAA;AAAA,IAEtD;AAAA,EACF;AACF;"}