@hashgraphonline/standards-agent-kit 0.2.127 → 0.2.129
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/standards-agent-kit.cjs +1 -1
- package/dist/cjs/standards-agent-kit.cjs.map +1 -1
- package/dist/cjs/tools/inscriber/InscribeFromBufferTool.d.ts +2 -10
- package/dist/cjs/tools/inscriber/InscribeHashinalTool.d.ts +62 -30
- package/dist/cjs/utils/content-resolver.d.ts +10 -0
- package/dist/cjs/utils/metadata-defaults.d.ts +18 -0
- package/dist/cjs/validation/content-ref-schemas.d.ts +9 -0
- package/dist/cjs/validation/hip412-schemas.d.ts +125 -0
- package/dist/es/standards-agent-kit.es36.js +11 -63
- package/dist/es/standards-agent-kit.es36.js.map +1 -1
- package/dist/es/standards-agent-kit.es37.js +159 -33
- package/dist/es/standards-agent-kit.es37.js.map +1 -1
- package/dist/es/standards-agent-kit.es44.js +57 -0
- package/dist/es/standards-agent-kit.es44.js.map +1 -0
- package/dist/es/standards-agent-kit.es45.js +6 -0
- package/dist/es/standards-agent-kit.es45.js.map +1 -0
- package/dist/es/standards-agent-kit.es46.js +43 -0
- package/dist/es/standards-agent-kit.es46.js.map +1 -0
- package/dist/es/standards-agent-kit.es47.js +15 -0
- package/dist/es/standards-agent-kit.es47.js.map +1 -0
- package/dist/es/tools/inscriber/InscribeFromBufferTool.d.ts +2 -10
- package/dist/es/tools/inscriber/InscribeHashinalTool.d.ts +62 -30
- package/dist/es/utils/content-resolver.d.ts +10 -0
- package/dist/es/utils/metadata-defaults.d.ts +18 -0
- package/dist/es/validation/content-ref-schemas.d.ts +9 -0
- package/dist/es/validation/hip412-schemas.d.ts +125 -0
- package/dist/umd/standards-agent-kit.umd.js +1 -1
- package/dist/umd/standards-agent-kit.umd.js.map +1 -1
- package/dist/umd/tools/inscriber/InscribeFromBufferTool.d.ts +2 -10
- package/dist/umd/tools/inscriber/InscribeHashinalTool.d.ts +62 -30
- package/dist/umd/utils/content-resolver.d.ts +10 -0
- package/dist/umd/utils/metadata-defaults.d.ts +18 -0
- package/dist/umd/validation/content-ref-schemas.d.ts +9 -0
- package/dist/umd/validation/hip412-schemas.d.ts +125 -0
- package/package.json +34 -31
- package/src/tools/inscriber/InscribeFromBufferTool.ts +30 -133
- package/src/tools/inscriber/InscribeHashinalTool.ts +271 -46
- package/src/utils/content-resolver.ts +87 -0
- package/src/utils/metadata-defaults.ts +25 -0
- package/src/validation/content-ref-schemas.ts +20 -0
- package/src/validation/hip412-schemas.ts +52 -0
|
@@ -2,10 +2,9 @@ import { z } from 'zod';
|
|
|
2
2
|
import { BaseInscriberQueryTool } from './base-inscriber-tools';
|
|
3
3
|
import { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';
|
|
4
4
|
declare const inscribeFromBufferSchema: z.ZodObject<{
|
|
5
|
-
base64Data: z.ZodString
|
|
5
|
+
base64Data: z.ZodUnion<[z.ZodString, z.ZodString]>;
|
|
6
6
|
fileName: z.ZodString;
|
|
7
7
|
mimeType: z.ZodOptional<z.ZodString>;
|
|
8
|
-
mode: z.ZodOptional<z.ZodEnum<["file", "hashinal"]>>;
|
|
9
8
|
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
10
9
|
tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
11
10
|
chunkSize: z.ZodOptional<z.ZodNumber>;
|
|
@@ -20,7 +19,6 @@ declare const inscribeFromBufferSchema: z.ZodObject<{
|
|
|
20
19
|
tags?: string[] | undefined;
|
|
21
20
|
metadata?: Record<string, unknown> | undefined;
|
|
22
21
|
mimeType?: string | undefined;
|
|
23
|
-
mode?: "file" | "hashinal" | undefined;
|
|
24
22
|
chunkSize?: number | undefined;
|
|
25
23
|
waitForConfirmation?: boolean | undefined;
|
|
26
24
|
timeoutMs?: number | undefined;
|
|
@@ -31,7 +29,6 @@ declare const inscribeFromBufferSchema: z.ZodObject<{
|
|
|
31
29
|
tags?: string[] | undefined;
|
|
32
30
|
metadata?: Record<string, unknown> | undefined;
|
|
33
31
|
mimeType?: string | undefined;
|
|
34
|
-
mode?: "file" | "hashinal" | undefined;
|
|
35
32
|
chunkSize?: number | undefined;
|
|
36
33
|
waitForConfirmation?: boolean | undefined;
|
|
37
34
|
timeoutMs?: number | undefined;
|
|
@@ -43,10 +40,9 @@ export declare class InscribeFromBufferTool extends BaseInscriberQueryTool<typeo
|
|
|
43
40
|
description: string;
|
|
44
41
|
private config;
|
|
45
42
|
get specificInputSchema(): z.ZodObject<{
|
|
46
|
-
base64Data: z.ZodString
|
|
43
|
+
base64Data: z.ZodUnion<[z.ZodString, z.ZodString]>;
|
|
47
44
|
fileName: z.ZodString;
|
|
48
45
|
mimeType: z.ZodOptional<z.ZodString>;
|
|
49
|
-
mode: z.ZodOptional<z.ZodEnum<["file", "hashinal"]>>;
|
|
50
46
|
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
51
47
|
tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
52
48
|
chunkSize: z.ZodOptional<z.ZodNumber>;
|
|
@@ -61,7 +57,6 @@ export declare class InscribeFromBufferTool extends BaseInscriberQueryTool<typeo
|
|
|
61
57
|
tags?: string[] | undefined;
|
|
62
58
|
metadata?: Record<string, unknown> | undefined;
|
|
63
59
|
mimeType?: string | undefined;
|
|
64
|
-
mode?: "file" | "hashinal" | undefined;
|
|
65
60
|
chunkSize?: number | undefined;
|
|
66
61
|
waitForConfirmation?: boolean | undefined;
|
|
67
62
|
timeoutMs?: number | undefined;
|
|
@@ -72,7 +67,6 @@ export declare class InscribeFromBufferTool extends BaseInscriberQueryTool<typeo
|
|
|
72
67
|
tags?: string[] | undefined;
|
|
73
68
|
metadata?: Record<string, unknown> | undefined;
|
|
74
69
|
mimeType?: string | undefined;
|
|
75
|
-
mode?: "file" | "hashinal" | undefined;
|
|
76
70
|
chunkSize?: number | undefined;
|
|
77
71
|
waitForConfirmation?: boolean | undefined;
|
|
78
72
|
timeoutMs?: number | undefined;
|
|
@@ -84,7 +78,5 @@ export declare class InscribeFromBufferTool extends BaseInscriberQueryTool<typeo
|
|
|
84
78
|
private validateContent;
|
|
85
79
|
private executeInscription;
|
|
86
80
|
private formatInscriptionResult;
|
|
87
|
-
private resolveContent;
|
|
88
|
-
private handleDirectContent;
|
|
89
81
|
}
|
|
90
82
|
export {};
|
|
@@ -5,11 +5,15 @@ import { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';
|
|
|
5
5
|
* Schema for inscribing Hashinal NFT
|
|
6
6
|
*/
|
|
7
7
|
declare const inscribeHashinalSchema: z.ZodObject<{
|
|
8
|
-
url: z.ZodString
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
url: z.ZodOptional<z.ZodString>;
|
|
9
|
+
contentRef: z.ZodOptional<z.ZodString>;
|
|
10
|
+
base64Data: z.ZodOptional<z.ZodString>;
|
|
11
|
+
fileName: z.ZodOptional<z.ZodString>;
|
|
12
|
+
mimeType: z.ZodOptional<z.ZodString>;
|
|
13
|
+
name: z.ZodOptional<z.ZodString>;
|
|
14
|
+
creator: z.ZodOptional<z.ZodString>;
|
|
15
|
+
description: z.ZodOptional<z.ZodString>;
|
|
16
|
+
type: z.ZodOptional<z.ZodString>;
|
|
13
17
|
attributes: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
14
18
|
trait_type: z.ZodString;
|
|
15
19
|
value: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
|
|
@@ -22,6 +26,7 @@ declare const inscribeHashinalSchema: z.ZodObject<{
|
|
|
22
26
|
}>, "many">>;
|
|
23
27
|
properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
24
28
|
jsonFileURL: z.ZodOptional<z.ZodString>;
|
|
29
|
+
fileStandard: z.ZodDefault<z.ZodOptional<z.ZodEnum<["1", "6"]>>>;
|
|
25
30
|
tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
26
31
|
chunkSize: z.ZodOptional<z.ZodNumber>;
|
|
27
32
|
waitForConfirmation: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -29,41 +34,51 @@ declare const inscribeHashinalSchema: z.ZodObject<{
|
|
|
29
34
|
apiKey: z.ZodOptional<z.ZodString>;
|
|
30
35
|
quoteOnly: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
31
36
|
}, "strip", z.ZodTypeAny, {
|
|
32
|
-
url: string;
|
|
33
|
-
type: string;
|
|
34
|
-
name: string;
|
|
35
|
-
description: string;
|
|
36
|
-
creator: string;
|
|
37
37
|
quoteOnly: boolean;
|
|
38
|
+
fileStandard: "1" | "6";
|
|
39
|
+
url?: string | undefined;
|
|
40
|
+
type?: string | undefined;
|
|
41
|
+
name?: string | undefined;
|
|
42
|
+
description?: string | undefined;
|
|
38
43
|
tags?: string[] | undefined;
|
|
44
|
+
creator?: string | undefined;
|
|
39
45
|
properties?: Record<string, unknown> | undefined;
|
|
46
|
+
mimeType?: string | undefined;
|
|
40
47
|
chunkSize?: number | undefined;
|
|
41
48
|
waitForConfirmation?: boolean | undefined;
|
|
42
49
|
timeoutMs?: number | undefined;
|
|
43
50
|
apiKey?: string | undefined;
|
|
51
|
+
fileName?: string | undefined;
|
|
52
|
+
base64Data?: string | undefined;
|
|
44
53
|
attributes?: {
|
|
45
54
|
value: string | number;
|
|
46
55
|
trait_type: string;
|
|
47
56
|
}[] | undefined;
|
|
57
|
+
contentRef?: string | undefined;
|
|
48
58
|
jsonFileURL?: string | undefined;
|
|
49
59
|
}, {
|
|
50
|
-
url
|
|
51
|
-
type
|
|
52
|
-
name
|
|
53
|
-
description
|
|
54
|
-
creator: string;
|
|
60
|
+
url?: string | undefined;
|
|
61
|
+
type?: string | undefined;
|
|
62
|
+
name?: string | undefined;
|
|
63
|
+
description?: string | undefined;
|
|
55
64
|
tags?: string[] | undefined;
|
|
65
|
+
creator?: string | undefined;
|
|
56
66
|
properties?: Record<string, unknown> | undefined;
|
|
67
|
+
mimeType?: string | undefined;
|
|
57
68
|
chunkSize?: number | undefined;
|
|
58
69
|
waitForConfirmation?: boolean | undefined;
|
|
59
70
|
timeoutMs?: number | undefined;
|
|
60
71
|
apiKey?: string | undefined;
|
|
61
72
|
quoteOnly?: boolean | undefined;
|
|
73
|
+
fileName?: string | undefined;
|
|
74
|
+
base64Data?: string | undefined;
|
|
62
75
|
attributes?: {
|
|
63
76
|
value: string | number;
|
|
64
77
|
trait_type: string;
|
|
65
78
|
}[] | undefined;
|
|
79
|
+
contentRef?: string | undefined;
|
|
66
80
|
jsonFileURL?: string | undefined;
|
|
81
|
+
fileStandard?: "1" | "6" | undefined;
|
|
67
82
|
}>;
|
|
68
83
|
/**
|
|
69
84
|
* Tool for inscribing Hashinal NFTs
|
|
@@ -72,11 +87,15 @@ export declare class InscribeHashinalTool extends BaseInscriberQueryTool<typeof
|
|
|
72
87
|
name: string;
|
|
73
88
|
description: string;
|
|
74
89
|
get specificInputSchema(): z.ZodObject<{
|
|
75
|
-
url: z.ZodString
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
90
|
+
url: z.ZodOptional<z.ZodString>;
|
|
91
|
+
contentRef: z.ZodOptional<z.ZodString>;
|
|
92
|
+
base64Data: z.ZodOptional<z.ZodString>;
|
|
93
|
+
fileName: z.ZodOptional<z.ZodString>;
|
|
94
|
+
mimeType: z.ZodOptional<z.ZodString>;
|
|
95
|
+
name: z.ZodOptional<z.ZodString>;
|
|
96
|
+
creator: z.ZodOptional<z.ZodString>;
|
|
97
|
+
description: z.ZodOptional<z.ZodString>;
|
|
98
|
+
type: z.ZodOptional<z.ZodString>;
|
|
80
99
|
attributes: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
81
100
|
trait_type: z.ZodString;
|
|
82
101
|
value: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
|
|
@@ -89,6 +108,7 @@ export declare class InscribeHashinalTool extends BaseInscriberQueryTool<typeof
|
|
|
89
108
|
}>, "many">>;
|
|
90
109
|
properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
91
110
|
jsonFileURL: z.ZodOptional<z.ZodString>;
|
|
111
|
+
fileStandard: z.ZodDefault<z.ZodOptional<z.ZodEnum<["1", "6"]>>>;
|
|
92
112
|
tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
93
113
|
chunkSize: z.ZodOptional<z.ZodNumber>;
|
|
94
114
|
waitForConfirmation: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -96,42 +116,54 @@ export declare class InscribeHashinalTool extends BaseInscriberQueryTool<typeof
|
|
|
96
116
|
apiKey: z.ZodOptional<z.ZodString>;
|
|
97
117
|
quoteOnly: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
98
118
|
}, "strip", z.ZodTypeAny, {
|
|
99
|
-
url: string;
|
|
100
|
-
type: string;
|
|
101
|
-
name: string;
|
|
102
|
-
description: string;
|
|
103
|
-
creator: string;
|
|
104
119
|
quoteOnly: boolean;
|
|
120
|
+
fileStandard: "1" | "6";
|
|
121
|
+
url?: string | undefined;
|
|
122
|
+
type?: string | undefined;
|
|
123
|
+
name?: string | undefined;
|
|
124
|
+
description?: string | undefined;
|
|
105
125
|
tags?: string[] | undefined;
|
|
126
|
+
creator?: string | undefined;
|
|
106
127
|
properties?: Record<string, unknown> | undefined;
|
|
128
|
+
mimeType?: string | undefined;
|
|
107
129
|
chunkSize?: number | undefined;
|
|
108
130
|
waitForConfirmation?: boolean | undefined;
|
|
109
131
|
timeoutMs?: number | undefined;
|
|
110
132
|
apiKey?: string | undefined;
|
|
133
|
+
fileName?: string | undefined;
|
|
134
|
+
base64Data?: string | undefined;
|
|
111
135
|
attributes?: {
|
|
112
136
|
value: string | number;
|
|
113
137
|
trait_type: string;
|
|
114
138
|
}[] | undefined;
|
|
139
|
+
contentRef?: string | undefined;
|
|
115
140
|
jsonFileURL?: string | undefined;
|
|
116
141
|
}, {
|
|
117
|
-
url
|
|
118
|
-
type
|
|
119
|
-
name
|
|
120
|
-
description
|
|
121
|
-
creator: string;
|
|
142
|
+
url?: string | undefined;
|
|
143
|
+
type?: string | undefined;
|
|
144
|
+
name?: string | undefined;
|
|
145
|
+
description?: string | undefined;
|
|
122
146
|
tags?: string[] | undefined;
|
|
147
|
+
creator?: string | undefined;
|
|
123
148
|
properties?: Record<string, unknown> | undefined;
|
|
149
|
+
mimeType?: string | undefined;
|
|
124
150
|
chunkSize?: number | undefined;
|
|
125
151
|
waitForConfirmation?: boolean | undefined;
|
|
126
152
|
timeoutMs?: number | undefined;
|
|
127
153
|
apiKey?: string | undefined;
|
|
128
154
|
quoteOnly?: boolean | undefined;
|
|
155
|
+
fileName?: string | undefined;
|
|
156
|
+
base64Data?: string | undefined;
|
|
129
157
|
attributes?: {
|
|
130
158
|
value: string | number;
|
|
131
159
|
trait_type: string;
|
|
132
160
|
}[] | undefined;
|
|
161
|
+
contentRef?: string | undefined;
|
|
133
162
|
jsonFileURL?: string | undefined;
|
|
163
|
+
fileStandard?: "1" | "6" | undefined;
|
|
134
164
|
}>;
|
|
135
165
|
protected executeQuery(params: z.infer<typeof inscribeHashinalSchema>, _runManager?: CallbackManagerForToolRun): Promise<unknown>;
|
|
166
|
+
private resolveContent;
|
|
167
|
+
private handleDirectContent;
|
|
136
168
|
}
|
|
137
169
|
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface ContentResolutionResult {
|
|
2
|
+
buffer: Buffer;
|
|
3
|
+
mimeType?: string;
|
|
4
|
+
fileName?: string;
|
|
5
|
+
wasReference?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Resolves content from various input formats (content-ref, base64, plain text)
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveContent(input: string, providedMimeType?: string, providedFileName?: string): Promise<ContentResolutionResult>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates default metadata for NFT inscription
|
|
3
|
+
*/
|
|
4
|
+
export declare function generateDefaultMetadata(params: {
|
|
5
|
+
name?: string;
|
|
6
|
+
creator?: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
type?: string;
|
|
9
|
+
fileName?: string;
|
|
10
|
+
mimeType?: string;
|
|
11
|
+
operatorAccount: string;
|
|
12
|
+
}): {
|
|
13
|
+
name: string;
|
|
14
|
+
creator: string;
|
|
15
|
+
description: string;
|
|
16
|
+
type: string;
|
|
17
|
+
image: string;
|
|
18
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Validates content reference format
|
|
4
|
+
*/
|
|
5
|
+
export declare const contentRefSchema: z.ZodString;
|
|
6
|
+
/**
|
|
7
|
+
* Validates content reference or returns error for dumber models
|
|
8
|
+
*/
|
|
9
|
+
export declare function validateContentRef(input: string): string;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* HIP-412 file schema for multi-file NFTs
|
|
4
|
+
*/
|
|
5
|
+
export declare const hip412FileSchema: z.ZodObject<{
|
|
6
|
+
uri: z.ZodString;
|
|
7
|
+
checksum: z.ZodOptional<z.ZodString>;
|
|
8
|
+
is_default_file: z.ZodOptional<z.ZodBoolean>;
|
|
9
|
+
type: z.ZodString;
|
|
10
|
+
}, "strip", z.ZodTypeAny, {
|
|
11
|
+
type: string;
|
|
12
|
+
uri: string;
|
|
13
|
+
checksum?: string | undefined;
|
|
14
|
+
is_default_file?: boolean | undefined;
|
|
15
|
+
}, {
|
|
16
|
+
type: string;
|
|
17
|
+
uri: string;
|
|
18
|
+
checksum?: string | undefined;
|
|
19
|
+
is_default_file?: boolean | undefined;
|
|
20
|
+
}>;
|
|
21
|
+
/**
|
|
22
|
+
* HIP-412 attribute schema for NFT traits
|
|
23
|
+
*/
|
|
24
|
+
export declare const hip412AttributeSchema: z.ZodObject<{
|
|
25
|
+
trait_type: z.ZodString;
|
|
26
|
+
value: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
|
|
27
|
+
display_type: z.ZodOptional<z.ZodString>;
|
|
28
|
+
}, "strip", z.ZodTypeAny, {
|
|
29
|
+
value: string | number;
|
|
30
|
+
trait_type: string;
|
|
31
|
+
display_type?: string | undefined;
|
|
32
|
+
}, {
|
|
33
|
+
value: string | number;
|
|
34
|
+
trait_type: string;
|
|
35
|
+
display_type?: string | undefined;
|
|
36
|
+
}>;
|
|
37
|
+
/**
|
|
38
|
+
* HIP-412 compliant metadata schema for Hedera NFTs
|
|
39
|
+
*/
|
|
40
|
+
export declare const hip412MetadataSchema: z.ZodObject<{
|
|
41
|
+
name: z.ZodString;
|
|
42
|
+
description: z.ZodString;
|
|
43
|
+
image: z.ZodString;
|
|
44
|
+
type: z.ZodString;
|
|
45
|
+
creator: z.ZodOptional<z.ZodString>;
|
|
46
|
+
creatorDID: z.ZodOptional<z.ZodString>;
|
|
47
|
+
checksum: z.ZodOptional<z.ZodString>;
|
|
48
|
+
format: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
49
|
+
files: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
50
|
+
uri: z.ZodString;
|
|
51
|
+
checksum: z.ZodOptional<z.ZodString>;
|
|
52
|
+
is_default_file: z.ZodOptional<z.ZodBoolean>;
|
|
53
|
+
type: z.ZodString;
|
|
54
|
+
}, "strip", z.ZodTypeAny, {
|
|
55
|
+
type: string;
|
|
56
|
+
uri: string;
|
|
57
|
+
checksum?: string | undefined;
|
|
58
|
+
is_default_file?: boolean | undefined;
|
|
59
|
+
}, {
|
|
60
|
+
type: string;
|
|
61
|
+
uri: string;
|
|
62
|
+
checksum?: string | undefined;
|
|
63
|
+
is_default_file?: boolean | undefined;
|
|
64
|
+
}>, "many">>;
|
|
65
|
+
attributes: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
66
|
+
trait_type: z.ZodString;
|
|
67
|
+
value: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
|
|
68
|
+
display_type: z.ZodOptional<z.ZodString>;
|
|
69
|
+
}, "strip", z.ZodTypeAny, {
|
|
70
|
+
value: string | number;
|
|
71
|
+
trait_type: string;
|
|
72
|
+
display_type?: string | undefined;
|
|
73
|
+
}, {
|
|
74
|
+
value: string | number;
|
|
75
|
+
trait_type: string;
|
|
76
|
+
display_type?: string | undefined;
|
|
77
|
+
}>, "many">>;
|
|
78
|
+
properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
79
|
+
}, "strip", z.ZodTypeAny, {
|
|
80
|
+
type: string;
|
|
81
|
+
image: string;
|
|
82
|
+
name: string;
|
|
83
|
+
description: string;
|
|
84
|
+
format: string;
|
|
85
|
+
creator?: string | undefined;
|
|
86
|
+
properties?: Record<string, unknown> | undefined;
|
|
87
|
+
checksum?: string | undefined;
|
|
88
|
+
creatorDID?: string | undefined;
|
|
89
|
+
files?: {
|
|
90
|
+
type: string;
|
|
91
|
+
uri: string;
|
|
92
|
+
checksum?: string | undefined;
|
|
93
|
+
is_default_file?: boolean | undefined;
|
|
94
|
+
}[] | undefined;
|
|
95
|
+
attributes?: {
|
|
96
|
+
value: string | number;
|
|
97
|
+
trait_type: string;
|
|
98
|
+
display_type?: string | undefined;
|
|
99
|
+
}[] | undefined;
|
|
100
|
+
}, {
|
|
101
|
+
type: string;
|
|
102
|
+
image: string;
|
|
103
|
+
name: string;
|
|
104
|
+
description: string;
|
|
105
|
+
creator?: string | undefined;
|
|
106
|
+
properties?: Record<string, unknown> | undefined;
|
|
107
|
+
checksum?: string | undefined;
|
|
108
|
+
creatorDID?: string | undefined;
|
|
109
|
+
format?: string | undefined;
|
|
110
|
+
files?: {
|
|
111
|
+
type: string;
|
|
112
|
+
uri: string;
|
|
113
|
+
checksum?: string | undefined;
|
|
114
|
+
is_default_file?: boolean | undefined;
|
|
115
|
+
}[] | undefined;
|
|
116
|
+
attributes?: {
|
|
117
|
+
value: string | number;
|
|
118
|
+
trait_type: string;
|
|
119
|
+
display_type?: string | undefined;
|
|
120
|
+
}[] | undefined;
|
|
121
|
+
}>;
|
|
122
|
+
/**
|
|
123
|
+
* Validates metadata against HIP-412 standard
|
|
124
|
+
*/
|
|
125
|
+
export declare function validateHIP412Metadata(metadata: any): z.infer<typeof hip412MetadataSchema>;
|
|
@@ -1,29 +1,25 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { BaseInscriberQueryTool } from "./standards-agent-kit.es33.js";
|
|
3
|
-
import {
|
|
3
|
+
import { resolveContent } from "./standards-agent-kit.es44.js";
|
|
4
|
+
import { contentRefSchema } from "./standards-agent-kit.es45.js";
|
|
4
5
|
import { loadConfig } from "./standards-agent-kit.es2.js";
|
|
5
6
|
const inscribeFromBufferSchema = z.object({
|
|
6
|
-
base64Data: z.string().
|
|
7
|
-
|
|
8
|
-
),
|
|
9
|
-
fileName: z.string().min(1, "File name cannot be empty").describe("Name for the inscribed content. Required for all inscriptions."),
|
|
7
|
+
base64Data: z.union([z.string(), contentRefSchema]).describe("Content to inscribe as base64 data, plain text, or content reference"),
|
|
8
|
+
fileName: z.string().min(1).describe("Name for the inscribed content"),
|
|
10
9
|
mimeType: z.string().optional().describe("MIME type of the content"),
|
|
11
|
-
|
|
12
|
-
metadata: z.record(z.unknown()).optional().describe("Metadata to attach to the inscription"),
|
|
10
|
+
metadata: z.record(z.unknown()).optional().describe("Metadata to attach"),
|
|
13
11
|
tags: z.array(z.string()).optional().describe("Tags to categorize the inscription"),
|
|
14
12
|
chunkSize: z.number().int().positive().optional().describe("Chunk size for large files"),
|
|
15
|
-
waitForConfirmation: z.boolean().optional().describe("
|
|
16
|
-
timeoutMs: z.number().int().positive().optional().describe(
|
|
17
|
-
"Timeout in milliseconds for inscription (default: no timeout - waits until completion)"
|
|
18
|
-
),
|
|
13
|
+
waitForConfirmation: z.boolean().optional().describe("Wait for inscription confirmation"),
|
|
14
|
+
timeoutMs: z.number().int().positive().optional().describe("Timeout in milliseconds"),
|
|
19
15
|
apiKey: z.string().optional().describe("API key for inscription service"),
|
|
20
|
-
quoteOnly: z.boolean().optional().default(false).describe("
|
|
16
|
+
quoteOnly: z.boolean().optional().default(false).describe("Return cost quote only")
|
|
21
17
|
});
|
|
22
18
|
class InscribeFromBufferTool extends BaseInscriberQueryTool {
|
|
23
19
|
constructor() {
|
|
24
20
|
super(...arguments);
|
|
25
21
|
this.name = "inscribeFromBuffer";
|
|
26
|
-
this.description = 'Inscribe content that you have already retrieved or displayed. When user says "inscribe it" after you showed search results or other content, 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.';
|
|
22
|
+
this.description = 'Inscribe content that you have already retrieved or displayed as standard file inscription (NOT for hashinal NFTs - use InscribeHashinalTool for NFTs). When user says "inscribe it" after you showed search results or other content, 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.';
|
|
27
23
|
this.config = loadConfig();
|
|
28
24
|
}
|
|
29
25
|
get specificInputSchema() {
|
|
@@ -31,7 +27,7 @@ class InscribeFromBufferTool extends BaseInscriberQueryTool {
|
|
|
31
27
|
}
|
|
32
28
|
async executeQuery(params, _runManager) {
|
|
33
29
|
this.validateInput(params);
|
|
34
|
-
const resolvedContent = await
|
|
30
|
+
const resolvedContent = await resolveContent(
|
|
35
31
|
params.base64Data,
|
|
36
32
|
params.mimeType,
|
|
37
33
|
params.fileName
|
|
@@ -41,7 +37,7 @@ class InscribeFromBufferTool extends BaseInscriberQueryTool {
|
|
|
41
37
|
const resolvedMimeType = resolvedContent.mimeType || params.mimeType;
|
|
42
38
|
const resolvedFileName = resolvedContent.fileName || params.fileName;
|
|
43
39
|
const options = {
|
|
44
|
-
mode:
|
|
40
|
+
mode: "file",
|
|
45
41
|
metadata: params.metadata,
|
|
46
42
|
tags: params.tags,
|
|
47
43
|
chunkSize: params.chunkSize,
|
|
@@ -184,54 +180,6 @@ The inscription is processing and will be confirmed shortly.`;
|
|
|
184
180
|
}
|
|
185
181
|
return "Inscription operation completed.";
|
|
186
182
|
}
|
|
187
|
-
async resolveContent(input, providedMimeType, providedFileName) {
|
|
188
|
-
const trimmedInput = input.trim();
|
|
189
|
-
const resolver = this.getContentResolver() || ContentResolverRegistry.getResolver();
|
|
190
|
-
if (!resolver) {
|
|
191
|
-
return this.handleDirectContent(trimmedInput, providedMimeType, providedFileName);
|
|
192
|
-
}
|
|
193
|
-
const referenceId = resolver.extractReferenceId(trimmedInput);
|
|
194
|
-
if (referenceId) {
|
|
195
|
-
try {
|
|
196
|
-
const resolution = await resolver.resolveReference(referenceId);
|
|
197
|
-
return {
|
|
198
|
-
buffer: resolution.content,
|
|
199
|
-
mimeType: resolution.metadata?.mimeType || providedMimeType,
|
|
200
|
-
fileName: resolution.metadata?.fileName || providedFileName,
|
|
201
|
-
wasReference: true
|
|
202
|
-
};
|
|
203
|
-
} catch (error) {
|
|
204
|
-
const errorMsg = error instanceof Error ? error.message : "Unknown error resolving reference";
|
|
205
|
-
throw new Error(`Reference resolution failed: ${errorMsg}`);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
return this.handleDirectContent(trimmedInput, providedMimeType, providedFileName);
|
|
209
|
-
}
|
|
210
|
-
handleDirectContent(input, providedMimeType, providedFileName) {
|
|
211
|
-
const isValidBase64 = /^[A-Za-z0-9+/]*={0,2}$/.test(input);
|
|
212
|
-
if (isValidBase64) {
|
|
213
|
-
try {
|
|
214
|
-
const buffer2 = Buffer.from(input, "base64");
|
|
215
|
-
return {
|
|
216
|
-
buffer: buffer2,
|
|
217
|
-
mimeType: providedMimeType,
|
|
218
|
-
fileName: providedFileName,
|
|
219
|
-
wasReference: false
|
|
220
|
-
};
|
|
221
|
-
} catch (error) {
|
|
222
|
-
throw new Error(
|
|
223
|
-
"Failed to decode base64 data. Please ensure the data is properly encoded."
|
|
224
|
-
);
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
const buffer = Buffer.from(input, "utf8");
|
|
228
|
-
return {
|
|
229
|
-
buffer,
|
|
230
|
-
mimeType: providedMimeType || "text/plain",
|
|
231
|
-
fileName: providedFileName,
|
|
232
|
-
wasReference: false
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
183
|
}
|
|
236
184
|
export {
|
|
237
185
|
InscribeFromBufferTool
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standards-agent-kit.es36.js","sources":["../../src/tools/inscriber/InscribeFromBufferTool.ts"],"sourcesContent":["import { z } from 'zod';\nimport { BaseInscriberQueryTool } from './base-inscriber-tools';\nimport { InscriptionOptions, ContentResolverRegistry } from '@hashgraphonline/standards-sdk';\nimport { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';\nimport { loadConfig } from '../../config/ContentReferenceConfig';\n\nconst inscribeFromBufferSchema = z.object({\n base64Data: z\n .string()\n .min(1, 'Data cannot be empty')\n .describe(\n 'The content to inscribe. Accept BOTH plain text AND base64. Also accepts content reference IDs in format \"content-ref:[id]\". When user says \"inscribe it\" or \"inscribe the content\", use the EXACT content from your previous message or from MCP tool results. DO NOT generate new content. DO NOT create repetitive text. Pass the actual search results or other retrieved content EXACTLY as you received it.'\n ),\n fileName: z\n .string()\n .min(1, 'File name cannot be empty')\n .describe('Name for the inscribed content. Required for all inscriptions.'),\n mimeType: z.string().optional().describe('MIME type of the content'),\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(\n 'Timeout in milliseconds for inscription (default: no timeout - waits until completion)'\n ),\n apiKey: z.string().optional().describe('API key for inscription service'),\n quoteOnly: z\n .boolean()\n .optional()\n .default(false)\n .describe('If true, returns a cost quote instead of executing the inscription'),\n});\n\nexport class InscribeFromBufferTool extends BaseInscriberQueryTool<\n typeof inscribeFromBufferSchema\n> {\n name = 'inscribeFromBuffer';\n description =\n 'Inscribe content that you have already retrieved or displayed. When user says \"inscribe it\" after you showed search results or other content, 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.';\n\n private config = loadConfig();\n\n get specificInputSchema() {\n return inscribeFromBufferSchema;\n }\n\n protected async executeQuery(\n params: z.infer<typeof inscribeFromBufferSchema>,\n _runManager?: CallbackManagerForToolRun\n ): Promise<unknown> {\n this.validateInput(params);\n\n const resolvedContent = await this.resolveContent(\n params.base64Data,\n params.mimeType,\n params.fileName\n );\n\n this.validateContent(resolvedContent.buffer);\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: params.mode,\n metadata: params.metadata,\n tags: params.tags,\n chunkSize: params.chunkSize,\n waitForConfirmation: params.quoteOnly ? false : (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,\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} (${(buffer.length / 1024).toFixed(2)} KB)\\nTotal cost: ${quote.totalCostHbar} HBAR`,\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'Failed to generate inscription quote';\n throw new Error(`Quote generation failed: ${errorMessage}`);\n }\n }\n\n try {\n const result = await this.executeInscription(\n buffer,\n resolvedFileName,\n resolvedMimeType,\n options,\n params.timeoutMs\n );\n return this.formatInscriptionResult(result, options);\n } catch (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 if (result.confirmed && !result.quote) {\n const topicId = result.inscription?.topic_id || (result.result as any).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 as any).transactionId\n }\\nTopic ID: ${topicId || 'N/A'}${\n cdnUrl ? `\\nView inscription: ${cdnUrl}` : ''\n }\\n\\nThe inscription is now available.`;\n }\n\n if (!result.quote && !result.confirmed) {\n return `Successfully submitted inscription to the Hedera network!\\n\\nTransaction ID: ${(result.result as any).transactionId}\\n\\nThe inscription is processing and will be confirmed shortly.`;\n }\n\n return 'Inscription operation completed.';\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 = this.getContentResolver() || ContentResolverRegistry.getResolver();\n \n if (!resolver) {\n return this.handleDirectContent(trimmedInput, providedMimeType, providedFileName);\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(trimmedInput, providedMimeType, providedFileName);\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"],"names":["buffer"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"standards-agent-kit.es36.js","sources":["../../src/tools/inscriber/InscribeFromBufferTool.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 { resolveContent } from '../../utils/content-resolver';\nimport { contentRefSchema } from '../../validation/content-ref-schemas';\nimport { loadConfig } from '../../config/ContentReferenceConfig';\n\nconst inscribeFromBufferSchema = z.object({\n base64Data: z.union([z.string(), contentRefSchema])\n .describe('Content to inscribe as base64 data, plain text, or content reference'),\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.array(z.string()).optional().describe('Tags to categorize the inscription'),\n chunkSize: z.number().int().positive().optional().describe('Chunk size for large files'),\n waitForConfirmation: z.boolean().optional().describe('Wait for inscription confirmation'),\n timeoutMs: z.number().int().positive().optional().describe('Timeout in milliseconds'),\n apiKey: z.string().optional().describe('API key for inscription service'),\n quoteOnly: z.boolean().optional().default(false).describe('Return cost quote only'),\n});\n\nexport class InscribeFromBufferTool extends BaseInscriberQueryTool<\n typeof inscribeFromBufferSchema\n> {\n name = 'inscribeFromBuffer';\n description =\n 'Inscribe content that you have already retrieved or displayed as standard file inscription (NOT for hashinal NFTs - use InscribeHashinalTool for NFTs). When user says \"inscribe it\" after you showed search results or other content, 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.';\n\n private config = loadConfig();\n\n get specificInputSchema() {\n return inscribeFromBufferSchema;\n }\n\n protected async executeQuery(\n params: z.infer<typeof inscribeFromBufferSchema>,\n _runManager?: CallbackManagerForToolRun\n ): Promise<unknown> {\n this.validateInput(params);\n\n const resolvedContent = await resolveContent(\n params.base64Data,\n params.mimeType,\n params.fileName\n );\n\n this.validateContent(resolvedContent.buffer);\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: 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,\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 const result = await this.executeInscription(\n buffer,\n resolvedFileName,\n resolvedMimeType,\n options,\n params.timeoutMs\n );\n return this.formatInscriptionResult(result, options);\n } catch (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 if (result.confirmed && !result.quote) {\n const topicId =\n result.inscription?.topic_id || (result.result as any).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 as any).transactionId\n }\\nTopic ID: ${topicId || 'N/A'}${\n cdnUrl ? `\\nView inscription: ${cdnUrl}` : ''\n }\\n\\nThe inscription is now available.`;\n }\n\n if (!result.quote && !result.confirmed) {\n return `Successfully submitted inscription to the Hedera network!\\n\\nTransaction ID: ${\n (result.result as any).transactionId\n }\\n\\nThe inscription is processing and will be confirmed shortly.`;\n }\n\n return 'Inscription operation completed.';\n }\n\n}\n"],"names":[],"mappings":";;;;;AAQA,MAAM,2BAA2B,EAAE,OAAO;AAAA,EACxC,YAAY,EAAE,MAAM,CAAC,EAAE,OAAA,GAAU,gBAAgB,CAAC,EAC/C,SAAS,sEAAsE;AAAA,EAClF,UAAU,EAAE,OAAA,EAAS,IAAI,CAAC,EAAE,SAAS,gCAAgC;AAAA,EACrE,UAAU,EAAE,OAAA,EAAS,SAAA,EAAW,SAAS,0BAA0B;AAAA,EACnE,UAAU,EAAE,OAAO,EAAE,QAAA,CAAS,EAAE,SAAA,EAAW,SAAS,oBAAoB;AAAA,EACxE,MAAM,EAAE,MAAM,EAAE,OAAA,CAAQ,EAAE,SAAA,EAAW,SAAS,oCAAoC;AAAA,EAClF,WAAW,EAAE,OAAA,EAAS,IAAA,EAAM,SAAA,EAAW,SAAA,EAAW,SAAS,4BAA4B;AAAA,EACvF,qBAAqB,EAAE,QAAA,EAAU,SAAA,EAAW,SAAS,mCAAmC;AAAA,EACxF,WAAW,EAAE,OAAA,EAAS,IAAA,EAAM,SAAA,EAAW,SAAA,EAAW,SAAS,yBAAyB;AAAA,EACpF,QAAQ,EAAE,OAAA,EAAS,SAAA,EAAW,SAAS,iCAAiC;AAAA,EACxE,WAAW,EAAE,UAAU,SAAA,EAAW,QAAQ,KAAK,EAAE,SAAS,wBAAwB;AACpF,CAAC;AAEM,MAAM,+BAA+B,uBAE1C;AAAA,EAFK,cAAA;AAAA,UAAA,GAAA,SAAA;AAGL,SAAA,OAAO;AACP,SAAA,cACE;AAEF,SAAQ,SAAS,WAAA;AAAA,EAAW;AAAA,EAE5B,IAAI,sBAAsB;AACxB,WAAO;AAAA,EACT;AAAA,EAEA,MAAgB,aACd,QACA,aACkB;AAClB,SAAK,cAAc,MAAM;AAEzB,UAAM,kBAAkB,MAAM;AAAA,MAC5B,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,IAAA;AAGT,SAAK,gBAAgB,gBAAgB,MAAM;AAE3C,UAAM,SAAS,gBAAgB;AAC/B,UAAM,mBAAmB,gBAAgB,YAAY,OAAO;AAC5D,UAAM,mBAAmB,gBAAgB,YAAY,OAAO;AAE5D,UAAM,UAA8B;AAAA,MAClC,MAAM;AAAA,MACN,UAAU,OAAO;AAAA,MACjB,MAAM,OAAO;AAAA,MACb,WAAW,OAAO;AAAA,MAClB,qBAAqB,OAAO,YACxB,QACA,OAAO,uBAAuB;AAAA,MAClC,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,QAAQ,OAAO;AAAA,MACf,SAAS,KAAK,iBAAiB,WAAW,EAAE,OAAO,QAChD,SAAA,EACA,SAAS,SAAS,IACjB,YACA;AAAA,MACJ,WAAW,OAAO;AAAA,IAAA;AAGpB,QAAI,OAAO,WAAW;AACpB,UAAI;AACF,cAAM,QAAQ,MAAM,KAAK;AAAA,UACvB;AAAA,YACE,MAAM;AAAA,YACN;AAAA,YACA,UAAU;AAAA,YACV,UAAU;AAAA,UAAA;AAAA,UAEZ;AAAA,QAAA;AAGF,eAAO;AAAA,UACL,SAAS;AAAA,UACT,OAAO;AAAA,YACL,eAAe,MAAM;AAAA,YACrB,YAAY,MAAM;AAAA,YAClB,WAAW,MAAM;AAAA,UAAA;AAAA,UAEnB,aAAa;AAAA,YACX,UAAU;AAAA,YACV,UAAU;AAAA,YACV,WAAW,OAAO;AAAA,UAAA;AAAA,UAEpB,SAAS,uCAAuC,gBAAgB,MAC9D,OAAO,SAAS,MAChB,QAAQ,CAAC,CAAC;AAAA,cAAqB,MAAM,aAAa;AAAA,QAAA;AAAA,MAExD,SAAS,OAAO;AACd,cAAM,eACJ,iBAAiB,QACb,MAAM,UACN;AACN,cAAM,IAAI,MAAM,4BAA4B,YAAY,EAAE;AAAA,MAC5D;AAAA,IACF;AAEA,QAAI;AACF,YAAM,SAAS,MAAM,KAAK;AAAA,QACxB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO;AAAA,MAAA;AAET,aAAO,KAAK,wBAAwB,QAAQ,OAAO;AAAA,IACrD,SAAS,OAAO;AACd,YAAM,eACJ,iBAAiB,QACb,MAAM,UACN;AACN,YAAM,IAAI,MAAM,uBAAuB,YAAY,EAAE;AAAA,IACvD;AAAA,EACF;AAAA,EAEQ,cACN,QACM;AACN,QAAI,CAAC,OAAO,cAAc,OAAO,WAAW,KAAA,MAAW,IAAI;AACzD,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAAA,IAEJ;AAEA,QAAI,CAAC,OAAO,YAAY,OAAO,SAAS,KAAA,MAAW,IAAI;AACrD,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAAA,IAEJ;AAAA,EACF;AAAA,EAEQ,gBAAgB,QAAsB;AAC5C,QAAI,OAAO,WAAW,GAAG;AACvB,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAAA,IAEJ;AAEA,QAAI,OAAO,SAAS,KAAK,OAAO,oBAAoB;AAClD,YAAM,YAAY,KAAK,MAAM,KAAK,OAAO,qBAAqB,IAAI;AAClE,YAAM,eAAe,KAAK,MAAM,OAAO,SAAS,IAAI;AACpD,YAAM,IAAI;AAAA,QACR,yCAAyC,YAAY,WAAW,SAAS;AAAA,MAAA;AAAA,IAE7E;AAEA,QAAI,OAAO,SAAS,KAAK,OAAO,gBAAgB;AAC9C,YAAM,IAAI;AAAA,QACR,gCAAgC,OAAO,MAAM;AAAA,MAAA;AAAA,IAEjD;AAEA,QACE,OAAO,SAAS,QAAQ,GAAG,KAAK,IAAI,OAAO,QAAQ,GAAG,CAAC,EAAE,KAAA,MAAW,IACpE;AACA,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAAA,IAEJ;AAEA,UAAM,aAAa,OAAO,SAAS,MAAM;AACzC,UAAM,mBAAmB;AACzB,UAAM,oBACJ,iBAAiB,KAAK,UAAU,KAChC,WAAW,QAAQ,YAAY,EAAE,EAAE,KAAA,EAAO,SAAS;AAErD,QAAI,mBAAmB;AACrB,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAAA,IAEJ;AAAA,EACF;AAAA,EAEA,MAAc,mBACZ,QACA,UACA,UACA,SACA,WACqE;AACrE,UAAM,kBAAkB;AAAA,MACtB,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGF,QAAI,WAAW;AACb,YAAM,iBAAiB,IAAI,QAAe,CAAC,GAAG,WAAW;AACvD;AAAA,UACE,MAAM,OAAO,IAAI,MAAM,+BAA+B,SAAS,IAAI,CAAC;AAAA,UACpE;AAAA,QAAA;AAAA,MAEJ,CAAC;AAED,aAAO,QAAQ,KAAK;AAAA,QAClB,KAAK,iBAAiB,SAAS,iBAAiB,OAAO;AAAA,QACvD;AAAA,MAAA,CACD;AAAA,IACH;AAEA,WAAO,KAAK,iBAAiB,SAAS,iBAAiB,OAAO;AAAA,EAChE;AAAA,EAEQ,wBACN,QACA,SACQ;AACR,QAAI,OAAO,aAAa,CAAC,OAAO,OAAO;AACrC,YAAM,UACJ,OAAO,aAAa,YAAa,OAAO,OAAe;AACzD,YAAM,UAAU,QAAQ,WAAW;AACnC,YAAM,SAAS,UACX,8CAA8C,OAAO,YAAY,OAAO,KACxE;AACJ,aAAO;AAAA;AAAA,kBACJ,OAAO,OAAe,aACzB;AAAA,YAAe,WAAW,KAAK,GAC7B,SAAS;AAAA,oBAAuB,MAAM,KAAK,EAC7C;AAAA;AAAA;AAAA,IACF;AAEA,QAAI,CAAC,OAAO,SAAS,CAAC,OAAO,WAAW;AACtC,aAAO;AAAA;AAAA,kBACJ,OAAO,OAAe,aACzB;AAAA;AAAA;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEF;"}
|