@dipansrimany/mlink-sdk 0.3.1 → 0.4.2
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/adapters/express.d.mts +2 -2
- package/dist/adapters/express.d.ts +2 -2
- package/dist/adapters/express.js +117 -10
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +117 -10
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/next.d.mts +2 -2
- package/dist/adapters/next.d.ts +2 -2
- package/dist/adapters/next.js +117 -10
- package/dist/adapters/next.js.map +1 -1
- package/dist/adapters/next.mjs +117 -10
- package/dist/adapters/next.mjs.map +1 -1
- package/dist/builders-CLqoe2Kx.d.ts +245 -0
- package/dist/builders-pKj4NiIj.d.mts +245 -0
- package/dist/index.d.mts +1131 -24
- package/dist/index.d.ts +1131 -24
- package/dist/index.js +346 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +317 -21
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +43 -5
- package/dist/react/index.d.ts +43 -5
- package/dist/react/index.js +522 -37
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +522 -37
- package/dist/react/index.mjs.map +1 -1
- package/dist/styles.css +248 -0
- package/dist/types-DD9rJ58Y.d.mts +214 -0
- package/dist/types-DD9rJ58Y.d.ts +214 -0
- package/package.json +2 -2
- package/dist/builders-CJNt88dM.d.ts +0 -19
- package/dist/builders-CN5ijFpW.d.mts +0 -19
- package/dist/types-CAnUIaVe.d.mts +0 -68
- package/dist/types-CAnUIaVe.d.ts +0 -68
package/dist/index.js
CHANGED
|
@@ -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.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),
|
|
71
|
+
disabled: zod.z.boolean().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)
|
|
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
|
+
);
|
|
15
98
|
var ActionMetadataSchema = zod.z.object({
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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(),
|
|
20
108
|
disabled: zod.z.boolean().optional(),
|
|
21
109
|
error: zod.z.object({ message: zod.z.string() }).optional()
|
|
22
|
-
})
|
|
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
|
var TransactionResponseSchema = zod.z.object({
|
|
35
|
-
transaction
|
|
36
|
-
|
|
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 validateActionMetadata(data) {
|
|
39
146
|
const result = ActionMetadataSchema.safeParse(data);
|
|
40
147
|
if (result.success) {
|
|
@@ -62,6 +169,58 @@ function isValidAddress(address) {
|
|
|
62
169
|
function isValidHex(hex) {
|
|
63
170
|
return hexRegex.test(hex);
|
|
64
171
|
}
|
|
172
|
+
function validateLinkedAction(data) {
|
|
173
|
+
const result = LinkedActionSchema.safeParse(data);
|
|
174
|
+
if (result.success) {
|
|
175
|
+
return { success: true, data: result.data };
|
|
176
|
+
}
|
|
177
|
+
return { success: false, error: result.error.message };
|
|
178
|
+
}
|
|
179
|
+
function validateParameter(data) {
|
|
180
|
+
const result = TypedActionParameterSchema.safeParse(data);
|
|
181
|
+
if (result.success) {
|
|
182
|
+
return { success: true, data: result.data };
|
|
183
|
+
}
|
|
184
|
+
return { success: false, error: result.error.message };
|
|
185
|
+
}
|
|
186
|
+
function validateParameterValues(parameters, values) {
|
|
187
|
+
const errors = [];
|
|
188
|
+
for (const param of parameters) {
|
|
189
|
+
const value = values[param.name];
|
|
190
|
+
if (param.required && (value === void 0 || value === "" || Array.isArray(value) && value.length === 0)) {
|
|
191
|
+
errors.push(`${param.label || param.name} is required`);
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
if (value === void 0 || value === "") continue;
|
|
195
|
+
const strValue = Array.isArray(value) ? value[0] : value;
|
|
196
|
+
if (param.pattern && strValue) {
|
|
197
|
+
const regex = new RegExp(param.pattern);
|
|
198
|
+
if (!regex.test(strValue)) {
|
|
199
|
+
errors.push(param.patternDescription || `${param.label || param.name} has invalid format`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if ((param.type === "number" || param.type === "amount") && strValue) {
|
|
203
|
+
const numValue = parseFloat(strValue);
|
|
204
|
+
if (isNaN(numValue)) {
|
|
205
|
+
errors.push(`${param.label || param.name} must be a number`);
|
|
206
|
+
} else {
|
|
207
|
+
if (param.min !== void 0 && numValue < Number(param.min)) {
|
|
208
|
+
errors.push(`${param.label || param.name} must be at least ${param.min}`);
|
|
209
|
+
}
|
|
210
|
+
if (param.max !== void 0 && numValue > Number(param.max)) {
|
|
211
|
+
errors.push(`${param.label || param.name} must be at most ${param.max}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (param.type === "address" && strValue && !isValidAddress(strValue)) {
|
|
216
|
+
errors.push(`${param.label || param.name} must be a valid Ethereum address`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (errors.length > 0) {
|
|
220
|
+
return { success: false, error: errors.join(", ") };
|
|
221
|
+
}
|
|
222
|
+
return { success: true, data: values };
|
|
223
|
+
}
|
|
65
224
|
|
|
66
225
|
// src/builders.ts
|
|
67
226
|
function button(config) {
|
|
@@ -81,12 +240,142 @@ function input(config) {
|
|
|
81
240
|
disabled: config.disabled
|
|
82
241
|
};
|
|
83
242
|
}
|
|
243
|
+
function linkedAction(config) {
|
|
244
|
+
return {
|
|
245
|
+
type: "transaction",
|
|
246
|
+
href: config.href,
|
|
247
|
+
label: config.label,
|
|
248
|
+
disabled: config.disabled,
|
|
249
|
+
parameters: config.parameters
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
function actionButton(config) {
|
|
253
|
+
return {
|
|
254
|
+
type: "transaction",
|
|
255
|
+
href: config.href,
|
|
256
|
+
label: config.label,
|
|
257
|
+
disabled: config.disabled
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
function textParam(config) {
|
|
261
|
+
return {
|
|
262
|
+
type: "text",
|
|
263
|
+
name: config.name,
|
|
264
|
+
label: config.label,
|
|
265
|
+
required: config.required,
|
|
266
|
+
pattern: config.pattern,
|
|
267
|
+
patternDescription: config.patternDescription
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
function numberParam(config) {
|
|
271
|
+
return {
|
|
272
|
+
type: "number",
|
|
273
|
+
name: config.name,
|
|
274
|
+
label: config.label,
|
|
275
|
+
required: config.required,
|
|
276
|
+
min: config.min,
|
|
277
|
+
max: config.max
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
function amountParam(config) {
|
|
281
|
+
return {
|
|
282
|
+
type: "amount",
|
|
283
|
+
name: config.name,
|
|
284
|
+
label: config.label || "Amount",
|
|
285
|
+
required: config.required,
|
|
286
|
+
min: config.min,
|
|
287
|
+
max: config.max
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
function addressParam(config) {
|
|
291
|
+
return {
|
|
292
|
+
type: "address",
|
|
293
|
+
name: config.name,
|
|
294
|
+
label: config.label || "Address",
|
|
295
|
+
required: config.required,
|
|
296
|
+
pattern: "^0x[a-fA-F0-9]{40}$",
|
|
297
|
+
patternDescription: "Valid Ethereum address (0x...)"
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
function selectParam(config) {
|
|
301
|
+
return {
|
|
302
|
+
type: "select",
|
|
303
|
+
name: config.name,
|
|
304
|
+
label: config.label,
|
|
305
|
+
required: config.required,
|
|
306
|
+
options: config.options
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
function radioParam(config) {
|
|
310
|
+
return {
|
|
311
|
+
type: "radio",
|
|
312
|
+
name: config.name,
|
|
313
|
+
label: config.label,
|
|
314
|
+
required: config.required,
|
|
315
|
+
options: config.options
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
function checkboxParam(config) {
|
|
319
|
+
return {
|
|
320
|
+
type: "checkbox",
|
|
321
|
+
name: config.name,
|
|
322
|
+
label: config.label,
|
|
323
|
+
required: config.required,
|
|
324
|
+
options: config.options
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
function dateParam(config) {
|
|
328
|
+
return {
|
|
329
|
+
type: "date",
|
|
330
|
+
name: config.name,
|
|
331
|
+
label: config.label,
|
|
332
|
+
required: config.required,
|
|
333
|
+
min: config.min,
|
|
334
|
+
max: config.max
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
function textareaParam(config) {
|
|
338
|
+
return {
|
|
339
|
+
type: "textarea",
|
|
340
|
+
name: config.name,
|
|
341
|
+
label: config.label,
|
|
342
|
+
required: config.required
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
function option(label, value, selected) {
|
|
346
|
+
return { label, value, selected };
|
|
347
|
+
}
|
|
348
|
+
function createLinks(actions) {
|
|
349
|
+
return { actions };
|
|
350
|
+
}
|
|
351
|
+
function buildHref(template, params) {
|
|
352
|
+
let result = template;
|
|
353
|
+
for (const [key, value] of Object.entries(params)) {
|
|
354
|
+
const placeholder = `{${key}}`;
|
|
355
|
+
const replacement = Array.isArray(value) ? value.join(",") : value;
|
|
356
|
+
result = result.replace(new RegExp(placeholder, "g"), encodeURIComponent(replacement));
|
|
357
|
+
}
|
|
358
|
+
return result;
|
|
359
|
+
}
|
|
360
|
+
function extractParams(template) {
|
|
361
|
+
const matches = template.match(/\{([^}]+)\}/g);
|
|
362
|
+
if (!matches) return [];
|
|
363
|
+
return matches.map((m) => m.slice(1, -1));
|
|
364
|
+
}
|
|
365
|
+
function hasParameters(action) {
|
|
366
|
+
return Boolean(action.parameters && action.parameters.length > 0);
|
|
367
|
+
}
|
|
368
|
+
function isSelectableParam(param) {
|
|
369
|
+
return param.type === "select" || param.type === "radio" || param.type === "checkbox";
|
|
370
|
+
}
|
|
84
371
|
function createAction(definition) {
|
|
85
372
|
if (!definition.title) throw new Error("Action title is required");
|
|
86
373
|
if (!definition.icon) throw new Error("Action icon is required");
|
|
87
374
|
if (!definition.description) throw new Error("Action description is required");
|
|
88
|
-
|
|
89
|
-
|
|
375
|
+
const hasLegacyActions = definition.actions && definition.actions.length > 0;
|
|
376
|
+
const hasLinkedActions = definition.links?.actions && definition.links.actions.length > 0;
|
|
377
|
+
if (!hasLegacyActions && !hasLinkedActions) {
|
|
378
|
+
throw new Error("At least one action or linked action is required");
|
|
90
379
|
}
|
|
91
380
|
if (typeof definition.handler !== "function") {
|
|
92
381
|
throw new Error("Handler must be a function");
|
|
@@ -94,10 +383,13 @@ function createAction(definition) {
|
|
|
94
383
|
return {
|
|
95
384
|
getMetadata() {
|
|
96
385
|
return {
|
|
386
|
+
type: "action",
|
|
97
387
|
title: definition.title,
|
|
98
388
|
icon: definition.icon,
|
|
99
389
|
description: definition.description,
|
|
390
|
+
label: definition.label,
|
|
100
391
|
actions: definition.actions,
|
|
392
|
+
links: definition.links,
|
|
101
393
|
disabled: definition.disabled
|
|
102
394
|
};
|
|
103
395
|
},
|
|
@@ -106,19 +398,21 @@ function createAction(definition) {
|
|
|
106
398
|
if (!validation.success) {
|
|
107
399
|
throw new Error(validation.error);
|
|
108
400
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
401
|
+
if (definition.actions) {
|
|
402
|
+
const selectedAction = definition.actions.find(
|
|
403
|
+
(a) => a.value === request.action || a.type === "input" && request.action === "__input__"
|
|
404
|
+
);
|
|
405
|
+
if (selectedAction) {
|
|
406
|
+
if (selectedAction.type === "input" && !request.input) {
|
|
407
|
+
throw new Error("Input value is required");
|
|
408
|
+
}
|
|
409
|
+
}
|
|
117
410
|
}
|
|
118
411
|
const response = await definition.handler({
|
|
119
412
|
account: request.account,
|
|
120
413
|
action: request.action,
|
|
121
|
-
input: request.input
|
|
414
|
+
input: request.input,
|
|
415
|
+
data: request.data
|
|
122
416
|
});
|
|
123
417
|
return response;
|
|
124
418
|
}
|
|
@@ -152,6 +446,8 @@ var SUPPORTED_CHAINS = [MANTLE_MAINNET, MANTLE_SEPOLIA];
|
|
|
152
446
|
var DEFAULT_CHAIN = MANTLE_SEPOLIA;
|
|
153
447
|
var BLINK_BASE_URL = "https://blink.mantle.xyz";
|
|
154
448
|
var ACTION_QUERY_PARAM = "action";
|
|
449
|
+
var REGISTRY_URL = "https://mlinks-fe.vercel.app";
|
|
450
|
+
var REGISTRY_VALIDATE_ENDPOINT = "/api/registry/validate";
|
|
155
451
|
|
|
156
452
|
// src/utils.ts
|
|
157
453
|
function createBlinkUrl(actionUrl, baseUrl = BLINK_BASE_URL) {
|
|
@@ -210,29 +506,59 @@ function getAddressExplorerUrl(chainId, address) {
|
|
|
210
506
|
}
|
|
211
507
|
|
|
212
508
|
exports.ACTION_QUERY_PARAM = ACTION_QUERY_PARAM;
|
|
509
|
+
exports.ActionButtonSchema = ActionButtonSchema;
|
|
510
|
+
exports.ActionLinksSchema = ActionLinksSchema;
|
|
213
511
|
exports.ActionMetadataSchema = ActionMetadataSchema;
|
|
512
|
+
exports.ActionParameterOptionSchema = ActionParameterOptionSchema;
|
|
513
|
+
exports.ActionParameterSchema = ActionParameterSchema;
|
|
514
|
+
exports.ActionParameterSelectableSchema = ActionParameterSelectableSchema;
|
|
214
515
|
exports.BLINK_BASE_URL = BLINK_BASE_URL;
|
|
215
516
|
exports.DEFAULT_CHAIN = DEFAULT_CHAIN;
|
|
517
|
+
exports.LinkedActionSchema = LinkedActionSchema;
|
|
216
518
|
exports.MANTLE_MAINNET = MANTLE_MAINNET;
|
|
217
519
|
exports.MANTLE_SEPOLIA = MANTLE_SEPOLIA;
|
|
520
|
+
exports.NextActionLinkSchema = NextActionLinkSchema;
|
|
521
|
+
exports.REGISTRY_URL = REGISTRY_URL;
|
|
522
|
+
exports.REGISTRY_VALIDATE_ENDPOINT = REGISTRY_VALIDATE_ENDPOINT;
|
|
218
523
|
exports.SUPPORTED_CHAINS = SUPPORTED_CHAINS;
|
|
219
524
|
exports.TransactionRequestSchema = TransactionRequestSchema;
|
|
220
525
|
exports.TransactionResponseSchema = TransactionResponseSchema;
|
|
526
|
+
exports.TypedActionParameterSchema = TypedActionParameterSchema;
|
|
527
|
+
exports.actionButton = actionButton;
|
|
528
|
+
exports.addressParam = addressParam;
|
|
529
|
+
exports.amountParam = amountParam;
|
|
530
|
+
exports.buildHref = buildHref;
|
|
221
531
|
exports.button = button;
|
|
532
|
+
exports.checkboxParam = checkboxParam;
|
|
222
533
|
exports.createAction = createAction;
|
|
223
534
|
exports.createBlinkUrl = createBlinkUrl;
|
|
535
|
+
exports.createLinks = createLinks;
|
|
536
|
+
exports.dateParam = dateParam;
|
|
537
|
+
exports.extractParams = extractParams;
|
|
224
538
|
exports.formatEther = formatEther;
|
|
225
539
|
exports.getAddressExplorerUrl = getAddressExplorerUrl;
|
|
226
540
|
exports.getChainById = getChainById;
|
|
227
541
|
exports.getExplorerUrl = getExplorerUrl;
|
|
542
|
+
exports.hasParameters = hasParameters;
|
|
228
543
|
exports.input = input;
|
|
229
544
|
exports.isBlinkUrl = isBlinkUrl;
|
|
545
|
+
exports.isSelectableParam = isSelectableParam;
|
|
230
546
|
exports.isValidAddress = isValidAddress;
|
|
231
547
|
exports.isValidHex = isValidHex;
|
|
548
|
+
exports.linkedAction = linkedAction;
|
|
549
|
+
exports.numberParam = numberParam;
|
|
550
|
+
exports.option = option;
|
|
232
551
|
exports.parseBlinkUrl = parseBlinkUrl;
|
|
233
552
|
exports.parseEther = parseEther;
|
|
553
|
+
exports.radioParam = radioParam;
|
|
554
|
+
exports.selectParam = selectParam;
|
|
234
555
|
exports.shortenAddress = shortenAddress;
|
|
556
|
+
exports.textParam = textParam;
|
|
557
|
+
exports.textareaParam = textareaParam;
|
|
235
558
|
exports.validateActionMetadata = validateActionMetadata;
|
|
559
|
+
exports.validateLinkedAction = validateLinkedAction;
|
|
560
|
+
exports.validateParameter = validateParameter;
|
|
561
|
+
exports.validateParameterValues = validateParameterValues;
|
|
236
562
|
exports.validateTransactionRequest = validateTransactionRequest;
|
|
237
563
|
exports.validateTransactionResponse = validateTransactionResponse;
|
|
238
564
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/validators.ts","../src/builders.ts","../src/constants.ts","../src/utils.ts"],"names":["z"],"mappings":"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","file":"index.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 {\n ActionButton,\n ActionDefinition,\n ActionMetadata,\n TransactionRequest,\n TransactionResponse,\n} from './types';\nimport { validateTransactionRequest } from './validators';\n\n// Create a button action\nexport function button(config: {\n label: string;\n value: string;\n disabled?: boolean;\n}): ActionButton {\n return {\n label: config.label,\n value: config.value,\n type: 'button',\n disabled: config.disabled,\n };\n}\n\n// Create an input action\nexport function input(config: {\n label: string;\n placeholder?: string;\n disabled?: boolean;\n}): ActionButton {\n return {\n label: config.label,\n value: '__input__',\n type: 'input',\n placeholder: config.placeholder,\n disabled: config.disabled,\n };\n}\n\n// Action object returned by createAction\nexport interface Action {\n getMetadata(): ActionMetadata;\n handleRequest(request: TransactionRequest): Promise<TransactionResponse>;\n}\n\n// Create a complete action\nexport function createAction(definition: ActionDefinition): Action {\n // Validate definition\n if (!definition.title) throw new Error('Action title is required');\n if (!definition.icon) throw new Error('Action icon is required');\n if (!definition.description) throw new Error('Action description is required');\n if (!definition.actions || definition.actions.length === 0) {\n throw new Error('At least one action is required');\n }\n if (typeof definition.handler !== 'function') {\n throw new Error('Handler must be a function');\n }\n\n return {\n getMetadata(): ActionMetadata {\n return {\n title: definition.title,\n icon: definition.icon,\n description: definition.description,\n actions: definition.actions,\n disabled: definition.disabled,\n };\n },\n\n async handleRequest(\n request: TransactionRequest\n ): Promise<TransactionResponse> {\n // Validate request\n const validation = validateTransactionRequest(request);\n if (!validation.success) {\n throw new Error(validation.error);\n }\n\n // Find the selected action\n const selectedAction = definition.actions.find(\n (a) => a.value === request.action || (a.type === 'input' && request.action === '__input__')\n );\n\n if (!selectedAction) {\n throw new Error('Invalid action selected');\n }\n\n // If input type, require input value\n if (selectedAction.type === 'input' && !request.input) {\n throw new Error('Input value is required');\n }\n\n // Call handler\n const response = await definition.handler({\n account: request.account,\n action: request.action,\n input: request.input,\n });\n\n return response;\n },\n };\n}\n","import type { ChainConfig } from './types';\n\nexport const MANTLE_MAINNET: ChainConfig = {\n chainId: 5000,\n name: 'Mantle',\n rpcUrl: 'https://rpc.mantle.xyz',\n explorerUrl: 'https://mantlescan.xyz',\n nativeCurrency: {\n name: 'MNT',\n symbol: 'MNT',\n decimals: 18,\n },\n};\n\nexport const MANTLE_SEPOLIA: ChainConfig = {\n chainId: 5003,\n name: 'Mantle Sepolia',\n rpcUrl: 'https://rpc.sepolia.mantle.xyz',\n explorerUrl: 'https://sepolia.mantlescan.xyz',\n nativeCurrency: {\n name: 'MNT',\n symbol: 'MNT',\n decimals: 18,\n },\n};\n\nexport const SUPPORTED_CHAINS: ChainConfig[] = [MANTLE_MAINNET, MANTLE_SEPOLIA];\n\nexport const DEFAULT_CHAIN = MANTLE_SEPOLIA;\n\nexport const BLINK_BASE_URL = 'https://blink.mantle.xyz';\n\nexport const ACTION_QUERY_PARAM = 'action';\n","import {\n BLINK_BASE_URL,\n ACTION_QUERY_PARAM,\n SUPPORTED_CHAINS,\n} from './constants';\nimport type { ChainConfig } from './types';\n\n// Create Blink URL from Action URL\nexport function createBlinkUrl(\n actionUrl: string,\n baseUrl: string = BLINK_BASE_URL\n): string {\n // Validate actionUrl is a valid URL\n try {\n new URL(actionUrl);\n } catch {\n throw new Error('Invalid action URL');\n }\n\n const encodedAction = encodeURIComponent(actionUrl);\n return `${baseUrl}/mlink?${ACTION_QUERY_PARAM}=${encodedAction}`;\n}\n\n// Parse Blink URL to extract Action URL\nexport function parseBlinkUrl(blinkUrl: string): string | null {\n try {\n const url = new URL(blinkUrl);\n const actionParam = url.searchParams.get(ACTION_QUERY_PARAM);\n\n if (!actionParam) return null;\n\n const actionUrl = decodeURIComponent(actionParam);\n\n // Validate it's a valid URL\n new URL(actionUrl);\n\n return actionUrl;\n } catch {\n return null;\n }\n}\n\n// Check if URL is a valid Blink URL\nexport function isBlinkUrl(url: string): boolean {\n return parseBlinkUrl(url) !== null;\n}\n\n// Convert human readable amount to wei string\nexport function parseEther(amount: string | number): string {\n const value = typeof amount === 'string' ? parseFloat(amount) : amount;\n if (isNaN(value) || value < 0) {\n throw new Error('Invalid amount');\n }\n const wei = BigInt(Math.floor(value * 1e18));\n return wei.toString();\n}\n\n// Convert wei to human readable amount\nexport function formatEther(wei: string | bigint): string {\n const value = typeof wei === 'string' ? BigInt(wei) : wei;\n const ether = Number(value) / 1e18;\n return ether.toFixed(6).replace(/\\.?0+$/, '');\n}\n\n// Shorten address for display\nexport function shortenAddress(address: string): string {\n if (!address || address.length < 10) return address;\n return `${address.slice(0, 6)}...${address.slice(-4)}`;\n}\n\n// Get explorer URL for transaction\nexport function getExplorerUrl(chainId: number, txHash: string): string {\n const chain = getChainById(chainId);\n if (!chain) return '';\n return `${chain.explorerUrl}/tx/${txHash}`;\n}\n\n// Get chain config by ID\nexport function getChainById(chainId: number): ChainConfig | undefined {\n return SUPPORTED_CHAINS.find((c) => c.chainId === chainId);\n}\n\n// Get explorer URL for address\nexport function getAddressExplorerUrl(\n chainId: number,\n address: string\n): string {\n const chain = getChainById(chainId);\n if (!chain) return '';\n return `${chain.explorerUrl}/address/${address}`;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/validators.ts","../src/builders.ts","../src/constants.ts","../src/utils.ts"],"names":["z"],"mappings":"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","file":"index.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 {\n ActionButton,\n ActionDefinition,\n ActionMetadata,\n TransactionRequest,\n TransactionResponse,\n LinkedAction,\n TypedActionParameter,\n ActionParameter,\n ActionParameterSelectable,\n ActionParameterOption,\n ActionParameterType,\n SelectableParameterType,\n ActionLinks,\n} from './types';\nimport { validateTransactionRequest } from './validators';\n\n// Create a button action\nexport function button(config: {\n label: string;\n value: string;\n disabled?: boolean;\n}): ActionButton {\n return {\n label: config.label,\n value: config.value,\n type: 'button',\n disabled: config.disabled,\n };\n}\n\n// Create an input action\nexport function input(config: {\n label: string;\n placeholder?: string;\n disabled?: boolean;\n}): ActionButton {\n return {\n label: config.label,\n value: '__input__',\n type: 'input',\n placeholder: config.placeholder,\n disabled: config.disabled,\n };\n}\n\n// =============================================================================\n// SOLANA-STYLE LINKED ACTIONS & PARAMETERS BUILDERS\n// =============================================================================\n\n/**\n * Create a linked action with optional parameters\n * Uses Solana-style href templates with {parameter} placeholders\n *\n * @example\n * ```ts\n * linkedAction({\n * href: '/api/swap?amount={amount}&token={token}',\n * label: 'Swap Tokens',\n * parameters: [\n * textParam({ name: 'amount', label: 'Amount', required: true }),\n * selectParam({\n * name: 'token',\n * label: 'Token',\n * options: [\n * { label: 'USDC', value: '0x...' },\n * { label: 'USDT', value: '0x...' }\n * ]\n * })\n * ]\n * })\n * ```\n */\nexport function linkedAction(config: {\n href: string;\n label: string;\n disabled?: boolean;\n parameters?: TypedActionParameter[];\n}): LinkedAction {\n return {\n type: 'transaction',\n href: config.href,\n label: config.label,\n disabled: config.disabled,\n parameters: config.parameters,\n };\n}\n\n/**\n * Create a simple linked action button (no parameters, just a static href)\n *\n * @example\n * ```ts\n * actionButton({\n * href: '/api/tip?amount=1',\n * label: 'Tip 1 MNT'\n * })\n * ```\n */\nexport function actionButton(config: {\n href: string;\n label: string;\n disabled?: boolean;\n}): LinkedAction {\n return {\n type: 'transaction',\n href: config.href,\n label: config.label,\n disabled: config.disabled,\n };\n}\n\n/**\n * Create a text parameter\n */\nexport function textParam(config: {\n name: string;\n label?: string;\n required?: boolean;\n pattern?: string;\n patternDescription?: string;\n}): ActionParameter {\n return {\n type: 'text',\n name: config.name,\n label: config.label,\n required: config.required,\n pattern: config.pattern,\n patternDescription: config.patternDescription,\n };\n}\n\n/**\n * Create a number parameter\n */\nexport function numberParam(config: {\n name: string;\n label?: string;\n required?: boolean;\n min?: number | string;\n max?: number | string;\n}): ActionParameter {\n return {\n type: 'number',\n name: config.name,\n label: config.label,\n required: config.required,\n min: config.min,\n max: config.max,\n };\n}\n\n/**\n * Create an amount parameter (for token/ETH amounts)\n */\nexport function amountParam(config: {\n name: string;\n label?: string;\n required?: boolean;\n min?: number | string;\n max?: number | string;\n}): ActionParameter {\n return {\n type: 'amount',\n name: config.name,\n label: config.label || 'Amount',\n required: config.required,\n min: config.min,\n max: config.max,\n };\n}\n\n/**\n * Create an address parameter (for wallet addresses)\n */\nexport function addressParam(config: {\n name: string;\n label?: string;\n required?: boolean;\n}): ActionParameter {\n return {\n type: 'address',\n name: config.name,\n label: config.label || 'Address',\n required: config.required,\n pattern: '^0x[a-fA-F0-9]{40}$',\n patternDescription: 'Valid Ethereum address (0x...)',\n };\n}\n\n/**\n * Create a select dropdown parameter\n */\nexport function selectParam(config: {\n name: string;\n label?: string;\n required?: boolean;\n options: ActionParameterOption[];\n}): ActionParameterSelectable {\n return {\n type: 'select',\n name: config.name,\n label: config.label,\n required: config.required,\n options: config.options,\n };\n}\n\n/**\n * Create a radio button group parameter\n */\nexport function radioParam(config: {\n name: string;\n label?: string;\n required?: boolean;\n options: ActionParameterOption[];\n}): ActionParameterSelectable {\n return {\n type: 'radio',\n name: config.name,\n label: config.label,\n required: config.required,\n options: config.options,\n };\n}\n\n/**\n * Create a checkbox parameter (multiple selection)\n */\nexport function checkboxParam(config: {\n name: string;\n label?: string;\n required?: boolean;\n options: ActionParameterOption[];\n}): ActionParameterSelectable {\n return {\n type: 'checkbox',\n name: config.name,\n label: config.label,\n required: config.required,\n options: config.options,\n };\n}\n\n/**\n * Create a date parameter\n */\nexport function dateParam(config: {\n name: string;\n label?: string;\n required?: boolean;\n min?: string;\n max?: string;\n}): ActionParameter {\n return {\n type: 'date',\n name: config.name,\n label: config.label,\n required: config.required,\n min: config.min,\n max: config.max,\n };\n}\n\n/**\n * Create a textarea parameter (multi-line text)\n */\nexport function textareaParam(config: {\n name: string;\n label?: string;\n required?: boolean;\n}): ActionParameter {\n return {\n type: 'textarea',\n name: config.name,\n label: config.label,\n required: config.required,\n };\n}\n\n/**\n * Create an option for select/radio/checkbox parameters\n */\nexport function option(\n label: string,\n value: string,\n selected?: boolean\n): ActionParameterOption {\n return { label, value, selected };\n}\n\n/**\n * Create a links object with actions array\n *\n * @example\n * ```ts\n * createLinks([\n * actionButton({ href: '/api/tip?amount=1', label: 'Tip 1 MNT' }),\n * actionButton({ href: '/api/tip?amount=5', label: 'Tip 5 MNT' }),\n * linkedAction({\n * href: '/api/tip?amount={amount}',\n * label: 'Custom Amount',\n * parameters: [amountParam({ name: 'amount', required: true })]\n * })\n * ])\n * ```\n */\nexport function createLinks(actions: LinkedAction[]): ActionLinks {\n return { actions };\n}\n\n/**\n * Replace placeholders in href template with parameter values\n *\n * @example\n * ```ts\n * buildHref('/api/swap?amount={amount}&token={token}', { amount: '100', token: '0x...' })\n * // Returns: '/api/swap?amount=100&token=0x...'\n * ```\n */\nexport function buildHref(\n template: string,\n params: Record<string, string | string[]>\n): string {\n let result = template;\n for (const [key, value] of Object.entries(params)) {\n const placeholder = `{${key}}`;\n const replacement = Array.isArray(value) ? value.join(',') : value;\n result = result.replace(new RegExp(placeholder, 'g'), encodeURIComponent(replacement));\n }\n return result;\n}\n\n/**\n * Extract parameter names from href template\n *\n * @example\n * ```ts\n * extractParams('/api/swap?amount={amount}&token={token}')\n * // Returns: ['amount', 'token']\n * ```\n */\nexport function extractParams(template: string): string[] {\n const matches = template.match(/\\{([^}]+)\\}/g);\n if (!matches) return [];\n return matches.map((m) => m.slice(1, -1));\n}\n\n/**\n * Check if a linked action has parameters that need to be collected\n */\nexport function hasParameters(action: LinkedAction): boolean {\n return Boolean(action.parameters && action.parameters.length > 0);\n}\n\n/**\n * Check if a parameter is selectable (select/radio/checkbox)\n */\nexport function isSelectableParam(\n param: TypedActionParameter\n): param is ActionParameterSelectable {\n return param.type === 'select' || param.type === 'radio' || param.type === 'checkbox';\n}\n\n// Action object returned by createAction\nexport interface Action {\n getMetadata(): ActionMetadata;\n handleRequest(request: TransactionRequest): Promise<TransactionResponse>;\n}\n\n/**\n * Extended action definition that supports both legacy actions and linked actions\n */\nexport interface ExtendedActionDefinition extends Omit<ActionDefinition, 'actions'> {\n /** Primary button label */\n label?: string;\n /** Legacy actions array (backwards compatible) */\n actions?: ActionButton[];\n /** Solana-style linked actions */\n links?: ActionLinks;\n}\n\n/**\n * Create a complete action with support for both legacy and Solana-style linked actions\n *\n * @example Legacy style (backwards compatible):\n * ```ts\n * createAction({\n * title: 'Tip',\n * icon: 'https://...',\n * description: 'Send a tip',\n * actions: [\n * button({ label: '1 MNT', value: '1' }),\n * input({ label: 'Custom' })\n * ],\n * handler: async (ctx) => ({ transaction: {...} })\n * })\n * ```\n *\n * @example Solana-style linked actions:\n * ```ts\n * createAction({\n * title: 'Swap Tokens',\n * icon: 'https://...',\n * description: 'Swap tokens on DEX',\n * links: createLinks([\n * actionButton({ href: '/api/swap?amount=10', label: 'Swap 10' }),\n * linkedAction({\n * href: '/api/swap?amount={amount}&token={token}',\n * label: 'Custom Swap',\n * parameters: [\n * amountParam({ name: 'amount', required: true }),\n * selectParam({ name: 'token', options: [...] })\n * ]\n * })\n * ]),\n * handler: async (ctx) => ({ transaction: {...} })\n * })\n * ```\n */\nexport function createAction(definition: ExtendedActionDefinition): Action {\n // Validate definition\n if (!definition.title) throw new Error('Action title is required');\n if (!definition.icon) throw new Error('Action icon is required');\n if (!definition.description) throw new Error('Action description is required');\n\n // Must have either actions or links\n const hasLegacyActions = definition.actions && definition.actions.length > 0;\n const hasLinkedActions = definition.links?.actions && definition.links.actions.length > 0;\n\n if (!hasLegacyActions && !hasLinkedActions) {\n throw new Error('At least one action or linked action is required');\n }\n\n if (typeof definition.handler !== 'function') {\n throw new Error('Handler must be a function');\n }\n\n return {\n getMetadata(): ActionMetadata {\n return {\n type: 'action',\n title: definition.title,\n icon: definition.icon,\n description: definition.description,\n label: definition.label,\n actions: definition.actions,\n links: definition.links,\n disabled: definition.disabled,\n };\n },\n\n async handleRequest(\n request: TransactionRequest\n ): Promise<TransactionResponse> {\n // Validate request\n const validation = validateTransactionRequest(request);\n if (!validation.success) {\n throw new Error(validation.error);\n }\n\n // Handle legacy actions\n if (definition.actions) {\n const selectedAction = definition.actions.find(\n (a) => a.value === request.action || (a.type === 'input' && request.action === '__input__')\n );\n\n if (selectedAction) {\n // If input type, require input value\n if (selectedAction.type === 'input' && !request.input) {\n throw new Error('Input value is required');\n }\n }\n }\n\n // Call handler with full context including data\n const response = await definition.handler({\n account: request.account,\n action: request.action,\n input: request.input,\n data: request.data,\n });\n\n return response;\n },\n };\n}\n","import type { ChainConfig } from './types';\n\nexport const MANTLE_MAINNET: ChainConfig = {\n chainId: 5000,\n name: 'Mantle',\n rpcUrl: 'https://rpc.mantle.xyz',\n explorerUrl: 'https://mantlescan.xyz',\n nativeCurrency: {\n name: 'MNT',\n symbol: 'MNT',\n decimals: 18,\n },\n};\n\nexport const MANTLE_SEPOLIA: ChainConfig = {\n chainId: 5003,\n name: 'Mantle Sepolia',\n rpcUrl: 'https://rpc.sepolia.mantle.xyz',\n explorerUrl: 'https://sepolia.mantlescan.xyz',\n nativeCurrency: {\n name: 'MNT',\n symbol: 'MNT',\n decimals: 18,\n },\n};\n\nexport const SUPPORTED_CHAINS: ChainConfig[] = [MANTLE_MAINNET, MANTLE_SEPOLIA];\n\nexport const DEFAULT_CHAIN = MANTLE_SEPOLIA;\n\nexport const BLINK_BASE_URL = 'https://blink.mantle.xyz';\n\nexport const ACTION_QUERY_PARAM = 'action';\n\n// Registry URL for validation\nexport const REGISTRY_URL = 'https://mlinks-fe.vercel.app';\nexport const REGISTRY_VALIDATE_ENDPOINT = '/api/registry/validate';\n","import {\n BLINK_BASE_URL,\n ACTION_QUERY_PARAM,\n SUPPORTED_CHAINS,\n} from './constants';\nimport type { ChainConfig } from './types';\n\n// Create Blink URL from Action URL\nexport function createBlinkUrl(\n actionUrl: string,\n baseUrl: string = BLINK_BASE_URL\n): string {\n // Validate actionUrl is a valid URL\n try {\n new URL(actionUrl);\n } catch {\n throw new Error('Invalid action URL');\n }\n\n const encodedAction = encodeURIComponent(actionUrl);\n return `${baseUrl}/mlink?${ACTION_QUERY_PARAM}=${encodedAction}`;\n}\n\n// Parse Blink URL to extract Action URL\nexport function parseBlinkUrl(blinkUrl: string): string | null {\n try {\n const url = new URL(blinkUrl);\n const actionParam = url.searchParams.get(ACTION_QUERY_PARAM);\n\n if (!actionParam) return null;\n\n const actionUrl = decodeURIComponent(actionParam);\n\n // Validate it's a valid URL\n new URL(actionUrl);\n\n return actionUrl;\n } catch {\n return null;\n }\n}\n\n// Check if URL is a valid Blink URL\nexport function isBlinkUrl(url: string): boolean {\n return parseBlinkUrl(url) !== null;\n}\n\n// Convert human readable amount to wei string\nexport function parseEther(amount: string | number): string {\n const value = typeof amount === 'string' ? parseFloat(amount) : amount;\n if (isNaN(value) || value < 0) {\n throw new Error('Invalid amount');\n }\n const wei = BigInt(Math.floor(value * 1e18));\n return wei.toString();\n}\n\n// Convert wei to human readable amount\nexport function formatEther(wei: string | bigint): string {\n const value = typeof wei === 'string' ? BigInt(wei) : wei;\n const ether = Number(value) / 1e18;\n return ether.toFixed(6).replace(/\\.?0+$/, '');\n}\n\n// Shorten address for display\nexport function shortenAddress(address: string): string {\n if (!address || address.length < 10) return address;\n return `${address.slice(0, 6)}...${address.slice(-4)}`;\n}\n\n// Get explorer URL for transaction\nexport function getExplorerUrl(chainId: number, txHash: string): string {\n const chain = getChainById(chainId);\n if (!chain) return '';\n return `${chain.explorerUrl}/tx/${txHash}`;\n}\n\n// Get chain config by ID\nexport function getChainById(chainId: number): ChainConfig | undefined {\n return SUPPORTED_CHAINS.find((c) => c.chainId === chainId);\n}\n\n// Get explorer URL for address\nexport function getAddressExplorerUrl(\n chainId: number,\n address: string\n): string {\n const chain = getChainById(chainId);\n if (!chain) return '';\n return `${chain.explorerUrl}/address/${address}`;\n}\n"]}
|