@thyme-sh/sdk 0.2.0 → 0.3.1
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/index.d.ts +135 -75
- package/dist/index.js +98 -37
- package/dist/index.js.map +1 -1
- package/package.json +11 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,87 +1,82 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { PublicClient, Address, Hex } from 'viem';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
interface ThymeContext<TArgs> {
|
|
8
|
-
/** User-provided arguments validated against schema */
|
|
9
|
-
args: TArgs;
|
|
10
|
-
/** Viem public client for reading blockchain data */
|
|
11
|
-
client: PublicClient;
|
|
4
|
+
interface CompressResult {
|
|
5
|
+
zipBuffer: Uint8Array;
|
|
6
|
+
checksum: string;
|
|
12
7
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
interface Call {
|
|
17
|
-
/** Target contract address */
|
|
18
|
-
to: Address;
|
|
19
|
-
/** Encoded function call data */
|
|
20
|
-
data: Hex;
|
|
8
|
+
interface DecompressResult {
|
|
9
|
+
source: string;
|
|
10
|
+
bundle: string;
|
|
21
11
|
}
|
|
22
12
|
/**
|
|
23
|
-
*
|
|
13
|
+
* Compress source and bundle into a ZIP archive
|
|
14
|
+
* Uses fflate for fast, modern compression
|
|
15
|
+
* Uses SHA-256 for cryptographically secure checksum
|
|
24
16
|
*/
|
|
25
|
-
|
|
26
|
-
canExec: true;
|
|
27
|
-
/** Array of calls to execute on-chain */
|
|
28
|
-
calls: Call[];
|
|
29
|
-
}
|
|
17
|
+
declare function compressTask(source: string, bundle: string): CompressResult;
|
|
30
18
|
/**
|
|
31
|
-
*
|
|
19
|
+
* Decompress ZIP archive and extract source and bundle files
|
|
20
|
+
* Uses fflate for fast decompression
|
|
21
|
+
* Includes ZIP bomb protection
|
|
32
22
|
*/
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
/** Reason why execution should not proceed */
|
|
36
|
-
message: string;
|
|
37
|
-
}
|
|
23
|
+
declare function decompressTask(zipBuffer: Uint8Array | ArrayBuffer): DecompressResult;
|
|
24
|
+
|
|
38
25
|
/**
|
|
39
|
-
*
|
|
26
|
+
* Log entry with type and message
|
|
40
27
|
*/
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
*/
|
|
45
|
-
interface TaskDefinition<TSchema extends z.ZodType> {
|
|
46
|
-
/** Zod schema for validating task arguments */
|
|
47
|
-
schema: TSchema;
|
|
48
|
-
/** Main execution function */
|
|
49
|
-
run: (ctx: ThymeContext<z.infer<TSchema>>) => Promise<TaskResult>;
|
|
28
|
+
interface LogEntry {
|
|
29
|
+
type: 'info' | 'warn' | 'error';
|
|
30
|
+
message: string;
|
|
50
31
|
}
|
|
51
|
-
|
|
52
32
|
/**
|
|
53
|
-
*
|
|
33
|
+
* Logger for Thyme tasks
|
|
34
|
+
*
|
|
35
|
+
* Use this logger to output messages that will be captured and displayed
|
|
36
|
+
* in the Thyme dashboard. Regular console.log calls will not be captured.
|
|
54
37
|
*
|
|
55
38
|
* @example
|
|
56
39
|
* ```typescript
|
|
57
|
-
* import { defineTask, z } from '@thyme-sh/sdk'
|
|
58
|
-
* import { encodeFunctionData } from 'viem'
|
|
59
|
-
*
|
|
60
|
-
* const abi = [
|
|
61
|
-
* 'function transfer(address to, uint256 amount) returns (bool)',
|
|
62
|
-
* ] as const
|
|
63
|
-
*
|
|
64
40
|
* export default defineTask({
|
|
65
|
-
* schema: z.object({
|
|
66
|
-
* targetAddress: z.address(),
|
|
67
|
-
* }),
|
|
41
|
+
* schema: z.object({ ... }),
|
|
68
42
|
* async run(ctx) {
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* data: encodeFunctionData({
|
|
74
|
-
* abi,
|
|
75
|
-
* functionName: 'transfer',
|
|
76
|
-
* args: [recipientAddress, 1000n],
|
|
77
|
-
* }),
|
|
78
|
-
* }]
|
|
79
|
-
* }
|
|
43
|
+
* ctx.logger.info('Starting task execution')
|
|
44
|
+
* ctx.logger.warn('Low balance detected')
|
|
45
|
+
* ctx.logger.error('Failed to fetch price')
|
|
46
|
+
* return { canExec: false, message: 'Error occurred' }
|
|
80
47
|
* }
|
|
81
48
|
* })
|
|
82
49
|
* ```
|
|
83
50
|
*/
|
|
84
|
-
declare
|
|
51
|
+
declare class Logger {
|
|
52
|
+
private logs;
|
|
53
|
+
private static readonly LOG_PREFIX;
|
|
54
|
+
/**
|
|
55
|
+
* Log an info message
|
|
56
|
+
*/
|
|
57
|
+
info(message: string): void;
|
|
58
|
+
/**
|
|
59
|
+
* Log a warning message
|
|
60
|
+
*/
|
|
61
|
+
warn(message: string): void;
|
|
62
|
+
/**
|
|
63
|
+
* Log an error message
|
|
64
|
+
*/
|
|
65
|
+
error(message: string): void;
|
|
66
|
+
private log;
|
|
67
|
+
/**
|
|
68
|
+
* Get all collected logs
|
|
69
|
+
*/
|
|
70
|
+
getLogs(): LogEntry[];
|
|
71
|
+
/**
|
|
72
|
+
* Clear all collected logs
|
|
73
|
+
*/
|
|
74
|
+
clear(): void;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Create a new logger instance
|
|
78
|
+
*/
|
|
79
|
+
declare function createLogger(): Logger;
|
|
85
80
|
|
|
86
81
|
/**
|
|
87
82
|
* Extended Zod with Ethereum address validation
|
|
@@ -288,23 +283,88 @@ declare const zodExtended: {
|
|
|
288
283
|
*/
|
|
289
284
|
type InferSchema<T extends z.ZodType> = z.infer<T>;
|
|
290
285
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
286
|
+
/**
|
|
287
|
+
* Context provided to task execution
|
|
288
|
+
*/
|
|
289
|
+
interface ThymeContext<TArgs> {
|
|
290
|
+
/** User-provided arguments validated against schema */
|
|
291
|
+
args: TArgs;
|
|
292
|
+
/** Viem public client for reading blockchain data */
|
|
293
|
+
client: PublicClient;
|
|
294
|
+
/** Logger for outputting messages to the Thyme dashboard */
|
|
295
|
+
logger: Logger;
|
|
294
296
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
297
|
+
/**
|
|
298
|
+
* A call to be executed on-chain
|
|
299
|
+
*/
|
|
300
|
+
interface Call {
|
|
301
|
+
/** Target contract address */
|
|
302
|
+
to: Address;
|
|
303
|
+
/** Encoded function call data */
|
|
304
|
+
data: Hex;
|
|
298
305
|
}
|
|
299
306
|
/**
|
|
300
|
-
*
|
|
301
|
-
* Uses fflate for fast, modern compression
|
|
307
|
+
* Result when task determines execution should proceed
|
|
302
308
|
*/
|
|
303
|
-
|
|
309
|
+
interface SuccessResult {
|
|
310
|
+
canExec: true;
|
|
311
|
+
/** Array of calls to execute on-chain */
|
|
312
|
+
calls: Call[];
|
|
313
|
+
}
|
|
304
314
|
/**
|
|
305
|
-
*
|
|
306
|
-
* Uses fflate for fast decompression
|
|
315
|
+
* Result when task determines execution should not proceed
|
|
307
316
|
*/
|
|
308
|
-
|
|
317
|
+
interface FailResult {
|
|
318
|
+
canExec: false;
|
|
319
|
+
/** Reason why execution should not proceed */
|
|
320
|
+
message: string;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Result returned from task execution
|
|
324
|
+
*/
|
|
325
|
+
type TaskResult = SuccessResult | FailResult;
|
|
326
|
+
/**
|
|
327
|
+
* Task definition with schema and execution logic
|
|
328
|
+
*/
|
|
329
|
+
interface TaskDefinition<TSchema extends z.ZodType> {
|
|
330
|
+
/** Zod schema for validating task arguments */
|
|
331
|
+
schema: TSchema;
|
|
332
|
+
/** Main execution function */
|
|
333
|
+
run: (ctx: ThymeContext<z.infer<TSchema>>) => Promise<TaskResult>;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Define a Web3 automation task
|
|
338
|
+
*
|
|
339
|
+
* @example
|
|
340
|
+
* ```typescript
|
|
341
|
+
* import { defineTask, z } from '@thyme-sh/sdk'
|
|
342
|
+
* import { encodeFunctionData } from 'viem'
|
|
343
|
+
*
|
|
344
|
+
* const abi = [
|
|
345
|
+
* 'function transfer(address to, uint256 amount) returns (bool)',
|
|
346
|
+
* ] as const
|
|
347
|
+
*
|
|
348
|
+
* export default defineTask({
|
|
349
|
+
* schema: z.object({
|
|
350
|
+
* targetAddress: z.address(),
|
|
351
|
+
* }),
|
|
352
|
+
* async run(ctx) {
|
|
353
|
+
* return {
|
|
354
|
+
* canExec: true,
|
|
355
|
+
* calls: [{
|
|
356
|
+
* to: ctx.args.targetAddress,
|
|
357
|
+
* data: encodeFunctionData({
|
|
358
|
+
* abi,
|
|
359
|
+
* functionName: 'transfer',
|
|
360
|
+
* args: [recipientAddress, 1000n],
|
|
361
|
+
* }),
|
|
362
|
+
* }]
|
|
363
|
+
* }
|
|
364
|
+
* }
|
|
365
|
+
* })
|
|
366
|
+
* ```
|
|
367
|
+
*/
|
|
368
|
+
declare function defineTask<TSchema extends z.ZodType>(definition: TaskDefinition<TSchema>): TaskDefinition<TSchema>;
|
|
309
369
|
|
|
310
|
-
export { type Call, type CompressResult, type DecompressResult, type FailResult, type InferSchema, type SuccessResult, type TaskDefinition, type TaskResult, type ThymeContext, compressTask, decompressTask, defineTask, zodExtended as z };
|
|
370
|
+
export { type Call, type CompressResult, type DecompressResult, type FailResult, type InferSchema, type LogEntry, Logger, type SuccessResult, type TaskDefinition, type TaskResult, type ThymeContext, compressTask, createLogger, decompressTask, defineTask, zodExtended as z };
|
package/dist/index.js
CHANGED
|
@@ -1,33 +1,11 @@
|
|
|
1
|
-
// src/task.ts
|
|
2
|
-
function defineTask(definition) {
|
|
3
|
-
return definition;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
// src/schema.ts
|
|
7
|
-
import { getAddress, isAddress } from "viem";
|
|
8
|
-
import { z } from "zod";
|
|
9
|
-
var zodExtended = {
|
|
10
|
-
...z,
|
|
11
|
-
/**
|
|
12
|
-
* Validates an Ethereum address and returns viem's Address type
|
|
13
|
-
* Accepts both checksummed and non-checksummed addresses
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* ```typescript
|
|
17
|
-
* import { zodExtended as z } from '@thyme-sh/sdk'
|
|
18
|
-
*
|
|
19
|
-
* const schema = z.object({
|
|
20
|
-
* targetAddress: z.address(),
|
|
21
|
-
* })
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
address: () => z.string().refine((val) => isAddress(val), {
|
|
25
|
-
message: "Invalid Ethereum address"
|
|
26
|
-
}).transform((val) => getAddress(val))
|
|
27
|
-
};
|
|
28
|
-
|
|
29
1
|
// src/archive.ts
|
|
2
|
+
import { createHash } from "crypto";
|
|
30
3
|
import { strFromU8, strToU8, unzipSync, zipSync } from "fflate";
|
|
4
|
+
var MAX_ZIP_SIZE = 10 * 1024 * 1024;
|
|
5
|
+
var MAX_DECOMPRESSED_SIZE = 50 * 1024 * 1024;
|
|
6
|
+
function calculateSha256(data) {
|
|
7
|
+
return createHash("sha256").update(data).digest("hex");
|
|
8
|
+
}
|
|
31
9
|
function compressTask(source, bundle) {
|
|
32
10
|
const files = {
|
|
33
11
|
"source.ts": strToU8(source),
|
|
@@ -37,15 +15,7 @@ function compressTask(source, bundle) {
|
|
|
37
15
|
level: 6
|
|
38
16
|
// Balanced compression
|
|
39
17
|
});
|
|
40
|
-
|
|
41
|
-
for (let i = 0; i < compressed.length; i++) {
|
|
42
|
-
const byte = compressed[i];
|
|
43
|
-
if (byte !== void 0) {
|
|
44
|
-
hash = (hash << 5) - hash + byte;
|
|
45
|
-
hash = hash & hash;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
const checksum = Math.abs(hash).toString(16);
|
|
18
|
+
const checksum = calculateSha256(compressed);
|
|
49
19
|
return {
|
|
50
20
|
zipBuffer: compressed,
|
|
51
21
|
checksum
|
|
@@ -53,7 +23,24 @@ function compressTask(source, bundle) {
|
|
|
53
23
|
}
|
|
54
24
|
function decompressTask(zipBuffer) {
|
|
55
25
|
const uint8Array = zipBuffer instanceof ArrayBuffer ? new Uint8Array(zipBuffer) : zipBuffer;
|
|
26
|
+
if (uint8Array.length > MAX_ZIP_SIZE) {
|
|
27
|
+
throw new Error(
|
|
28
|
+
`ZIP file too large: ${uint8Array.length} bytes (max: ${MAX_ZIP_SIZE})`
|
|
29
|
+
);
|
|
30
|
+
}
|
|
56
31
|
const decompressed = unzipSync(uint8Array);
|
|
32
|
+
let totalDecompressedSize = 0;
|
|
33
|
+
for (const key of Object.keys(decompressed)) {
|
|
34
|
+
const file = decompressed[key];
|
|
35
|
+
if (file) {
|
|
36
|
+
totalDecompressedSize += file.length;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (totalDecompressedSize > MAX_DECOMPRESSED_SIZE) {
|
|
40
|
+
throw new Error(
|
|
41
|
+
`Decompressed content too large: ${totalDecompressedSize} bytes (max: ${MAX_DECOMPRESSED_SIZE})`
|
|
42
|
+
);
|
|
43
|
+
}
|
|
57
44
|
const sourceBytes = decompressed["source.ts"];
|
|
58
45
|
const bundleBytes = decompressed["bundle.js"];
|
|
59
46
|
if (!sourceBytes) {
|
|
@@ -69,8 +56,82 @@ function decompressTask(zipBuffer) {
|
|
|
69
56
|
bundle
|
|
70
57
|
};
|
|
71
58
|
}
|
|
59
|
+
|
|
60
|
+
// src/logger.ts
|
|
61
|
+
var Logger = class _Logger {
|
|
62
|
+
logs = [];
|
|
63
|
+
static LOG_PREFIX = "__THYME_LOG__";
|
|
64
|
+
/**
|
|
65
|
+
* Log an info message
|
|
66
|
+
*/
|
|
67
|
+
info(message) {
|
|
68
|
+
this.log("info", message);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Log a warning message
|
|
72
|
+
*/
|
|
73
|
+
warn(message) {
|
|
74
|
+
this.log("warn", message);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Log an error message
|
|
78
|
+
*/
|
|
79
|
+
error(message) {
|
|
80
|
+
this.log("error", message);
|
|
81
|
+
}
|
|
82
|
+
log(type, message) {
|
|
83
|
+
const entry = { type, message };
|
|
84
|
+
this.logs.push(entry);
|
|
85
|
+
console.log(`${_Logger.LOG_PREFIX}${JSON.stringify(entry)}`);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get all collected logs
|
|
89
|
+
*/
|
|
90
|
+
getLogs() {
|
|
91
|
+
return [...this.logs];
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Clear all collected logs
|
|
95
|
+
*/
|
|
96
|
+
clear() {
|
|
97
|
+
this.logs = [];
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
function createLogger() {
|
|
101
|
+
return new Logger();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// src/schema.ts
|
|
105
|
+
import { getAddress, isAddress } from "viem";
|
|
106
|
+
import { z } from "zod";
|
|
107
|
+
var zodExtended = {
|
|
108
|
+
...z,
|
|
109
|
+
/**
|
|
110
|
+
* Validates an Ethereum address and returns viem's Address type
|
|
111
|
+
* Accepts both checksummed and non-checksummed addresses
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```typescript
|
|
115
|
+
* import { zodExtended as z } from '@thyme-sh/sdk'
|
|
116
|
+
*
|
|
117
|
+
* const schema = z.object({
|
|
118
|
+
* targetAddress: z.address(),
|
|
119
|
+
* })
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
address: () => z.string().refine((val) => isAddress(val), {
|
|
123
|
+
message: "Invalid Ethereum address"
|
|
124
|
+
}).transform((val) => getAddress(val))
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// src/task.ts
|
|
128
|
+
function defineTask(definition) {
|
|
129
|
+
return definition;
|
|
130
|
+
}
|
|
72
131
|
export {
|
|
132
|
+
Logger,
|
|
73
133
|
compressTask,
|
|
134
|
+
createLogger,
|
|
74
135
|
decompressTask,
|
|
75
136
|
defineTask,
|
|
76
137
|
zodExtended as z
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/
|
|
1
|
+
{"version":3,"sources":["../src/archive.ts","../src/logger.ts","../src/schema.ts","../src/task.ts"],"sourcesContent":["import { createHash } from 'node:crypto'\nimport { strFromU8, strToU8, unzipSync, zipSync } from 'fflate'\n\nexport interface CompressResult {\n\tzipBuffer: Uint8Array\n\tchecksum: string\n}\n\nexport interface DecompressResult {\n\tsource: string\n\tbundle: string\n}\n\n// Maximum sizes for ZIP bomb protection\nconst MAX_ZIP_SIZE = 10 * 1024 * 1024 // 10MB compressed\nconst MAX_DECOMPRESSED_SIZE = 50 * 1024 * 1024 // 50MB decompressed\n\n/**\n * Calculate SHA-256 checksum of data\n */\nfunction calculateSha256(data: Uint8Array): string {\n\treturn createHash('sha256').update(data).digest('hex')\n}\n\n/**\n * Compress source and bundle into a ZIP archive\n * Uses fflate for fast, modern compression\n * Uses SHA-256 for cryptographically secure checksum\n */\nexport function compressTask(source: string, bundle: string): CompressResult {\n\t// Create ZIP archive with both files\n\tconst files = {\n\t\t'source.ts': strToU8(source),\n\t\t'bundle.js': strToU8(bundle),\n\t}\n\n\tconst compressed = zipSync(files, {\n\t\tlevel: 6, // Balanced compression\n\t})\n\n\t// Calculate SHA-256 checksum\n\tconst checksum = calculateSha256(compressed)\n\n\treturn {\n\t\tzipBuffer: compressed,\n\t\tchecksum,\n\t}\n}\n\n/**\n * Decompress ZIP archive and extract source and bundle files\n * Uses fflate for fast decompression\n * Includes ZIP bomb protection\n */\nexport function decompressTask(\n\tzipBuffer: Uint8Array | ArrayBuffer,\n): DecompressResult {\n\t// Convert ArrayBuffer to Uint8Array if needed\n\tconst uint8Array =\n\t\tzipBuffer instanceof ArrayBuffer ? new Uint8Array(zipBuffer) : zipBuffer\n\n\t// ZIP bomb protection: check compressed size\n\tif (uint8Array.length > MAX_ZIP_SIZE) {\n\t\tthrow new Error(\n\t\t\t`ZIP file too large: ${uint8Array.length} bytes (max: ${MAX_ZIP_SIZE})`,\n\t\t)\n\t}\n\n\t// Decompress ZIP\n\tconst decompressed = unzipSync(uint8Array)\n\n\t// ZIP bomb protection: check total decompressed size\n\tlet totalDecompressedSize = 0\n\tfor (const key of Object.keys(decompressed)) {\n\t\tconst file = decompressed[key]\n\t\tif (file) {\n\t\t\ttotalDecompressedSize += file.length\n\t\t}\n\t}\n\n\tif (totalDecompressedSize > MAX_DECOMPRESSED_SIZE) {\n\t\tthrow new Error(\n\t\t\t`Decompressed content too large: ${totalDecompressedSize} bytes (max: ${MAX_DECOMPRESSED_SIZE})`,\n\t\t)\n\t}\n\n\t// Extract files\n\tconst sourceBytes = decompressed['source.ts']\n\tconst bundleBytes = decompressed['bundle.js']\n\n\tif (!sourceBytes) {\n\t\tthrow new Error('source.ts not found in ZIP archive')\n\t}\n\n\tif (!bundleBytes) {\n\t\tthrow new Error('bundle.js not found in ZIP archive')\n\t}\n\n\t// Convert bytes to strings\n\tconst source = strFromU8(sourceBytes)\n\tconst bundle = strFromU8(bundleBytes)\n\n\treturn {\n\t\tsource,\n\t\tbundle,\n\t}\n}\n","// Declare console for environments that don't have DOM types\ndeclare const console: {\n\tlog: (...args: unknown[]) => void\n}\n\n/**\n * Log entry with type and message\n */\nexport interface LogEntry {\n\ttype: 'info' | 'warn' | 'error'\n\tmessage: string\n}\n\n/**\n * Logger for Thyme tasks\n *\n * Use this logger to output messages that will be captured and displayed\n * in the Thyme dashboard. Regular console.log calls will not be captured.\n *\n * @example\n * ```typescript\n * export default defineTask({\n * schema: z.object({ ... }),\n * async run(ctx) {\n * ctx.logger.info('Starting task execution')\n * ctx.logger.warn('Low balance detected')\n * ctx.logger.error('Failed to fetch price')\n * return { canExec: false, message: 'Error occurred' }\n * }\n * })\n * ```\n */\nexport class Logger {\n\tprivate logs: LogEntry[] = []\n\tprivate static readonly LOG_PREFIX = '__THYME_LOG__'\n\n\t/**\n\t * Log an info message\n\t */\n\tinfo(message: string): void {\n\t\tthis.log('info', message)\n\t}\n\n\t/**\n\t * Log a warning message\n\t */\n\twarn(message: string): void {\n\t\tthis.log('warn', message)\n\t}\n\n\t/**\n\t * Log an error message\n\t */\n\terror(message: string): void {\n\t\tthis.log('error', message)\n\t}\n\n\tprivate log(type: LogEntry['type'], message: string): void {\n\t\tconst entry: LogEntry = { type, message }\n\t\tthis.logs.push(entry)\n\t\t// Output with special prefix so it can be captured by the runner\n\t\tconsole.log(`${Logger.LOG_PREFIX}${JSON.stringify(entry)}`)\n\t}\n\n\t/**\n\t * Get all collected logs\n\t */\n\tgetLogs(): LogEntry[] {\n\t\treturn [...this.logs]\n\t}\n\n\t/**\n\t * Clear all collected logs\n\t */\n\tclear(): void {\n\t\tthis.logs = []\n\t}\n}\n\n/**\n * Create a new logger instance\n */\nexport function createLogger(): Logger {\n\treturn new Logger()\n}\n","import { type Address, getAddress, isAddress } from 'viem'\nimport { z } from 'zod'\n\n/**\n * Extended Zod with Ethereum address validation\n */\nexport const zodExtended = {\n\t...z,\n\t/**\n\t * Validates an Ethereum address and returns viem's Address type\n\t * Accepts both checksummed and non-checksummed addresses\n\t *\n\t * @example\n\t * ```typescript\n\t * import { zodExtended as z } from '@thyme-sh/sdk'\n\t *\n\t * const schema = z.object({\n\t * targetAddress: z.address(),\n\t * })\n\t * ```\n\t */\n\taddress: () =>\n\t\tz\n\t\t\t.string()\n\t\t\t.refine((val): val is Address => isAddress(val), {\n\t\t\t\tmessage: 'Invalid Ethereum address',\n\t\t\t})\n\t\t\t.transform((val) => getAddress(val)),\n}\n\n/**\n * Type helper to infer the schema type\n */\nexport type InferSchema<T extends z.ZodType> = z.infer<T>\n","import type { z } from 'zod'\nimport type { TaskDefinition } from './types'\n\n/**\n * Define a Web3 automation task\n *\n * @example\n * ```typescript\n * import { defineTask, z } from '@thyme-sh/sdk'\n * import { encodeFunctionData } from 'viem'\n *\n * const abi = [\n * 'function transfer(address to, uint256 amount) returns (bool)',\n * ] as const\n *\n * export default defineTask({\n * schema: z.object({\n * targetAddress: z.address(),\n * }),\n * async run(ctx) {\n * return {\n * canExec: true,\n * calls: [{\n * to: ctx.args.targetAddress,\n * data: encodeFunctionData({\n * abi,\n * functionName: 'transfer',\n * args: [recipientAddress, 1000n],\n * }),\n * }]\n * }\n * }\n * })\n * ```\n */\nexport function defineTask<TSchema extends z.ZodType>(\n\tdefinition: TaskDefinition<TSchema>,\n): TaskDefinition<TSchema> {\n\treturn definition\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thyme-sh/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "SDK for authoring Web3 automation tasks",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/bnhpio/thyme-sdk.git",
|
|
8
|
+
"directory": "packages/sdk"
|
|
9
|
+
},
|
|
5
10
|
"type": "module",
|
|
6
11
|
"main": "./dist/index.js",
|
|
7
12
|
"types": "./dist/index.d.ts",
|
|
@@ -28,12 +33,17 @@
|
|
|
28
33
|
],
|
|
29
34
|
"author": "",
|
|
30
35
|
"license": "MIT",
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public",
|
|
38
|
+
"provenance": true
|
|
39
|
+
},
|
|
31
40
|
"dependencies": {
|
|
32
41
|
"fflate": "^0.8.2",
|
|
33
42
|
"viem": "^2.21.54",
|
|
34
43
|
"zod": "^3.24.1"
|
|
35
44
|
},
|
|
36
45
|
"devDependencies": {
|
|
46
|
+
"@types/node": "^22.10.2",
|
|
37
47
|
"tsup": "^8.3.5",
|
|
38
48
|
"typescript": "^5.7.2"
|
|
39
49
|
}
|