@dipansrimany/mlink-sdk 0.3.0 → 0.4.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.
@@ -1,6 +1,6 @@
1
1
  import { Router } from 'express';
2
- import { A as Action } from '../builders-CN5ijFpW.mjs';
3
- import '../types-CAnUIaVe.mjs';
2
+ import { A as Action } from '../builders-pKj4NiIj.mjs';
3
+ import '../types-DD9rJ58Y.mjs';
4
4
 
5
5
  declare function createExpressHandler(action: Action, RouterClass: new () => Router): Router;
6
6
 
@@ -1,6 +1,6 @@
1
1
  import { Router } from 'express';
2
- import { A as Action } from '../builders-CJNt88dM.js';
3
- import '../types-CAnUIaVe.js';
2
+ import { A as Action } from '../builders-CLqoe2Kx.js';
3
+ import '../types-DD9rJ58Y.js';
4
4
 
5
5
  declare function createExpressHandler(action: Action, RouterClass: new () => Router): Router;
6
6
 
@@ -12,18 +12,113 @@ var ActionButtonSchema = zod.z.object({
12
12
  placeholder: zod.z.string().optional(),
13
13
  disabled: zod.z.boolean().optional()
14
14
  });
15
- zod.z.object({
16
- title: zod.z.string().min(1).max(100),
17
- icon: zod.z.string().url(),
18
- description: zod.z.string().min(1).max(500),
19
- actions: zod.z.array(ActionButtonSchema).min(1),
15
+ zod.z.enum([
16
+ "text",
17
+ "number",
18
+ "email",
19
+ "url",
20
+ "date",
21
+ "datetime-local",
22
+ "textarea",
23
+ "select",
24
+ "radio",
25
+ "checkbox",
26
+ "address",
27
+ "token",
28
+ "amount"
29
+ ]);
30
+ var ActionParameterOptionSchema = zod.z.object({
31
+ label: zod.z.string().min(1),
32
+ value: zod.z.string(),
33
+ selected: zod.z.boolean().optional()
34
+ });
35
+ var ActionParameterBaseSchema = zod.z.object({
36
+ name: zod.z.string().min(1).max(50),
37
+ label: zod.z.string().max(100).optional(),
38
+ required: zod.z.boolean().optional(),
39
+ pattern: zod.z.string().optional(),
40
+ patternDescription: zod.z.string().optional(),
41
+ min: zod.z.union([zod.z.string(), zod.z.number()]).optional(),
42
+ max: zod.z.union([zod.z.string(), zod.z.number()]).optional()
43
+ });
44
+ var ActionParameterSchema = ActionParameterBaseSchema.extend({
45
+ type: zod.z.enum([
46
+ "text",
47
+ "number",
48
+ "email",
49
+ "url",
50
+ "date",
51
+ "datetime-local",
52
+ "textarea",
53
+ "address",
54
+ "token",
55
+ "amount"
56
+ ]).optional()
57
+ });
58
+ var ActionParameterSelectableSchema = ActionParameterBaseSchema.extend({
59
+ type: zod.z.enum(["select", "radio", "checkbox"]),
60
+ options: zod.z.array(ActionParameterOptionSchema).min(1)
61
+ });
62
+ var TypedActionParameterSchema = zod.z.union([
63
+ ActionParameterSelectableSchema,
64
+ ActionParameterSchema
65
+ ]);
66
+ var LinkedActionTypeSchema = zod.z.enum(["transaction", "post", "external-link"]);
67
+ var LinkedActionSchema = zod.z.object({
68
+ type: LinkedActionTypeSchema.optional(),
69
+ href: zod.z.string().min(1),
70
+ label: zod.z.string().min(1).max(50),
20
71
  disabled: zod.z.boolean().optional(),
21
- error: zod.z.object({ message: zod.z.string() }).optional()
72
+ parameters: zod.z.array(TypedActionParameterSchema).optional()
73
+ });
74
+ var ActionLinksSchema = zod.z.object({
75
+ actions: zod.z.array(LinkedActionSchema).min(1)
76
+ });
77
+ var PostNextActionLinkSchema = zod.z.object({
78
+ type: zod.z.literal("post"),
79
+ href: zod.z.string().min(1)
80
+ });
81
+ var InlineNextActionLinkSchema = zod.z.object({
82
+ type: zod.z.literal("inline"),
83
+ action: zod.z.lazy(() => ActionMetadataSchema)
22
84
  });
85
+ var NextActionLinkSchema = zod.z.union([
86
+ PostNextActionLinkSchema,
87
+ InlineNextActionLinkSchema
88
+ ]);
89
+ var iconSchema = zod.z.string().refine(
90
+ (val) => {
91
+ if (val.startsWith("http://") || val.startsWith("https://")) return true;
92
+ if (val.startsWith("data:image/")) return true;
93
+ if (val.startsWith("/")) return true;
94
+ return false;
95
+ },
96
+ { message: "Icon must be a valid URL, base64 data URI, or relative path" }
97
+ );
98
+ var ActionMetadataSchema = zod.z.object({
99
+ type: zod.z.enum(["action", "completed"]).optional(),
100
+ title: zod.z.string().min(1).max(200),
101
+ icon: iconSchema,
102
+ description: zod.z.string().min(1).max(1e3),
103
+ label: zod.z.string().max(50).optional(),
104
+ // Legacy actions (optional)
105
+ actions: zod.z.array(ActionButtonSchema).optional(),
106
+ // Solana-style linked actions (optional)
107
+ links: ActionLinksSchema.optional(),
108
+ disabled: zod.z.boolean().optional(),
109
+ error: zod.z.object({ message: zod.z.string() }).optional()
110
+ }).refine(
111
+ (data) => {
112
+ return data.actions && data.actions.length > 0 || data.links?.actions && data.links.actions.length > 0;
113
+ },
114
+ { message: "Must have at least one action or linked action" }
115
+ );
23
116
  var TransactionRequestSchema = zod.z.object({
24
117
  account: zod.z.string().regex(addressRegex, "Invalid Ethereum address"),
25
118
  action: zod.z.string().min(1),
26
- input: zod.z.string().optional()
119
+ input: zod.z.string().optional(),
120
+ // Solana-style parameter data
121
+ data: zod.z.record(zod.z.union([zod.z.string(), zod.z.array(zod.z.string())])).optional()
27
122
  });
28
123
  var EVMTransactionSchema = zod.z.object({
29
124
  to: zod.z.string().regex(addressRegex, "Invalid to address"),
@@ -32,9 +127,21 @@ var EVMTransactionSchema = zod.z.object({
32
127
  chainId: zod.z.number().positive()
33
128
  });
34
129
  zod.z.object({
35
- transaction: EVMTransactionSchema,
36
- message: zod.z.string().optional()
37
- });
130
+ // Single transaction (legacy)
131
+ transaction: EVMTransactionSchema.optional(),
132
+ // Multiple transactions (batch)
133
+ transactions: zod.z.array(EVMTransactionSchema).optional(),
134
+ message: zod.z.string().optional(),
135
+ // Action chaining
136
+ links: zod.z.object({
137
+ next: NextActionLinkSchema.optional()
138
+ }).optional()
139
+ }).refine(
140
+ (data) => {
141
+ return data.transaction !== void 0 || data.transactions && data.transactions.length > 0;
142
+ },
143
+ { message: "Must have either transaction or transactions" }
144
+ );
38
145
  function validateTransactionRequest(data) {
39
146
  const result = TransactionRequestSchema.safeParse(data);
40
147
  if (result.success) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/validators.ts","../../src/adapters/express.ts"],"names":["z"],"mappings":";;;;;AASA,IAAM,YAAA,GAAe,qBAAA;AAGrB,IAAM,QAAA,GAAW,kBAAA;AAGV,IAAM,kBAAA,GAAqBA,MAAE,MAAA,CAAO;AAAA,EACzC,KAAA,EAAOA,MAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,IAAI,EAAE,CAAA;AAAA,EAC/B,KAAA,EAAOA,KAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EACvB,MAAMA,KAAA,CAAE,IAAA,CAAK,CAAC,QAAA,EAAU,OAAO,CAAC,CAAA;AAAA,EAChC,WAAA,EAAaA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EACjC,QAAA,EAAUA,KAAA,CAAE,OAAA,EAAQ,CAAE,QAAA;AACxB,CAAC,CAAA;AAEmCA,MAAE,MAAA,CAAO;AAAA,EAC3C,KAAA,EAAOA,MAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,IAAI,GAAG,CAAA;AAAA,EAChC,IAAA,EAAMA,KAAA,CAAE,MAAA,EAAO,CAAE,GAAA,EAAI;AAAA,EACrB,WAAA,EAAaA,MAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,IAAI,GAAG,CAAA;AAAA,EACtC,SAASA,KAAA,CAAE,KAAA,CAAM,kBAAkB,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA,EAC1C,QAAA,EAAUA,KAAA,CAAE,OAAA,EAAQ,CAAE,QAAA,EAAS;AAAA,EAC/B,KAAA,EAAOA,KAAA,CAAE,MAAA,CAAO,EAAE,OAAA,EAASA,MAAE,MAAA,EAAO,EAAG,CAAA,CAAE,QAAA;AAC3C,CAAC;AAEM,IAAM,wBAAA,GAA2BA,MAAE,MAAA,CAAO;AAAA,EAC/C,SAASA,KAAA,CAAE,MAAA,EAAO,CAAE,KAAA,CAAM,cAAc,0BAA0B,CAAA;AAAA,EAClE,MAAA,EAAQA,KAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EACxB,KAAA,EAAOA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AACpB,CAAC,CAAA;AAEM,IAAM,oBAAA,GAAuBA,MAAE,MAAA,CAAO;AAAA,EAC3C,IAAIA,KAAA,CAAE,MAAA,EAAO,CAAE,KAAA,CAAM,cAAc,oBAAoB,CAAA;AAAA,EACvD,KAAA,EAAOA,MAAE,MAAA,EAAO;AAAA,EAChB,MAAMA,KAAA,CAAE,MAAA,EAAO,CAAE,KAAA,CAAM,UAAU,kBAAkB,CAAA;AAAA,EACnD,OAAA,EAASA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AACtB,CAAC,CAAA;AAEwCA,MAAE,MAAA,CAAO;AAAA,EAChD,WAAA,EAAa,oBAAA;AAAA,EACb,OAAA,EAASA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AACtB,CAAC;AAaM,SAAS,2BACd,IAAA,EACsC;AACtC,EAAA,MAAM,MAAA,GAAS,wBAAA,CAAyB,SAAA,CAAU,IAAI,CAAA;AACtD,EAAA,IAAI,OAAO,OAAA,EAAS;AAClB,IAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,IAAA,EAAM,OAAO,IAAA,EAAK;AAAA,EAC5C;AACA,EAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,MAAA,CAAO,MAAM,OAAA,EAAQ;AACvD;;;AChEO,SAAS,oBAAA,CACd,QACA,WAAA,EACQ;AACR,EAAA,MAAM,MAAA,GAAS,IAAI,WAAA,EAAY;AAG/B,EAAA,MAAA,CAAO,GAAA,CAAI,CAAC,IAAA,EAAe,GAAA,EAAe,IAAA,KAAuB;AAC/D,IAAA,GAAA,CAAI,MAAA,CAAO,+BAA+B,GAAG,CAAA;AAC7C,IAAA,GAAA,CAAI,MAAA,CAAO,gCAAgC,oBAAoB,CAAA;AAC/D,IAAA,GAAA,CAAI,MAAA,CAAO,gCAAgC,cAAc,CAAA;AACzD,IAAA,IAAA,EAAK;AAAA,EACP,CAAC,CAAA;AAGD,EAAA,MAAA,CAAO,OAAA,CAAQ,GAAA,EAAK,CAAC,IAAA,EAAe,GAAA,KAAkB;AACpD,IAAA,GAAA,CAAI,WAAW,GAAG,CAAA;AAAA,EACpB,CAAC,CAAA;AAGD,EAAA,MAAA,CAAO,GAAA,CAAI,GAAA,EAAK,CAAC,IAAA,EAAe,GAAA,KAAkB;AAChD,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,OAAO,WAAA,EAAY;AACpC,MAAA,GAAA,CAAI,KAAK,QAAQ,CAAA;AAAA,IACnB,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,OAAA,GAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,eAAA;AACzD,MAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,EAAE,KAAA,EAAO,EAAE,OAAA,EAAQ,EAAG,CAAA;AAAA,IAC7C;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,MAAA,CAAO,IAAA,CAAK,GAAA,EAAK,OAAO,GAAA,EAAc,GAAA,KAAkB;AACtD,IAAA,IAAI;AACF,MAAA,MAAM,UAAA,GAAa,0BAAA,CAA2B,GAAA,CAAI,IAAI,CAAA;AAEtD,MAAA,IAAI,CAAC,WAAW,OAAA,EAAS;AACvB,QAAA,OAAO,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,EAAE,KAAA,EAAO,EAAE,OAAA,EAAS,UAAA,CAAW,KAAA,EAAM,EAAG,CAAA;AAAA,MACtE;AAEA,MAAA,MAAM,QAAA,GAAW,MAAM,MAAA,CAAO,aAAA,CAAc,WAAW,IAAI,CAAA;AAC3D,MAAA,GAAA,CAAI,KAAK,QAAQ,CAAA;AAAA,IACnB,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,OAAA,GAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,eAAA;AACzD,MAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,EAAE,KAAA,EAAO,EAAE,OAAA,EAAQ,EAAG,CAAA;AAAA,IAC7C;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAO,MAAA;AACT","file":"express.js","sourcesContent":["import { z } from 'zod';\nimport type {\n ActionMetadata,\n TransactionRequest,\n TransactionResponse,\n ValidationResult,\n} from './types';\n\n// Ethereum address regex\nconst addressRegex = /^0x[a-fA-F0-9]{40}$/;\n\n// Hex string regex\nconst hexRegex = /^0x[a-fA-F0-9]*$/;\n\n// Zod Schemas\nexport const ActionButtonSchema = z.object({\n label: z.string().min(1).max(50),\n value: z.string().min(1),\n type: z.enum(['button', 'input']),\n placeholder: z.string().optional(),\n disabled: z.boolean().optional(),\n});\n\nexport const ActionMetadataSchema = z.object({\n title: z.string().min(1).max(100),\n icon: z.string().url(),\n description: z.string().min(1).max(500),\n actions: z.array(ActionButtonSchema).min(1),\n disabled: z.boolean().optional(),\n error: z.object({ message: z.string() }).optional(),\n});\n\nexport const TransactionRequestSchema = z.object({\n account: z.string().regex(addressRegex, 'Invalid Ethereum address'),\n action: z.string().min(1),\n input: z.string().optional(),\n});\n\nexport const EVMTransactionSchema = z.object({\n to: z.string().regex(addressRegex, 'Invalid to address'),\n value: z.string(),\n data: z.string().regex(hexRegex, 'Invalid hex data'),\n chainId: z.number().positive(),\n});\n\nexport const TransactionResponseSchema = z.object({\n transaction: EVMTransactionSchema,\n message: z.string().optional(),\n});\n\n// Validation functions\nexport function validateActionMetadata(\n data: unknown\n): ValidationResult<ActionMetadata> {\n const result = ActionMetadataSchema.safeParse(data);\n if (result.success) {\n return { success: true, data: result.data as ActionMetadata };\n }\n return { success: false, error: result.error.message };\n}\n\nexport function validateTransactionRequest(\n data: unknown\n): ValidationResult<TransactionRequest> {\n const result = TransactionRequestSchema.safeParse(data);\n if (result.success) {\n return { success: true, data: result.data };\n }\n return { success: false, error: result.error.message };\n}\n\nexport function validateTransactionResponse(\n data: unknown\n): ValidationResult<TransactionResponse> {\n const result = TransactionResponseSchema.safeParse(data);\n if (result.success) {\n return { success: true, data: result.data as TransactionResponse };\n }\n return { success: false, error: result.error.message };\n}\n\nexport function isValidAddress(address: string): boolean {\n return addressRegex.test(address);\n}\n\nexport function isValidHex(hex: string): boolean {\n return hexRegex.test(hex);\n}\n","import type { Router, Request, Response, NextFunction } from 'express';\nimport type { Action } from '../builders';\nimport { validateTransactionRequest } from '../validators';\n\n// Create Express router\nexport function createExpressHandler(\n action: Action,\n RouterClass: new () => Router\n): Router {\n const router = new RouterClass();\n\n // CORS middleware\n router.use((_req: Request, res: Response, next: NextFunction) => {\n res.header('Access-Control-Allow-Origin', '*');\n res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.header('Access-Control-Allow-Headers', 'Content-Type');\n next();\n });\n\n // OPTIONS handler\n router.options('/', (_req: Request, res: Response) => {\n res.sendStatus(200);\n });\n\n // GET handler\n router.get('/', (_req: Request, res: Response) => {\n try {\n const metadata = action.getMetadata();\n res.json(metadata);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n res.status(500).json({ error: { message } });\n }\n });\n\n // POST handler\n router.post('/', async (req: Request, res: Response) => {\n try {\n const validation = validateTransactionRequest(req.body);\n\n if (!validation.success) {\n return res.status(400).json({ error: { message: validation.error } });\n }\n\n const response = await action.handleRequest(validation.data);\n res.json(response);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n res.status(500).json({ error: { message } });\n }\n });\n\n return router;\n}\n"]}
1
+ {"version":3,"sources":["../../src/validators.ts","../../src/adapters/express.ts"],"names":["z"],"mappings":"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","file":"express.js","sourcesContent":["import { z } from 'zod';\nimport type {\n ActionMetadata,\n TransactionRequest,\n TransactionResponse,\n LinkedAction,\n TypedActionParameter,\n ValidationResult,\n} from './types';\n\n// Ethereum address regex\nconst addressRegex = /^0x[a-fA-F0-9]{40}$/;\n\n// Hex string regex\nconst hexRegex = /^0x[a-fA-F0-9]*$/;\n\n// =============================================================================\n// LEGACY SCHEMAS (Backwards compatible)\n// =============================================================================\n\nexport const ActionButtonSchema = z.object({\n label: z.string().min(1).max(50),\n value: z.string().min(1),\n type: z.enum(['button', 'input']),\n placeholder: z.string().optional(),\n disabled: z.boolean().optional(),\n});\n\n// =============================================================================\n// SOLANA-STYLE PARAMETER SCHEMAS\n// =============================================================================\n\n/**\n * Parameter types enum\n */\nexport const ActionParameterTypeSchema = z.enum([\n 'text',\n 'number',\n 'email',\n 'url',\n 'date',\n 'datetime-local',\n 'textarea',\n 'select',\n 'radio',\n 'checkbox',\n 'address',\n 'token',\n 'amount',\n]);\n\n/**\n * Option for select/radio/checkbox\n */\nexport const ActionParameterOptionSchema = z.object({\n label: z.string().min(1),\n value: z.string(),\n selected: z.boolean().optional(),\n});\n\n/**\n * Base parameter fields\n */\nconst ActionParameterBaseSchema = z.object({\n name: z.string().min(1).max(50),\n label: z.string().max(100).optional(),\n required: z.boolean().optional(),\n pattern: z.string().optional(),\n patternDescription: z.string().optional(),\n min: z.union([z.string(), z.number()]).optional(),\n max: z.union([z.string(), z.number()]).optional(),\n});\n\n/**\n * Non-selectable parameter (text, number, etc.)\n */\nexport const ActionParameterSchema = ActionParameterBaseSchema.extend({\n type: z.enum([\n 'text', 'number', 'email', 'url', 'date', 'datetime-local',\n 'textarea', 'address', 'token', 'amount'\n ]).optional(),\n});\n\n/**\n * Selectable parameter (select, radio, checkbox)\n */\nexport const ActionParameterSelectableSchema = ActionParameterBaseSchema.extend({\n type: z.enum(['select', 'radio', 'checkbox']),\n options: z.array(ActionParameterOptionSchema).min(1),\n});\n\n/**\n * Union of all parameter types\n */\nexport const TypedActionParameterSchema = z.union([\n ActionParameterSelectableSchema,\n ActionParameterSchema,\n]);\n\n// =============================================================================\n// LINKED ACTION SCHEMAS\n// =============================================================================\n\n/**\n * Linked action type enum\n */\nexport const LinkedActionTypeSchema = z.enum(['transaction', 'post', 'external-link']);\n\n/**\n * Linked action with href template and parameters\n */\nexport const LinkedActionSchema = z.object({\n type: LinkedActionTypeSchema.optional(),\n href: z.string().min(1),\n label: z.string().min(1).max(50),\n disabled: z.boolean().optional(),\n parameters: z.array(TypedActionParameterSchema).optional(),\n});\n\n/**\n * Links section containing linked actions\n */\nexport const ActionLinksSchema = z.object({\n actions: z.array(LinkedActionSchema).min(1),\n});\n\n// =============================================================================\n// ACTION CHAINING SCHEMAS\n// =============================================================================\n\nexport const PostNextActionLinkSchema = z.object({\n type: z.literal('post'),\n href: z.string().min(1),\n});\n\nexport const InlineNextActionLinkSchema: z.ZodType<{ type: 'inline'; action: ActionMetadata }> = z.object({\n type: z.literal('inline'),\n action: z.lazy(() => ActionMetadataSchema),\n});\n\nexport const NextActionLinkSchema = z.union([\n PostNextActionLinkSchema,\n InlineNextActionLinkSchema,\n]);\n\n// =============================================================================\n// MAIN SCHEMAS (Enhanced)\n// =============================================================================\n\n/**\n * Icon can be URL or base64 data URI\n */\nconst iconSchema = z.string().refine(\n (val) => {\n // Allow URLs\n if (val.startsWith('http://') || val.startsWith('https://')) return true;\n // Allow base64 data URIs\n if (val.startsWith('data:image/')) return true;\n // Allow relative paths\n if (val.startsWith('/')) return true;\n return false;\n },\n { message: 'Icon must be a valid URL, base64 data URI, or relative path' }\n);\n\n/**\n * Enhanced ActionMetadata schema with links support\n */\nexport const ActionMetadataSchema = z.object({\n type: z.enum(['action', 'completed']).optional(),\n title: z.string().min(1).max(200),\n icon: iconSchema,\n description: z.string().min(1).max(1000),\n label: z.string().max(50).optional(),\n // Legacy actions (optional)\n actions: z.array(ActionButtonSchema).optional(),\n // Solana-style linked actions (optional)\n links: ActionLinksSchema.optional(),\n disabled: z.boolean().optional(),\n error: z.object({ message: z.string() }).optional(),\n}).refine(\n (data) => {\n // Must have either actions or links (or both)\n return (data.actions && data.actions.length > 0) ||\n (data.links?.actions && data.links.actions.length > 0);\n },\n { message: 'Must have at least one action or linked action' }\n);\n\n/**\n * Enhanced TransactionRequest with data support\n */\nexport const TransactionRequestSchema = z.object({\n account: z.string().regex(addressRegex, 'Invalid Ethereum address'),\n action: z.string().min(1),\n input: z.string().optional(),\n // Solana-style parameter data\n data: z.record(z.union([z.string(), z.array(z.string())])).optional(),\n});\n\nexport const EVMTransactionSchema = z.object({\n to: z.string().regex(addressRegex, 'Invalid to address'),\n value: z.string(),\n data: z.string().regex(hexRegex, 'Invalid hex data'),\n chainId: z.number().positive(),\n});\n\n/**\n * Enhanced TransactionResponse with multi-tx and chaining support\n */\nexport const TransactionResponseSchema = z.object({\n // Single transaction (legacy)\n transaction: EVMTransactionSchema.optional(),\n // Multiple transactions (batch)\n transactions: z.array(EVMTransactionSchema).optional(),\n message: z.string().optional(),\n // Action chaining\n links: z.object({\n next: NextActionLinkSchema.optional(),\n }).optional(),\n}).refine(\n (data) => {\n // Must have either transaction or transactions\n return data.transaction !== undefined || (data.transactions && data.transactions.length > 0);\n },\n { message: 'Must have either transaction or transactions' }\n);\n\n// Validation functions\nexport function validateActionMetadata(\n data: unknown\n): ValidationResult<ActionMetadata> {\n const result = ActionMetadataSchema.safeParse(data);\n if (result.success) {\n return { success: true, data: result.data as ActionMetadata };\n }\n return { success: false, error: result.error.message };\n}\n\nexport function validateTransactionRequest(\n data: unknown\n): ValidationResult<TransactionRequest> {\n const result = TransactionRequestSchema.safeParse(data);\n if (result.success) {\n return { success: true, data: result.data };\n }\n return { success: false, error: result.error.message };\n}\n\nexport function validateTransactionResponse(\n data: unknown\n): ValidationResult<TransactionResponse> {\n const result = TransactionResponseSchema.safeParse(data);\n if (result.success) {\n return { success: true, data: result.data as TransactionResponse };\n }\n return { success: false, error: result.error.message };\n}\n\nexport function isValidAddress(address: string): boolean {\n return addressRegex.test(address);\n}\n\nexport function isValidHex(hex: string): boolean {\n return hexRegex.test(hex);\n}\n\n// =============================================================================\n// NEW VALIDATION FUNCTIONS\n// =============================================================================\n\n/**\n * Validate a linked action\n */\nexport function validateLinkedAction(\n data: unknown\n): ValidationResult<LinkedAction> {\n const result = LinkedActionSchema.safeParse(data);\n if (result.success) {\n return { success: true, data: result.data as LinkedAction };\n }\n return { success: false, error: result.error.message };\n}\n\n/**\n * Validate a parameter\n */\nexport function validateParameter(\n data: unknown\n): ValidationResult<TypedActionParameter> {\n const result = TypedActionParameterSchema.safeParse(data);\n if (result.success) {\n return { success: true, data: result.data as TypedActionParameter };\n }\n return { success: false, error: result.error.message };\n}\n\n/**\n * Validate parameter values against their definitions\n */\nexport function validateParameterValues(\n parameters: TypedActionParameter[],\n values: Record<string, string | string[]>\n): ValidationResult<Record<string, string | string[]>> {\n const errors: string[] = [];\n\n for (const param of parameters) {\n const value = values[param.name];\n\n // Check required\n if (param.required && (value === undefined || value === '' || (Array.isArray(value) && value.length === 0))) {\n errors.push(`${param.label || param.name} is required`);\n continue;\n }\n\n // Skip validation if no value and not required\n if (value === undefined || value === '') continue;\n\n const strValue = Array.isArray(value) ? value[0] : value;\n\n // Validate pattern\n if (param.pattern && strValue) {\n const regex = new RegExp(param.pattern);\n if (!regex.test(strValue)) {\n errors.push(param.patternDescription || `${param.label || param.name} has invalid format`);\n }\n }\n\n // Validate min/max for number types\n if ((param.type === 'number' || param.type === 'amount') && strValue) {\n const numValue = parseFloat(strValue);\n if (isNaN(numValue)) {\n errors.push(`${param.label || param.name} must be a number`);\n } else {\n if (param.min !== undefined && numValue < Number(param.min)) {\n errors.push(`${param.label || param.name} must be at least ${param.min}`);\n }\n if (param.max !== undefined && numValue > Number(param.max)) {\n errors.push(`${param.label || param.name} must be at most ${param.max}`);\n }\n }\n }\n\n // Validate address type\n if (param.type === 'address' && strValue && !isValidAddress(strValue)) {\n errors.push(`${param.label || param.name} must be a valid Ethereum address`);\n }\n }\n\n if (errors.length > 0) {\n return { success: false, error: errors.join(', ') };\n }\n\n return { success: true, data: values };\n}\n","import type { Router, Request, Response, NextFunction } from 'express';\nimport type { Action } from '../builders';\nimport { validateTransactionRequest } from '../validators';\n\n// Create Express router\nexport function createExpressHandler(\n action: Action,\n RouterClass: new () => Router\n): Router {\n const router = new RouterClass();\n\n // CORS middleware\n router.use((_req: Request, res: Response, next: NextFunction) => {\n res.header('Access-Control-Allow-Origin', '*');\n res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.header('Access-Control-Allow-Headers', 'Content-Type');\n next();\n });\n\n // OPTIONS handler\n router.options('/', (_req: Request, res: Response) => {\n res.sendStatus(200);\n });\n\n // GET handler\n router.get('/', (_req: Request, res: Response) => {\n try {\n const metadata = action.getMetadata();\n res.json(metadata);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n res.status(500).json({ error: { message } });\n }\n });\n\n // POST handler\n router.post('/', async (req: Request, res: Response) => {\n try {\n const validation = validateTransactionRequest(req.body);\n\n if (!validation.success) {\n return res.status(400).json({ error: { message: validation.error } });\n }\n\n const response = await action.handleRequest(validation.data);\n res.json(response);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n res.status(500).json({ error: { message } });\n }\n });\n\n return router;\n}\n"]}
@@ -10,18 +10,113 @@ var ActionButtonSchema = z.object({
10
10
  placeholder: z.string().optional(),
11
11
  disabled: z.boolean().optional()
12
12
  });
13
- z.object({
14
- title: z.string().min(1).max(100),
15
- icon: z.string().url(),
16
- description: z.string().min(1).max(500),
17
- actions: z.array(ActionButtonSchema).min(1),
13
+ z.enum([
14
+ "text",
15
+ "number",
16
+ "email",
17
+ "url",
18
+ "date",
19
+ "datetime-local",
20
+ "textarea",
21
+ "select",
22
+ "radio",
23
+ "checkbox",
24
+ "address",
25
+ "token",
26
+ "amount"
27
+ ]);
28
+ var ActionParameterOptionSchema = z.object({
29
+ label: z.string().min(1),
30
+ value: z.string(),
31
+ selected: z.boolean().optional()
32
+ });
33
+ var ActionParameterBaseSchema = z.object({
34
+ name: z.string().min(1).max(50),
35
+ label: z.string().max(100).optional(),
36
+ required: z.boolean().optional(),
37
+ pattern: z.string().optional(),
38
+ patternDescription: z.string().optional(),
39
+ min: z.union([z.string(), z.number()]).optional(),
40
+ max: z.union([z.string(), z.number()]).optional()
41
+ });
42
+ var ActionParameterSchema = ActionParameterBaseSchema.extend({
43
+ type: z.enum([
44
+ "text",
45
+ "number",
46
+ "email",
47
+ "url",
48
+ "date",
49
+ "datetime-local",
50
+ "textarea",
51
+ "address",
52
+ "token",
53
+ "amount"
54
+ ]).optional()
55
+ });
56
+ var ActionParameterSelectableSchema = ActionParameterBaseSchema.extend({
57
+ type: z.enum(["select", "radio", "checkbox"]),
58
+ options: z.array(ActionParameterOptionSchema).min(1)
59
+ });
60
+ var TypedActionParameterSchema = z.union([
61
+ ActionParameterSelectableSchema,
62
+ ActionParameterSchema
63
+ ]);
64
+ var LinkedActionTypeSchema = z.enum(["transaction", "post", "external-link"]);
65
+ var LinkedActionSchema = z.object({
66
+ type: LinkedActionTypeSchema.optional(),
67
+ href: z.string().min(1),
68
+ label: z.string().min(1).max(50),
18
69
  disabled: z.boolean().optional(),
19
- error: z.object({ message: z.string() }).optional()
70
+ parameters: z.array(TypedActionParameterSchema).optional()
71
+ });
72
+ var ActionLinksSchema = z.object({
73
+ actions: z.array(LinkedActionSchema).min(1)
74
+ });
75
+ var PostNextActionLinkSchema = z.object({
76
+ type: z.literal("post"),
77
+ href: z.string().min(1)
78
+ });
79
+ var InlineNextActionLinkSchema = z.object({
80
+ type: z.literal("inline"),
81
+ action: z.lazy(() => ActionMetadataSchema)
20
82
  });
83
+ var NextActionLinkSchema = z.union([
84
+ PostNextActionLinkSchema,
85
+ InlineNextActionLinkSchema
86
+ ]);
87
+ var iconSchema = z.string().refine(
88
+ (val) => {
89
+ if (val.startsWith("http://") || val.startsWith("https://")) return true;
90
+ if (val.startsWith("data:image/")) return true;
91
+ if (val.startsWith("/")) return true;
92
+ return false;
93
+ },
94
+ { message: "Icon must be a valid URL, base64 data URI, or relative path" }
95
+ );
96
+ var ActionMetadataSchema = z.object({
97
+ type: z.enum(["action", "completed"]).optional(),
98
+ title: z.string().min(1).max(200),
99
+ icon: iconSchema,
100
+ description: z.string().min(1).max(1e3),
101
+ label: z.string().max(50).optional(),
102
+ // Legacy actions (optional)
103
+ actions: z.array(ActionButtonSchema).optional(),
104
+ // Solana-style linked actions (optional)
105
+ links: ActionLinksSchema.optional(),
106
+ disabled: z.boolean().optional(),
107
+ error: z.object({ message: z.string() }).optional()
108
+ }).refine(
109
+ (data) => {
110
+ return data.actions && data.actions.length > 0 || data.links?.actions && data.links.actions.length > 0;
111
+ },
112
+ { message: "Must have at least one action or linked action" }
113
+ );
21
114
  var TransactionRequestSchema = z.object({
22
115
  account: z.string().regex(addressRegex, "Invalid Ethereum address"),
23
116
  action: z.string().min(1),
24
- input: z.string().optional()
117
+ input: z.string().optional(),
118
+ // Solana-style parameter data
119
+ data: z.record(z.union([z.string(), z.array(z.string())])).optional()
25
120
  });
26
121
  var EVMTransactionSchema = z.object({
27
122
  to: z.string().regex(addressRegex, "Invalid to address"),
@@ -30,9 +125,21 @@ var EVMTransactionSchema = z.object({
30
125
  chainId: z.number().positive()
31
126
  });
32
127
  z.object({
33
- transaction: EVMTransactionSchema,
34
- message: z.string().optional()
35
- });
128
+ // Single transaction (legacy)
129
+ transaction: EVMTransactionSchema.optional(),
130
+ // Multiple transactions (batch)
131
+ transactions: z.array(EVMTransactionSchema).optional(),
132
+ message: z.string().optional(),
133
+ // Action chaining
134
+ links: z.object({
135
+ next: NextActionLinkSchema.optional()
136
+ }).optional()
137
+ }).refine(
138
+ (data) => {
139
+ return data.transaction !== void 0 || data.transactions && data.transactions.length > 0;
140
+ },
141
+ { message: "Must have either transaction or transactions" }
142
+ );
36
143
  function validateTransactionRequest(data) {
37
144
  const result = TransactionRequestSchema.safeParse(data);
38
145
  if (result.success) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/validators.ts","../../src/adapters/express.ts"],"names":[],"mappings":"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","file":"express.mjs","sourcesContent":["import { z } from 'zod';\nimport type {\n ActionMetadata,\n TransactionRequest,\n TransactionResponse,\n ValidationResult,\n} from './types';\n\n// Ethereum address regex\nconst addressRegex = /^0x[a-fA-F0-9]{40}$/;\n\n// Hex string regex\nconst hexRegex = /^0x[a-fA-F0-9]*$/;\n\n// Zod Schemas\nexport const ActionButtonSchema = z.object({\n label: z.string().min(1).max(50),\n value: z.string().min(1),\n type: z.enum(['button', 'input']),\n placeholder: z.string().optional(),\n disabled: z.boolean().optional(),\n});\n\nexport const ActionMetadataSchema = z.object({\n title: z.string().min(1).max(100),\n icon: z.string().url(),\n description: z.string().min(1).max(500),\n actions: z.array(ActionButtonSchema).min(1),\n disabled: z.boolean().optional(),\n error: z.object({ message: z.string() }).optional(),\n});\n\nexport const TransactionRequestSchema = z.object({\n account: z.string().regex(addressRegex, 'Invalid Ethereum address'),\n action: z.string().min(1),\n input: z.string().optional(),\n});\n\nexport const EVMTransactionSchema = z.object({\n to: z.string().regex(addressRegex, 'Invalid to address'),\n value: z.string(),\n data: z.string().regex(hexRegex, 'Invalid hex data'),\n chainId: z.number().positive(),\n});\n\nexport const TransactionResponseSchema = z.object({\n transaction: EVMTransactionSchema,\n message: z.string().optional(),\n});\n\n// Validation functions\nexport function validateActionMetadata(\n data: unknown\n): ValidationResult<ActionMetadata> {\n const result = ActionMetadataSchema.safeParse(data);\n if (result.success) {\n return { success: true, data: result.data as ActionMetadata };\n }\n return { success: false, error: result.error.message };\n}\n\nexport function validateTransactionRequest(\n data: unknown\n): ValidationResult<TransactionRequest> {\n const result = TransactionRequestSchema.safeParse(data);\n if (result.success) {\n return { success: true, data: result.data };\n }\n return { success: false, error: result.error.message };\n}\n\nexport function validateTransactionResponse(\n data: unknown\n): ValidationResult<TransactionResponse> {\n const result = TransactionResponseSchema.safeParse(data);\n if (result.success) {\n return { success: true, data: result.data as TransactionResponse };\n }\n return { success: false, error: result.error.message };\n}\n\nexport function isValidAddress(address: string): boolean {\n return addressRegex.test(address);\n}\n\nexport function isValidHex(hex: string): boolean {\n return hexRegex.test(hex);\n}\n","import type { Router, Request, Response, NextFunction } from 'express';\nimport type { Action } from '../builders';\nimport { validateTransactionRequest } from '../validators';\n\n// Create Express router\nexport function createExpressHandler(\n action: Action,\n RouterClass: new () => Router\n): Router {\n const router = new RouterClass();\n\n // CORS middleware\n router.use((_req: Request, res: Response, next: NextFunction) => {\n res.header('Access-Control-Allow-Origin', '*');\n res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.header('Access-Control-Allow-Headers', 'Content-Type');\n next();\n });\n\n // OPTIONS handler\n router.options('/', (_req: Request, res: Response) => {\n res.sendStatus(200);\n });\n\n // GET handler\n router.get('/', (_req: Request, res: Response) => {\n try {\n const metadata = action.getMetadata();\n res.json(metadata);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n res.status(500).json({ error: { message } });\n }\n });\n\n // POST handler\n router.post('/', async (req: Request, res: Response) => {\n try {\n const validation = validateTransactionRequest(req.body);\n\n if (!validation.success) {\n return res.status(400).json({ error: { message: validation.error } });\n }\n\n const response = await action.handleRequest(validation.data);\n res.json(response);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n res.status(500).json({ error: { message } });\n }\n });\n\n return router;\n}\n"]}
1
+ {"version":3,"sources":["../../src/validators.ts","../../src/adapters/express.ts"],"names":[],"mappings":";;;AAWA,IAAM,YAAA,GAAe,qBAAA;AAGrB,IAAM,QAAA,GAAW,kBAAA;AAMV,IAAM,kBAAA,GAAqB,EAAE,MAAA,CAAO;AAAA,EACzC,KAAA,EAAO,EAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,IAAI,EAAE,CAAA;AAAA,EAC/B,KAAA,EAAO,CAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EACvB,MAAM,CAAA,CAAE,IAAA,CAAK,CAAC,QAAA,EAAU,OAAO,CAAC,CAAA;AAAA,EAChC,WAAA,EAAa,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EACjC,QAAA,EAAU,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAA;AACxB,CAAC,CAAA;AASwC,EAAE,IAAA,CAAK;AAAA,EAC9C,MAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,gBAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAC;AAKM,IAAM,2BAAA,GAA8B,EAAE,MAAA,CAAO;AAAA,EAClD,KAAA,EAAO,CAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EACvB,KAAA,EAAO,EAAE,MAAA,EAAO;AAAA,EAChB,QAAA,EAAU,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAA;AACxB,CAAC,CAAA;AAKD,IAAM,yBAAA,GAA4B,EAAE,MAAA,CAAO;AAAA,EACzC,IAAA,EAAM,EAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,IAAI,EAAE,CAAA;AAAA,EAC9B,OAAO,CAAA,CAAE,MAAA,GAAS,GAAA,CAAI,GAAG,EAAE,QAAA,EAAS;AAAA,EACpC,QAAA,EAAU,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAA,EAAS;AAAA,EAC/B,OAAA,EAAS,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAC7B,kBAAA,EAAoB,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EACxC,GAAA,EAAK,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA,CAAE,MAAA,EAAO,EAAG,CAAA,CAAE,MAAA,EAAQ,CAAC,CAAA,CAAE,QAAA,EAAS;AAAA,EAChD,GAAA,EAAK,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA,CAAE,MAAA,EAAO,EAAG,CAAA,CAAE,MAAA,EAAQ,CAAC,CAAA,CAAE,QAAA;AACzC,CAAC,CAAA;AAKM,IAAM,qBAAA,GAAwB,0BAA0B,MAAA,CAAO;AAAA,EACpE,IAAA,EAAM,EAAE,IAAA,CAAK;AAAA,IACX,MAAA;AAAA,IAAQ,QAAA;AAAA,IAAU,OAAA;AAAA,IAAS,KAAA;AAAA,IAAO,MAAA;AAAA,IAAQ,gBAAA;AAAA,IAC1C,UAAA;AAAA,IAAY,SAAA;AAAA,IAAW,OAAA;AAAA,IAAS;AAAA,GACjC,EAAE,QAAA;AACL,CAAC,CAAA;AAKM,IAAM,+BAAA,GAAkC,0BAA0B,MAAA,CAAO;AAAA,EAC9E,MAAM,CAAA,CAAE,IAAA,CAAK,CAAC,QAAA,EAAU,OAAA,EAAS,UAAU,CAAC,CAAA;AAAA,EAC5C,SAAS,CAAA,CAAE,KAAA,CAAM,2BAA2B,CAAA,CAAE,IAAI,CAAC;AACrD,CAAC,CAAA;AAKM,IAAM,0BAAA,GAA6B,EAAE,KAAA,CAAM;AAAA,EAChD,+BAAA;AAAA,EACA;AACF,CAAC,CAAA;AASM,IAAM,yBAAyB,CAAA,CAAE,IAAA,CAAK,CAAC,aAAA,EAAe,MAAA,EAAQ,eAAe,CAAC,CAAA;AAK9E,IAAM,kBAAA,GAAqB,EAAE,MAAA,CAAO;AAAA,EACzC,IAAA,EAAM,uBAAuB,QAAA,EAAS;AAAA,EACtC,IAAA,EAAM,CAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EACtB,KAAA,EAAO,EAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,IAAI,EAAE,CAAA;AAAA,EAC/B,QAAA,EAAU,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAA,EAAS;AAAA,EAC/B,UAAA,EAAY,CAAA,CAAE,KAAA,CAAM,0BAA0B,EAAE,QAAA;AAClD,CAAC,CAAA;AAKM,IAAM,iBAAA,GAAoB,EAAE,MAAA,CAAO;AAAA,EACxC,SAAS,CAAA,CAAE,KAAA,CAAM,kBAAkB,CAAA,CAAE,IAAI,CAAC;AAC5C,CAAC,CAAA;AAMM,IAAM,wBAAA,GAA2B,EAAE,MAAA,CAAO;AAAA,EAC/C,IAAA,EAAM,CAAA,CAAE,OAAA,CAAQ,MAAM,CAAA;AAAA,EACtB,IAAA,EAAM,CAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC;AACxB,CAAC,CAAA;AAEM,IAAM,0BAAA,GAAoF,EAAE,MAAA,CAAO;AAAA,EACxG,IAAA,EAAM,CAAA,CAAE,OAAA,CAAQ,QAAQ,CAAA;AAAA,EACxB,MAAA,EAAQ,CAAA,CAAE,IAAA,CAAK,MAAM,oBAAoB;AAC3C,CAAC,CAAA;AAEM,IAAM,oBAAA,GAAuB,EAAE,KAAA,CAAM;AAAA,EAC1C,wBAAA;AAAA,EACA;AACF,CAAC,CAAA;AASD,IAAM,UAAA,GAAa,CAAA,CAAE,MAAA,EAAO,CAAE,MAAA;AAAA,EAC5B,CAAC,GAAA,KAAQ;AAEP,IAAA,IAAI,GAAA,CAAI,WAAW,SAAS,CAAA,IAAK,IAAI,UAAA,CAAW,UAAU,GAAG,OAAO,IAAA;AAEpE,IAAA,IAAI,GAAA,CAAI,UAAA,CAAW,aAAa,CAAA,EAAG,OAAO,IAAA;AAE1C,IAAA,IAAI,GAAA,CAAI,UAAA,CAAW,GAAG,CAAA,EAAG,OAAO,IAAA;AAChC,IAAA,OAAO,KAAA;AAAA,EACT,CAAA;AAAA,EACA,EAAE,SAAS,6DAAA;AACb,CAAA;AAKO,IAAM,oBAAA,GAAuB,EAAE,MAAA,CAAO;AAAA,EAC3C,IAAA,EAAM,EAAE,IAAA,CAAK,CAAC,UAAU,WAAW,CAAC,EAAE,QAAA,EAAS;AAAA,EAC/C,KAAA,EAAO,EAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,IAAI,GAAG,CAAA;AAAA,EAChC,IAAA,EAAM,UAAA;AAAA,EACN,WAAA,EAAa,EAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,IAAI,GAAI,CAAA;AAAA,EACvC,OAAO,CAAA,CAAE,MAAA,GAAS,GAAA,CAAI,EAAE,EAAE,QAAA,EAAS;AAAA;AAAA,EAEnC,OAAA,EAAS,CAAA,CAAE,KAAA,CAAM,kBAAkB,EAAE,QAAA,EAAS;AAAA;AAAA,EAE9C,KAAA,EAAO,kBAAkB,QAAA,EAAS;AAAA,EAClC,QAAA,EAAU,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAA,EAAS;AAAA,EAC/B,KAAA,EAAO,CAAA,CAAE,MAAA,CAAO,EAAE,OAAA,EAAS,EAAE,MAAA,EAAO,EAAG,CAAA,CAAE,QAAA;AAC3C,CAAC,CAAA,CAAE,MAAA;AAAA,EACD,CAAC,IAAA,KAAS;AAER,IAAA,OAAQ,IAAA,CAAK,OAAA,IAAW,IAAA,CAAK,OAAA,CAAQ,MAAA,GAAS,CAAA,IACtC,IAAA,CAAK,KAAA,EAAO,OAAA,IAAW,IAAA,CAAK,KAAA,CAAM,OAAA,CAAQ,MAAA,GAAS,CAAA;AAAA,EAC7D,CAAA;AAAA,EACA,EAAE,SAAS,gDAAA;AACb,CAAA;AAKO,IAAM,wBAAA,GAA2B,EAAE,MAAA,CAAO;AAAA,EAC/C,SAAS,CAAA,CAAE,MAAA,EAAO,CAAE,KAAA,CAAM,cAAc,0BAA0B,CAAA;AAAA,EAClE,MAAA,EAAQ,CAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EACxB,KAAA,EAAO,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA;AAAA,EAE3B,MAAM,CAAA,CAAE,MAAA,CAAO,EAAE,KAAA,CAAM,CAAC,EAAE,MAAA,EAAO,EAAG,CAAA,CAAE,KAAA,CAAM,EAAE,MAAA,EAAQ,CAAC,CAAC,CAAC,EAAE,QAAA;AAC7D,CAAC,CAAA;AAEM,IAAM,oBAAA,GAAuB,EAAE,MAAA,CAAO;AAAA,EAC3C,IAAI,CAAA,CAAE,MAAA,EAAO,CAAE,KAAA,CAAM,cAAc,oBAAoB,CAAA;AAAA,EACvD,KAAA,EAAO,EAAE,MAAA,EAAO;AAAA,EAChB,MAAM,CAAA,CAAE,MAAA,EAAO,CAAE,KAAA,CAAM,UAAU,kBAAkB,CAAA;AAAA,EACnD,OAAA,EAAS,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AACtB,CAAC,CAAA;AAKwC,EAAE,MAAA,CAAO;AAAA;AAAA,EAEhD,WAAA,EAAa,qBAAqB,QAAA,EAAS;AAAA;AAAA,EAE3C,YAAA,EAAc,CAAA,CAAE,KAAA,CAAM,oBAAoB,EAAE,QAAA,EAAS;AAAA,EACrD,OAAA,EAAS,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA;AAAA,EAE7B,KAAA,EAAO,EAAE,MAAA,CAAO;AAAA,IACd,IAAA,EAAM,qBAAqB,QAAA;AAAS,GACrC,EAAE,QAAA;AACL,CAAC,CAAA,CAAE,MAAA;AAAA,EACD,CAAC,IAAA,KAAS;AAER,IAAA,OAAO,KAAK,WAAA,KAAgB,MAAA,IAAc,KAAK,YAAA,IAAgB,IAAA,CAAK,aAAa,MAAA,GAAS,CAAA;AAAA,EAC5F,CAAA;AAAA,EACA,EAAE,SAAS,8CAAA;AACb;AAaO,SAAS,2BACd,IAAA,EACsC;AACtC,EAAA,MAAM,MAAA,GAAS,wBAAA,CAAyB,SAAA,CAAU,IAAI,CAAA;AACtD,EAAA,IAAI,OAAO,OAAA,EAAS;AAClB,IAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,IAAA,EAAM,OAAO,IAAA,EAAK;AAAA,EAC5C;AACA,EAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,MAAA,CAAO,MAAM,OAAA,EAAQ;AACvD;;;AClPO,SAAS,oBAAA,CACd,QACA,WAAA,EACQ;AACR,EAAA,MAAM,MAAA,GAAS,IAAI,WAAA,EAAY;AAG/B,EAAA,MAAA,CAAO,GAAA,CAAI,CAAC,IAAA,EAAe,GAAA,EAAe,IAAA,KAAuB;AAC/D,IAAA,GAAA,CAAI,MAAA,CAAO,+BAA+B,GAAG,CAAA;AAC7C,IAAA,GAAA,CAAI,MAAA,CAAO,gCAAgC,oBAAoB,CAAA;AAC/D,IAAA,GAAA,CAAI,MAAA,CAAO,gCAAgC,cAAc,CAAA;AACzD,IAAA,IAAA,EAAK;AAAA,EACP,CAAC,CAAA;AAGD,EAAA,MAAA,CAAO,OAAA,CAAQ,GAAA,EAAK,CAAC,IAAA,EAAe,GAAA,KAAkB;AACpD,IAAA,GAAA,CAAI,WAAW,GAAG,CAAA;AAAA,EACpB,CAAC,CAAA;AAGD,EAAA,MAAA,CAAO,GAAA,CAAI,GAAA,EAAK,CAAC,IAAA,EAAe,GAAA,KAAkB;AAChD,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,OAAO,WAAA,EAAY;AACpC,MAAA,GAAA,CAAI,KAAK,QAAQ,CAAA;AAAA,IACnB,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,OAAA,GAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,eAAA;AACzD,MAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,EAAE,KAAA,EAAO,EAAE,OAAA,EAAQ,EAAG,CAAA;AAAA,IAC7C;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,MAAA,CAAO,IAAA,CAAK,GAAA,EAAK,OAAO,GAAA,EAAc,GAAA,KAAkB;AACtD,IAAA,IAAI;AACF,MAAA,MAAM,UAAA,GAAa,0BAAA,CAA2B,GAAA,CAAI,IAAI,CAAA;AAEtD,MAAA,IAAI,CAAC,WAAW,OAAA,EAAS;AACvB,QAAA,OAAO,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,EAAE,KAAA,EAAO,EAAE,OAAA,EAAS,UAAA,CAAW,KAAA,EAAM,EAAG,CAAA;AAAA,MACtE;AAEA,MAAA,MAAM,QAAA,GAAW,MAAM,MAAA,CAAO,aAAA,CAAc,WAAW,IAAI,CAAA;AAC3D,MAAA,GAAA,CAAI,KAAK,QAAQ,CAAA;AAAA,IACnB,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,OAAA,GAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,eAAA;AACzD,MAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,EAAE,KAAA,EAAO,EAAE,OAAA,EAAQ,EAAG,CAAA;AAAA,IAC7C;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAO,MAAA;AACT","file":"express.mjs","sourcesContent":["import { z } from 'zod';\nimport type {\n ActionMetadata,\n TransactionRequest,\n TransactionResponse,\n LinkedAction,\n TypedActionParameter,\n ValidationResult,\n} from './types';\n\n// Ethereum address regex\nconst addressRegex = /^0x[a-fA-F0-9]{40}$/;\n\n// Hex string regex\nconst hexRegex = /^0x[a-fA-F0-9]*$/;\n\n// =============================================================================\n// LEGACY SCHEMAS (Backwards compatible)\n// =============================================================================\n\nexport const ActionButtonSchema = z.object({\n label: z.string().min(1).max(50),\n value: z.string().min(1),\n type: z.enum(['button', 'input']),\n placeholder: z.string().optional(),\n disabled: z.boolean().optional(),\n});\n\n// =============================================================================\n// SOLANA-STYLE PARAMETER SCHEMAS\n// =============================================================================\n\n/**\n * Parameter types enum\n */\nexport const ActionParameterTypeSchema = z.enum([\n 'text',\n 'number',\n 'email',\n 'url',\n 'date',\n 'datetime-local',\n 'textarea',\n 'select',\n 'radio',\n 'checkbox',\n 'address',\n 'token',\n 'amount',\n]);\n\n/**\n * Option for select/radio/checkbox\n */\nexport const ActionParameterOptionSchema = z.object({\n label: z.string().min(1),\n value: z.string(),\n selected: z.boolean().optional(),\n});\n\n/**\n * Base parameter fields\n */\nconst ActionParameterBaseSchema = z.object({\n name: z.string().min(1).max(50),\n label: z.string().max(100).optional(),\n required: z.boolean().optional(),\n pattern: z.string().optional(),\n patternDescription: z.string().optional(),\n min: z.union([z.string(), z.number()]).optional(),\n max: z.union([z.string(), z.number()]).optional(),\n});\n\n/**\n * Non-selectable parameter (text, number, etc.)\n */\nexport const ActionParameterSchema = ActionParameterBaseSchema.extend({\n type: z.enum([\n 'text', 'number', 'email', 'url', 'date', 'datetime-local',\n 'textarea', 'address', 'token', 'amount'\n ]).optional(),\n});\n\n/**\n * Selectable parameter (select, radio, checkbox)\n */\nexport const ActionParameterSelectableSchema = ActionParameterBaseSchema.extend({\n type: z.enum(['select', 'radio', 'checkbox']),\n options: z.array(ActionParameterOptionSchema).min(1),\n});\n\n/**\n * Union of all parameter types\n */\nexport const TypedActionParameterSchema = z.union([\n ActionParameterSelectableSchema,\n ActionParameterSchema,\n]);\n\n// =============================================================================\n// LINKED ACTION SCHEMAS\n// =============================================================================\n\n/**\n * Linked action type enum\n */\nexport const LinkedActionTypeSchema = z.enum(['transaction', 'post', 'external-link']);\n\n/**\n * Linked action with href template and parameters\n */\nexport const LinkedActionSchema = z.object({\n type: LinkedActionTypeSchema.optional(),\n href: z.string().min(1),\n label: z.string().min(1).max(50),\n disabled: z.boolean().optional(),\n parameters: z.array(TypedActionParameterSchema).optional(),\n});\n\n/**\n * Links section containing linked actions\n */\nexport const ActionLinksSchema = z.object({\n actions: z.array(LinkedActionSchema).min(1),\n});\n\n// =============================================================================\n// ACTION CHAINING SCHEMAS\n// =============================================================================\n\nexport const PostNextActionLinkSchema = z.object({\n type: z.literal('post'),\n href: z.string().min(1),\n});\n\nexport const InlineNextActionLinkSchema: z.ZodType<{ type: 'inline'; action: ActionMetadata }> = z.object({\n type: z.literal('inline'),\n action: z.lazy(() => ActionMetadataSchema),\n});\n\nexport const NextActionLinkSchema = z.union([\n PostNextActionLinkSchema,\n InlineNextActionLinkSchema,\n]);\n\n// =============================================================================\n// MAIN SCHEMAS (Enhanced)\n// =============================================================================\n\n/**\n * Icon can be URL or base64 data URI\n */\nconst iconSchema = z.string().refine(\n (val) => {\n // Allow URLs\n if (val.startsWith('http://') || val.startsWith('https://')) return true;\n // Allow base64 data URIs\n if (val.startsWith('data:image/')) return true;\n // Allow relative paths\n if (val.startsWith('/')) return true;\n return false;\n },\n { message: 'Icon must be a valid URL, base64 data URI, or relative path' }\n);\n\n/**\n * Enhanced ActionMetadata schema with links support\n */\nexport const ActionMetadataSchema = z.object({\n type: z.enum(['action', 'completed']).optional(),\n title: z.string().min(1).max(200),\n icon: iconSchema,\n description: z.string().min(1).max(1000),\n label: z.string().max(50).optional(),\n // Legacy actions (optional)\n actions: z.array(ActionButtonSchema).optional(),\n // Solana-style linked actions (optional)\n links: ActionLinksSchema.optional(),\n disabled: z.boolean().optional(),\n error: z.object({ message: z.string() }).optional(),\n}).refine(\n (data) => {\n // Must have either actions or links (or both)\n return (data.actions && data.actions.length > 0) ||\n (data.links?.actions && data.links.actions.length > 0);\n },\n { message: 'Must have at least one action or linked action' }\n);\n\n/**\n * Enhanced TransactionRequest with data support\n */\nexport const TransactionRequestSchema = z.object({\n account: z.string().regex(addressRegex, 'Invalid Ethereum address'),\n action: z.string().min(1),\n input: z.string().optional(),\n // Solana-style parameter data\n data: z.record(z.union([z.string(), z.array(z.string())])).optional(),\n});\n\nexport const EVMTransactionSchema = z.object({\n to: z.string().regex(addressRegex, 'Invalid to address'),\n value: z.string(),\n data: z.string().regex(hexRegex, 'Invalid hex data'),\n chainId: z.number().positive(),\n});\n\n/**\n * Enhanced TransactionResponse with multi-tx and chaining support\n */\nexport const TransactionResponseSchema = z.object({\n // Single transaction (legacy)\n transaction: EVMTransactionSchema.optional(),\n // Multiple transactions (batch)\n transactions: z.array(EVMTransactionSchema).optional(),\n message: z.string().optional(),\n // Action chaining\n links: z.object({\n next: NextActionLinkSchema.optional(),\n }).optional(),\n}).refine(\n (data) => {\n // Must have either transaction or transactions\n return data.transaction !== undefined || (data.transactions && data.transactions.length > 0);\n },\n { message: 'Must have either transaction or transactions' }\n);\n\n// Validation functions\nexport function validateActionMetadata(\n data: unknown\n): ValidationResult<ActionMetadata> {\n const result = ActionMetadataSchema.safeParse(data);\n if (result.success) {\n return { success: true, data: result.data as ActionMetadata };\n }\n return { success: false, error: result.error.message };\n}\n\nexport function validateTransactionRequest(\n data: unknown\n): ValidationResult<TransactionRequest> {\n const result = TransactionRequestSchema.safeParse(data);\n if (result.success) {\n return { success: true, data: result.data };\n }\n return { success: false, error: result.error.message };\n}\n\nexport function validateTransactionResponse(\n data: unknown\n): ValidationResult<TransactionResponse> {\n const result = TransactionResponseSchema.safeParse(data);\n if (result.success) {\n return { success: true, data: result.data as TransactionResponse };\n }\n return { success: false, error: result.error.message };\n}\n\nexport function isValidAddress(address: string): boolean {\n return addressRegex.test(address);\n}\n\nexport function isValidHex(hex: string): boolean {\n return hexRegex.test(hex);\n}\n\n// =============================================================================\n// NEW VALIDATION FUNCTIONS\n// =============================================================================\n\n/**\n * Validate a linked action\n */\nexport function validateLinkedAction(\n data: unknown\n): ValidationResult<LinkedAction> {\n const result = LinkedActionSchema.safeParse(data);\n if (result.success) {\n return { success: true, data: result.data as LinkedAction };\n }\n return { success: false, error: result.error.message };\n}\n\n/**\n * Validate a parameter\n */\nexport function validateParameter(\n data: unknown\n): ValidationResult<TypedActionParameter> {\n const result = TypedActionParameterSchema.safeParse(data);\n if (result.success) {\n return { success: true, data: result.data as TypedActionParameter };\n }\n return { success: false, error: result.error.message };\n}\n\n/**\n * Validate parameter values against their definitions\n */\nexport function validateParameterValues(\n parameters: TypedActionParameter[],\n values: Record<string, string | string[]>\n): ValidationResult<Record<string, string | string[]>> {\n const errors: string[] = [];\n\n for (const param of parameters) {\n const value = values[param.name];\n\n // Check required\n if (param.required && (value === undefined || value === '' || (Array.isArray(value) && value.length === 0))) {\n errors.push(`${param.label || param.name} is required`);\n continue;\n }\n\n // Skip validation if no value and not required\n if (value === undefined || value === '') continue;\n\n const strValue = Array.isArray(value) ? value[0] : value;\n\n // Validate pattern\n if (param.pattern && strValue) {\n const regex = new RegExp(param.pattern);\n if (!regex.test(strValue)) {\n errors.push(param.patternDescription || `${param.label || param.name} has invalid format`);\n }\n }\n\n // Validate min/max for number types\n if ((param.type === 'number' || param.type === 'amount') && strValue) {\n const numValue = parseFloat(strValue);\n if (isNaN(numValue)) {\n errors.push(`${param.label || param.name} must be a number`);\n } else {\n if (param.min !== undefined && numValue < Number(param.min)) {\n errors.push(`${param.label || param.name} must be at least ${param.min}`);\n }\n if (param.max !== undefined && numValue > Number(param.max)) {\n errors.push(`${param.label || param.name} must be at most ${param.max}`);\n }\n }\n }\n\n // Validate address type\n if (param.type === 'address' && strValue && !isValidAddress(strValue)) {\n errors.push(`${param.label || param.name} must be a valid Ethereum address`);\n }\n }\n\n if (errors.length > 0) {\n return { success: false, error: errors.join(', ') };\n }\n\n return { success: true, data: values };\n}\n","import type { Router, Request, Response, NextFunction } from 'express';\nimport type { Action } from '../builders';\nimport { validateTransactionRequest } from '../validators';\n\n// Create Express router\nexport function createExpressHandler(\n action: Action,\n RouterClass: new () => Router\n): Router {\n const router = new RouterClass();\n\n // CORS middleware\n router.use((_req: Request, res: Response, next: NextFunction) => {\n res.header('Access-Control-Allow-Origin', '*');\n res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.header('Access-Control-Allow-Headers', 'Content-Type');\n next();\n });\n\n // OPTIONS handler\n router.options('/', (_req: Request, res: Response) => {\n res.sendStatus(200);\n });\n\n // GET handler\n router.get('/', (_req: Request, res: Response) => {\n try {\n const metadata = action.getMetadata();\n res.json(metadata);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n res.status(500).json({ error: { message } });\n }\n });\n\n // POST handler\n router.post('/', async (req: Request, res: Response) => {\n try {\n const validation = validateTransactionRequest(req.body);\n\n if (!validation.success) {\n return res.status(400).json({ error: { message: validation.error } });\n }\n\n const response = await action.handleRequest(validation.data);\n res.json(response);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n res.status(500).json({ error: { message } });\n }\n });\n\n return router;\n}\n"]}
@@ -1,6 +1,6 @@
1
- import { A as ActionMetadata, a as TransactionResponse } from '../types-CAnUIaVe.mjs';
1
+ import { A as ActionMetadata, a as TransactionResponse } from '../types-DD9rJ58Y.mjs';
2
2
  import { NextResponse, NextRequest } from 'next/server';
3
- import { A as Action } from '../builders-CN5ijFpW.mjs';
3
+ import { A as Action } from '../builders-pKj4NiIj.mjs';
4
4
 
5
5
  declare function createNextHandler(action: Action): {
6
6
  GET: () => Promise<NextResponse<ActionMetadata> | NextResponse<{
@@ -1,6 +1,6 @@
1
- import { A as ActionMetadata, a as TransactionResponse } from '../types-CAnUIaVe.js';
1
+ import { A as ActionMetadata, a as TransactionResponse } from '../types-DD9rJ58Y.js';
2
2
  import { NextResponse, NextRequest } from 'next/server';
3
- import { A as Action } from '../builders-CJNt88dM.js';
3
+ import { A as Action } from '../builders-CLqoe2Kx.js';
4
4
 
5
5
  declare function createNextHandler(action: Action): {
6
6
  GET: () => Promise<NextResponse<ActionMetadata> | NextResponse<{
@@ -13,18 +13,113 @@ var ActionButtonSchema = zod.z.object({
13
13
  placeholder: zod.z.string().optional(),
14
14
  disabled: zod.z.boolean().optional()
15
15
  });
16
- zod.z.object({
17
- title: zod.z.string().min(1).max(100),
18
- icon: zod.z.string().url(),
19
- description: zod.z.string().min(1).max(500),
20
- actions: zod.z.array(ActionButtonSchema).min(1),
16
+ zod.z.enum([
17
+ "text",
18
+ "number",
19
+ "email",
20
+ "url",
21
+ "date",
22
+ "datetime-local",
23
+ "textarea",
24
+ "select",
25
+ "radio",
26
+ "checkbox",
27
+ "address",
28
+ "token",
29
+ "amount"
30
+ ]);
31
+ var ActionParameterOptionSchema = zod.z.object({
32
+ label: zod.z.string().min(1),
33
+ value: zod.z.string(),
34
+ selected: zod.z.boolean().optional()
35
+ });
36
+ var ActionParameterBaseSchema = zod.z.object({
37
+ name: zod.z.string().min(1).max(50),
38
+ label: zod.z.string().max(100).optional(),
39
+ required: zod.z.boolean().optional(),
40
+ pattern: zod.z.string().optional(),
41
+ patternDescription: zod.z.string().optional(),
42
+ min: zod.z.union([zod.z.string(), zod.z.number()]).optional(),
43
+ max: zod.z.union([zod.z.string(), zod.z.number()]).optional()
44
+ });
45
+ var ActionParameterSchema = ActionParameterBaseSchema.extend({
46
+ type: zod.z.enum([
47
+ "text",
48
+ "number",
49
+ "email",
50
+ "url",
51
+ "date",
52
+ "datetime-local",
53
+ "textarea",
54
+ "address",
55
+ "token",
56
+ "amount"
57
+ ]).optional()
58
+ });
59
+ var ActionParameterSelectableSchema = ActionParameterBaseSchema.extend({
60
+ type: zod.z.enum(["select", "radio", "checkbox"]),
61
+ options: zod.z.array(ActionParameterOptionSchema).min(1)
62
+ });
63
+ var TypedActionParameterSchema = zod.z.union([
64
+ ActionParameterSelectableSchema,
65
+ ActionParameterSchema
66
+ ]);
67
+ var LinkedActionTypeSchema = zod.z.enum(["transaction", "post", "external-link"]);
68
+ var LinkedActionSchema = zod.z.object({
69
+ type: LinkedActionTypeSchema.optional(),
70
+ href: zod.z.string().min(1),
71
+ label: zod.z.string().min(1).max(50),
21
72
  disabled: zod.z.boolean().optional(),
22
- error: zod.z.object({ message: zod.z.string() }).optional()
73
+ parameters: zod.z.array(TypedActionParameterSchema).optional()
74
+ });
75
+ var ActionLinksSchema = zod.z.object({
76
+ actions: zod.z.array(LinkedActionSchema).min(1)
77
+ });
78
+ var PostNextActionLinkSchema = zod.z.object({
79
+ type: zod.z.literal("post"),
80
+ href: zod.z.string().min(1)
81
+ });
82
+ var InlineNextActionLinkSchema = zod.z.object({
83
+ type: zod.z.literal("inline"),
84
+ action: zod.z.lazy(() => ActionMetadataSchema)
23
85
  });
86
+ var NextActionLinkSchema = zod.z.union([
87
+ PostNextActionLinkSchema,
88
+ InlineNextActionLinkSchema
89
+ ]);
90
+ var iconSchema = zod.z.string().refine(
91
+ (val) => {
92
+ if (val.startsWith("http://") || val.startsWith("https://")) return true;
93
+ if (val.startsWith("data:image/")) return true;
94
+ if (val.startsWith("/")) return true;
95
+ return false;
96
+ },
97
+ { message: "Icon must be a valid URL, base64 data URI, or relative path" }
98
+ );
99
+ var ActionMetadataSchema = zod.z.object({
100
+ type: zod.z.enum(["action", "completed"]).optional(),
101
+ title: zod.z.string().min(1).max(200),
102
+ icon: iconSchema,
103
+ description: zod.z.string().min(1).max(1e3),
104
+ label: zod.z.string().max(50).optional(),
105
+ // Legacy actions (optional)
106
+ actions: zod.z.array(ActionButtonSchema).optional(),
107
+ // Solana-style linked actions (optional)
108
+ links: ActionLinksSchema.optional(),
109
+ disabled: zod.z.boolean().optional(),
110
+ error: zod.z.object({ message: zod.z.string() }).optional()
111
+ }).refine(
112
+ (data) => {
113
+ return data.actions && data.actions.length > 0 || data.links?.actions && data.links.actions.length > 0;
114
+ },
115
+ { message: "Must have at least one action or linked action" }
116
+ );
24
117
  var TransactionRequestSchema = zod.z.object({
25
118
  account: zod.z.string().regex(addressRegex, "Invalid Ethereum address"),
26
119
  action: zod.z.string().min(1),
27
- input: zod.z.string().optional()
120
+ input: zod.z.string().optional(),
121
+ // Solana-style parameter data
122
+ data: zod.z.record(zod.z.union([zod.z.string(), zod.z.array(zod.z.string())])).optional()
28
123
  });
29
124
  var EVMTransactionSchema = zod.z.object({
30
125
  to: zod.z.string().regex(addressRegex, "Invalid to address"),
@@ -33,9 +128,21 @@ var EVMTransactionSchema = zod.z.object({
33
128
  chainId: zod.z.number().positive()
34
129
  });
35
130
  zod.z.object({
36
- transaction: EVMTransactionSchema,
37
- message: zod.z.string().optional()
38
- });
131
+ // Single transaction (legacy)
132
+ transaction: EVMTransactionSchema.optional(),
133
+ // Multiple transactions (batch)
134
+ transactions: zod.z.array(EVMTransactionSchema).optional(),
135
+ message: zod.z.string().optional(),
136
+ // Action chaining
137
+ links: zod.z.object({
138
+ next: NextActionLinkSchema.optional()
139
+ }).optional()
140
+ }).refine(
141
+ (data) => {
142
+ return data.transaction !== void 0 || data.transactions && data.transactions.length > 0;
143
+ },
144
+ { message: "Must have either transaction or transactions" }
145
+ );
39
146
  function validateTransactionRequest(data) {
40
147
  const result = TransactionRequestSchema.safeParse(data);
41
148
  if (result.success) {