@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 CHANGED
@@ -1,87 +1,82 @@
1
1
  import { z } from 'zod';
2
2
  import { PublicClient, Address, Hex } from 'viem';
3
3
 
4
- /**
5
- * Context provided to task execution
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
- * A call to be executed on-chain
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
- * Result when task determines execution should proceed
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
- interface SuccessResult {
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
- * Result when task determines execution should not proceed
19
+ * Decompress ZIP archive and extract source and bundle files
20
+ * Uses fflate for fast decompression
21
+ * Includes ZIP bomb protection
32
22
  */
33
- interface FailResult {
34
- canExec: false;
35
- /** Reason why execution should not proceed */
36
- message: string;
37
- }
23
+ declare function decompressTask(zipBuffer: Uint8Array | ArrayBuffer): DecompressResult;
24
+
38
25
  /**
39
- * Result returned from task execution
26
+ * Log entry with type and message
40
27
  */
41
- type TaskResult = SuccessResult | FailResult;
42
- /**
43
- * Task definition with schema and execution logic
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
- * Define a Web3 automation task
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
- * return {
70
- * canExec: true,
71
- * calls: [{
72
- * to: ctx.args.targetAddress,
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 function defineTask<TSchema extends z.ZodType>(definition: TaskDefinition<TSchema>): TaskDefinition<TSchema>;
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
- interface CompressResult {
292
- zipBuffer: Uint8Array;
293
- checksum: string;
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
- interface DecompressResult {
296
- source: string;
297
- bundle: string;
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
- * Compress source and bundle into a ZIP archive
301
- * Uses fflate for fast, modern compression
307
+ * Result when task determines execution should proceed
302
308
  */
303
- declare function compressTask(source: string, bundle: string): CompressResult;
309
+ interface SuccessResult {
310
+ canExec: true;
311
+ /** Array of calls to execute on-chain */
312
+ calls: Call[];
313
+ }
304
314
  /**
305
- * Decompress ZIP archive and extract source and bundle files
306
- * Uses fflate for fast decompression
315
+ * Result when task determines execution should not proceed
307
316
  */
308
- declare function decompressTask(zipBuffer: Uint8Array | ArrayBuffer): DecompressResult;
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
- let hash = 0;
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/task.ts","../src/schema.ts","../src/archive.ts"],"sourcesContent":["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","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 { 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/**\n * Compress source and bundle into a ZIP archive\n * Uses fflate for fast, modern compression\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 checksum (simple hash for now)\n\tlet hash = 0\n\tfor (let i = 0; i < compressed.length; i++) {\n\t\tconst byte = compressed[i]\n\t\tif (byte !== undefined) {\n\t\t\thash = (hash << 5) - hash + byte\n\t\t\thash = hash & hash // Convert to 32bit integer\n\t\t}\n\t}\n\tconst checksum = Math.abs(hash).toString(16)\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 */\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// Decompress ZIP\n\tconst decompressed = unzipSync(uint8Array)\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"],"mappings":";AAmCO,SAAS,WACf,YAC0B;AAC1B,SAAO;AACR;;;ACvCA,SAAuB,YAAY,iBAAiB;AACpD,SAAS,SAAS;AAKX,IAAM,cAAc;AAAA,EAC1B,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcH,SAAS,MACR,EACE,OAAO,EACP,OAAO,CAAC,QAAwB,UAAU,GAAG,GAAG;AAAA,IAChD,SAAS;AAAA,EACV,CAAC,EACA,UAAU,CAAC,QAAQ,WAAW,GAAG,CAAC;AACtC;;;AC5BA,SAAS,WAAW,SAAS,WAAW,eAAe;AAgBhD,SAAS,aAAa,QAAgB,QAAgC;AAE5E,QAAM,QAAQ;AAAA,IACb,aAAa,QAAQ,MAAM;AAAA,IAC3B,aAAa,QAAQ,MAAM;AAAA,EAC5B;AAEA,QAAM,aAAa,QAAQ,OAAO;AAAA,IACjC,OAAO;AAAA;AAAA,EACR,CAAC;AAGD,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC3C,UAAM,OAAO,WAAW,CAAC;AACzB,QAAI,SAAS,QAAW;AACvB,cAAQ,QAAQ,KAAK,OAAO;AAC5B,aAAO,OAAO;AAAA,IACf;AAAA,EACD;AACA,QAAM,WAAW,KAAK,IAAI,IAAI,EAAE,SAAS,EAAE;AAE3C,SAAO;AAAA,IACN,WAAW;AAAA,IACX;AAAA,EACD;AACD;AAMO,SAAS,eACf,WACmB;AAEnB,QAAM,aACL,qBAAqB,cAAc,IAAI,WAAW,SAAS,IAAI;AAGhE,QAAM,eAAe,UAAU,UAAU;AAGzC,QAAM,cAAc,aAAa,WAAW;AAC5C,QAAM,cAAc,aAAa,WAAW;AAE5C,MAAI,CAAC,aAAa;AACjB,UAAM,IAAI,MAAM,oCAAoC;AAAA,EACrD;AAEA,MAAI,CAAC,aAAa;AACjB,UAAM,IAAI,MAAM,oCAAoC;AAAA,EACrD;AAGA,QAAM,SAAS,UAAU,WAAW;AACpC,QAAM,SAAS,UAAU,WAAW;AAEpC,SAAO;AAAA,IACN;AAAA,IACA;AAAA,EACD;AACD;","names":[]}
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.2.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
  }