@dipansrimany/mlink-sdk 0.1.0 → 0.3.0
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/README.md +5 -5
- package/dist/adapters/express.d.mts +2 -1
- package/dist/adapters/express.d.ts +2 -1
- package/dist/adapters/next.d.mts +2 -1
- package/dist/adapters/next.d.ts +2 -1
- package/dist/builders-CJNt88dM.d.ts +19 -0
- package/dist/builders-CN5ijFpW.d.mts +19 -0
- package/dist/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/react/index.d.mts +208 -0
- package/dist/react/index.d.ts +208 -0
- package/dist/react/index.js +580 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/index.mjs +565 -0
- package/dist/react/index.mjs.map +1 -0
- package/dist/styles.css +339 -0
- package/dist/{builders-OoJ5KB_g.d.mts → types-CAnUIaVe.d.mts} +1 -17
- package/dist/{builders-OoJ5KB_g.d.ts → types-CAnUIaVe.d.ts} +1 -17
- package/package.json +27 -7
|
@@ -0,0 +1,580 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var zod = require('zod');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
|
|
7
|
+
// src/constants.ts
|
|
8
|
+
var MANTLE_SEPOLIA = {
|
|
9
|
+
chainId: 5003,
|
|
10
|
+
name: "Mantle Sepolia",
|
|
11
|
+
rpcUrl: "https://rpc.sepolia.mantle.xyz",
|
|
12
|
+
explorerUrl: "https://sepolia.mantlescan.xyz",
|
|
13
|
+
nativeCurrency: {
|
|
14
|
+
name: "MNT",
|
|
15
|
+
symbol: "MNT",
|
|
16
|
+
decimals: 18
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
var DEFAULT_CHAIN = MANTLE_SEPOLIA;
|
|
20
|
+
var ACTION_QUERY_PARAM = "action";
|
|
21
|
+
|
|
22
|
+
// src/utils.ts
|
|
23
|
+
function parseBlinkUrl(blinkUrl) {
|
|
24
|
+
try {
|
|
25
|
+
const url = new URL(blinkUrl);
|
|
26
|
+
const actionParam = url.searchParams.get(ACTION_QUERY_PARAM);
|
|
27
|
+
if (!actionParam) return null;
|
|
28
|
+
const actionUrl = decodeURIComponent(actionParam);
|
|
29
|
+
new URL(actionUrl);
|
|
30
|
+
return actionUrl;
|
|
31
|
+
} catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
var addressRegex = /^0x[a-fA-F0-9]{40}$/;
|
|
36
|
+
var hexRegex = /^0x[a-fA-F0-9]*$/;
|
|
37
|
+
var ActionButtonSchema = zod.z.object({
|
|
38
|
+
label: zod.z.string().min(1).max(50),
|
|
39
|
+
value: zod.z.string().min(1),
|
|
40
|
+
type: zod.z.enum(["button", "input"]),
|
|
41
|
+
placeholder: zod.z.string().optional(),
|
|
42
|
+
disabled: zod.z.boolean().optional()
|
|
43
|
+
});
|
|
44
|
+
var ActionMetadataSchema = zod.z.object({
|
|
45
|
+
title: zod.z.string().min(1).max(100),
|
|
46
|
+
icon: zod.z.string().url(),
|
|
47
|
+
description: zod.z.string().min(1).max(500),
|
|
48
|
+
actions: zod.z.array(ActionButtonSchema).min(1),
|
|
49
|
+
disabled: zod.z.boolean().optional(),
|
|
50
|
+
error: zod.z.object({ message: zod.z.string() }).optional()
|
|
51
|
+
});
|
|
52
|
+
zod.z.object({
|
|
53
|
+
account: zod.z.string().regex(addressRegex, "Invalid Ethereum address"),
|
|
54
|
+
action: zod.z.string().min(1),
|
|
55
|
+
input: zod.z.string().optional()
|
|
56
|
+
});
|
|
57
|
+
var EVMTransactionSchema = zod.z.object({
|
|
58
|
+
to: zod.z.string().regex(addressRegex, "Invalid to address"),
|
|
59
|
+
value: zod.z.string(),
|
|
60
|
+
data: zod.z.string().regex(hexRegex, "Invalid hex data"),
|
|
61
|
+
chainId: zod.z.number().positive()
|
|
62
|
+
});
|
|
63
|
+
var TransactionResponseSchema = zod.z.object({
|
|
64
|
+
transaction: EVMTransactionSchema,
|
|
65
|
+
message: zod.z.string().optional()
|
|
66
|
+
});
|
|
67
|
+
function validateActionMetadata(data) {
|
|
68
|
+
const result = ActionMetadataSchema.safeParse(data);
|
|
69
|
+
if (result.success) {
|
|
70
|
+
return { success: true, data: result.data };
|
|
71
|
+
}
|
|
72
|
+
return { success: false, error: result.error.message };
|
|
73
|
+
}
|
|
74
|
+
function validateTransactionResponse(data) {
|
|
75
|
+
const result = TransactionResponseSchema.safeParse(data);
|
|
76
|
+
if (result.success) {
|
|
77
|
+
return { success: true, data: result.data };
|
|
78
|
+
}
|
|
79
|
+
return { success: false, error: result.error.message };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/react/useMlink.ts
|
|
83
|
+
var DEFAULT_REFRESH_INTERVAL = 10 * 60 * 1e3;
|
|
84
|
+
function useMlink(url, options = {}) {
|
|
85
|
+
const { refreshInterval = DEFAULT_REFRESH_INTERVAL, enabled = true } = options;
|
|
86
|
+
const [status, setStatus] = react.useState("idle");
|
|
87
|
+
const [metadata, setMetadata] = react.useState(null);
|
|
88
|
+
const [error, setError] = react.useState(null);
|
|
89
|
+
const abortControllerRef = react.useRef(null);
|
|
90
|
+
const intervalRef = react.useRef(null);
|
|
91
|
+
const actionUrl = parseBlinkUrl(url) || url;
|
|
92
|
+
const fetchMetadata = react.useCallback(async () => {
|
|
93
|
+
if (!actionUrl || !enabled) return;
|
|
94
|
+
if (abortControllerRef.current) {
|
|
95
|
+
abortControllerRef.current.abort();
|
|
96
|
+
}
|
|
97
|
+
abortControllerRef.current = new AbortController();
|
|
98
|
+
setStatus("loading");
|
|
99
|
+
setError(null);
|
|
100
|
+
try {
|
|
101
|
+
const response = await fetch(actionUrl, {
|
|
102
|
+
method: "GET",
|
|
103
|
+
headers: {
|
|
104
|
+
Accept: "application/json"
|
|
105
|
+
},
|
|
106
|
+
signal: abortControllerRef.current.signal
|
|
107
|
+
});
|
|
108
|
+
if (!response.ok) {
|
|
109
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
110
|
+
}
|
|
111
|
+
const data = await response.json();
|
|
112
|
+
const validation = validateActionMetadata(data);
|
|
113
|
+
if (!validation.success) {
|
|
114
|
+
throw new Error(`Invalid metadata: ${validation.error}`);
|
|
115
|
+
}
|
|
116
|
+
setMetadata(validation.data);
|
|
117
|
+
setStatus("ready");
|
|
118
|
+
} catch (err) {
|
|
119
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const errorMessage = err instanceof Error ? err.message : "Failed to fetch mlink data";
|
|
123
|
+
setError(errorMessage);
|
|
124
|
+
setStatus("error");
|
|
125
|
+
}
|
|
126
|
+
}, [actionUrl, enabled]);
|
|
127
|
+
react.useEffect(() => {
|
|
128
|
+
if (enabled) {
|
|
129
|
+
fetchMetadata();
|
|
130
|
+
}
|
|
131
|
+
return () => {
|
|
132
|
+
if (abortControllerRef.current) {
|
|
133
|
+
abortControllerRef.current.abort();
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
}, [fetchMetadata, enabled]);
|
|
137
|
+
react.useEffect(() => {
|
|
138
|
+
if (!enabled || !refreshInterval) return;
|
|
139
|
+
intervalRef.current = setInterval(() => {
|
|
140
|
+
fetchMetadata();
|
|
141
|
+
}, refreshInterval);
|
|
142
|
+
return () => {
|
|
143
|
+
if (intervalRef.current) {
|
|
144
|
+
clearInterval(intervalRef.current);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
}, [fetchMetadata, refreshInterval, enabled]);
|
|
148
|
+
return {
|
|
149
|
+
status,
|
|
150
|
+
metadata,
|
|
151
|
+
error,
|
|
152
|
+
url: actionUrl,
|
|
153
|
+
refresh: fetchMetadata
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function useExecuteMlink(options) {
|
|
157
|
+
const { adapter, actionUrl, onSuccess, onError } = options;
|
|
158
|
+
const [status, setStatus] = react.useState("ready");
|
|
159
|
+
const [txHash, setTxHash] = react.useState(null);
|
|
160
|
+
const [error, setError] = react.useState(null);
|
|
161
|
+
const reset = react.useCallback(() => {
|
|
162
|
+
setStatus("ready");
|
|
163
|
+
setTxHash(null);
|
|
164
|
+
setError(null);
|
|
165
|
+
}, []);
|
|
166
|
+
const execute = react.useCallback(
|
|
167
|
+
async (action, input) => {
|
|
168
|
+
setStatus("executing");
|
|
169
|
+
setError(null);
|
|
170
|
+
setTxHash(null);
|
|
171
|
+
try {
|
|
172
|
+
let account = adapter.getAddress();
|
|
173
|
+
if (!adapter.isConnected() || !account) {
|
|
174
|
+
account = await adapter.connect();
|
|
175
|
+
}
|
|
176
|
+
const response = await fetch(actionUrl, {
|
|
177
|
+
method: "POST",
|
|
178
|
+
headers: {
|
|
179
|
+
"Content-Type": "application/json"
|
|
180
|
+
},
|
|
181
|
+
body: JSON.stringify({
|
|
182
|
+
account,
|
|
183
|
+
action,
|
|
184
|
+
input
|
|
185
|
+
})
|
|
186
|
+
});
|
|
187
|
+
if (!response.ok) {
|
|
188
|
+
const errorData = await response.json().catch(() => ({}));
|
|
189
|
+
throw new Error(
|
|
190
|
+
errorData.message || `HTTP ${response.status}: ${response.statusText}`
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
const data = await response.json();
|
|
194
|
+
const validation = validateTransactionResponse(data);
|
|
195
|
+
if (!validation.success) {
|
|
196
|
+
throw new Error(`Invalid response: ${validation.error}`);
|
|
197
|
+
}
|
|
198
|
+
const hash = await adapter.signAndSendTransaction(data.transaction);
|
|
199
|
+
setTxHash(hash);
|
|
200
|
+
setStatus("success");
|
|
201
|
+
onSuccess?.(hash, action);
|
|
202
|
+
return {
|
|
203
|
+
success: true,
|
|
204
|
+
txHash: hash,
|
|
205
|
+
message: data.message
|
|
206
|
+
};
|
|
207
|
+
} catch (err) {
|
|
208
|
+
const errorMessage = err instanceof Error ? err.message : "Transaction failed";
|
|
209
|
+
setError(errorMessage);
|
|
210
|
+
setStatus("error");
|
|
211
|
+
onError?.(errorMessage);
|
|
212
|
+
return {
|
|
213
|
+
success: false,
|
|
214
|
+
error: errorMessage
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
[adapter, actionUrl, onSuccess, onError]
|
|
219
|
+
);
|
|
220
|
+
return {
|
|
221
|
+
execute,
|
|
222
|
+
status,
|
|
223
|
+
txHash,
|
|
224
|
+
error,
|
|
225
|
+
reset
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// src/react/themes.ts
|
|
230
|
+
var lightTheme = {
|
|
231
|
+
// Colors
|
|
232
|
+
"--mlink-bg-primary": "#ffffff",
|
|
233
|
+
"--mlink-bg-secondary": "#f8f9fa",
|
|
234
|
+
"--mlink-border-color": "#e9ecef",
|
|
235
|
+
"--mlink-text-primary": "#212529",
|
|
236
|
+
"--mlink-text-secondary": "#6c757d",
|
|
237
|
+
"--mlink-text-link": "#0d6efd",
|
|
238
|
+
"--mlink-button-bg": "#212529",
|
|
239
|
+
"--mlink-button-text": "#ffffff",
|
|
240
|
+
"--mlink-button-hover": "#343a40",
|
|
241
|
+
"--mlink-button-disabled": "#adb5bd",
|
|
242
|
+
"--mlink-input-bg": "#ffffff",
|
|
243
|
+
"--mlink-input-border": "#ced4da",
|
|
244
|
+
"--mlink-input-text": "#212529",
|
|
245
|
+
"--mlink-input-placeholder": "#adb5bd",
|
|
246
|
+
"--mlink-success": "#198754",
|
|
247
|
+
"--mlink-error": "#dc3545",
|
|
248
|
+
"--mlink-warning": "#ffc107",
|
|
249
|
+
// Sizing
|
|
250
|
+
"--mlink-border-radius": "12px",
|
|
251
|
+
"--mlink-button-radius": "8px",
|
|
252
|
+
"--mlink-input-radius": "8px",
|
|
253
|
+
// Shadows
|
|
254
|
+
"--mlink-shadow": "0 2px 8px rgba(0, 0, 0, 0.08)"
|
|
255
|
+
};
|
|
256
|
+
var darkTheme = {
|
|
257
|
+
// Colors
|
|
258
|
+
"--mlink-bg-primary": "#1a1a1a",
|
|
259
|
+
"--mlink-bg-secondary": "#2d2d2d",
|
|
260
|
+
"--mlink-border-color": "#404040",
|
|
261
|
+
"--mlink-text-primary": "#ffffff",
|
|
262
|
+
"--mlink-text-secondary": "#a0a0a0",
|
|
263
|
+
"--mlink-text-link": "#60a5fa",
|
|
264
|
+
"--mlink-button-bg": "#ffffff",
|
|
265
|
+
"--mlink-button-text": "#1a1a1a",
|
|
266
|
+
"--mlink-button-hover": "#e5e5e5",
|
|
267
|
+
"--mlink-button-disabled": "#525252",
|
|
268
|
+
"--mlink-input-bg": "#2d2d2d",
|
|
269
|
+
"--mlink-input-border": "#404040",
|
|
270
|
+
"--mlink-input-text": "#ffffff",
|
|
271
|
+
"--mlink-input-placeholder": "#6b7280",
|
|
272
|
+
"--mlink-success": "#22c55e",
|
|
273
|
+
"--mlink-error": "#ef4444",
|
|
274
|
+
"--mlink-warning": "#f59e0b",
|
|
275
|
+
// Sizing
|
|
276
|
+
"--mlink-border-radius": "12px",
|
|
277
|
+
"--mlink-button-radius": "8px",
|
|
278
|
+
"--mlink-input-radius": "8px",
|
|
279
|
+
// Shadows
|
|
280
|
+
"--mlink-shadow": "0 2px 8px rgba(0, 0, 0, 0.3)"
|
|
281
|
+
};
|
|
282
|
+
var mantleTheme = {
|
|
283
|
+
// Colors - Mantle brand colors
|
|
284
|
+
"--mlink-bg-primary": "#0a0a0a",
|
|
285
|
+
"--mlink-bg-secondary": "#141414",
|
|
286
|
+
"--mlink-border-color": "#2a2a2a",
|
|
287
|
+
"--mlink-text-primary": "#ffffff",
|
|
288
|
+
"--mlink-text-secondary": "#9ca3af",
|
|
289
|
+
"--mlink-text-link": "#65d9e4",
|
|
290
|
+
"--mlink-button-bg": "#65d9e4",
|
|
291
|
+
"--mlink-button-text": "#000000",
|
|
292
|
+
"--mlink-button-hover": "#85e3ec",
|
|
293
|
+
"--mlink-button-disabled": "#374151",
|
|
294
|
+
"--mlink-input-bg": "#1f1f1f",
|
|
295
|
+
"--mlink-input-border": "#374151",
|
|
296
|
+
"--mlink-input-text": "#ffffff",
|
|
297
|
+
"--mlink-input-placeholder": "#6b7280",
|
|
298
|
+
"--mlink-success": "#34d399",
|
|
299
|
+
"--mlink-error": "#f87171",
|
|
300
|
+
"--mlink-warning": "#fbbf24",
|
|
301
|
+
// Sizing
|
|
302
|
+
"--mlink-border-radius": "16px",
|
|
303
|
+
"--mlink-button-radius": "10px",
|
|
304
|
+
"--mlink-input-radius": "10px",
|
|
305
|
+
// Shadows
|
|
306
|
+
"--mlink-shadow": "0 4px 16px rgba(101, 217, 228, 0.1)"
|
|
307
|
+
};
|
|
308
|
+
var themePresets = {
|
|
309
|
+
light: lightTheme,
|
|
310
|
+
dark: darkTheme,
|
|
311
|
+
mantle: mantleTheme
|
|
312
|
+
};
|
|
313
|
+
function resolveTheme(theme) {
|
|
314
|
+
if (!theme) {
|
|
315
|
+
return darkTheme;
|
|
316
|
+
}
|
|
317
|
+
if (typeof theme === "string") {
|
|
318
|
+
return themePresets[theme] || darkTheme;
|
|
319
|
+
}
|
|
320
|
+
return { ...darkTheme, ...theme };
|
|
321
|
+
}
|
|
322
|
+
function themeToCSS(theme) {
|
|
323
|
+
return theme;
|
|
324
|
+
}
|
|
325
|
+
var MlinkContext = react.createContext(null);
|
|
326
|
+
function MlinkProvider({
|
|
327
|
+
children,
|
|
328
|
+
theme,
|
|
329
|
+
defaultChain = DEFAULT_CHAIN
|
|
330
|
+
}) {
|
|
331
|
+
const resolvedTheme = react.useMemo(() => resolveTheme(theme), [theme]);
|
|
332
|
+
const value = react.useMemo(
|
|
333
|
+
() => ({
|
|
334
|
+
theme: resolvedTheme,
|
|
335
|
+
defaultChain
|
|
336
|
+
}),
|
|
337
|
+
[resolvedTheme, defaultChain]
|
|
338
|
+
);
|
|
339
|
+
return /* @__PURE__ */ jsxRuntime.jsx(MlinkContext.Provider, { value, children });
|
|
340
|
+
}
|
|
341
|
+
function useMlinkContext() {
|
|
342
|
+
const context = react.useContext(MlinkContext);
|
|
343
|
+
if (!context) {
|
|
344
|
+
return {
|
|
345
|
+
theme: resolveTheme("dark"),
|
|
346
|
+
defaultChain: DEFAULT_CHAIN
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
return context;
|
|
350
|
+
}
|
|
351
|
+
function Mlink({
|
|
352
|
+
url,
|
|
353
|
+
adapter,
|
|
354
|
+
theme: themeProp,
|
|
355
|
+
onSuccess,
|
|
356
|
+
onError,
|
|
357
|
+
className = "",
|
|
358
|
+
stylePreset = "default"
|
|
359
|
+
}) {
|
|
360
|
+
const context = useMlinkContext();
|
|
361
|
+
const resolvedTheme = themeProp ? resolveTheme(themeProp) : context.theme;
|
|
362
|
+
const { status: fetchStatus, metadata, error: fetchError } = useMlink(url);
|
|
363
|
+
const {
|
|
364
|
+
execute,
|
|
365
|
+
status: execStatus,
|
|
366
|
+
txHash,
|
|
367
|
+
error: execError,
|
|
368
|
+
reset
|
|
369
|
+
} = useExecuteMlink({
|
|
370
|
+
adapter,
|
|
371
|
+
actionUrl: url,
|
|
372
|
+
onSuccess,
|
|
373
|
+
onError
|
|
374
|
+
});
|
|
375
|
+
const [inputValues, setInputValues] = react.useState({});
|
|
376
|
+
const handleInputChange = react.useCallback((actionValue, value) => {
|
|
377
|
+
setInputValues((prev) => ({ ...prev, [actionValue]: value }));
|
|
378
|
+
}, []);
|
|
379
|
+
const handleAction = react.useCallback(
|
|
380
|
+
async (action) => {
|
|
381
|
+
const input = action.type === "input" ? inputValues[action.value] : void 0;
|
|
382
|
+
await execute(action.value, input);
|
|
383
|
+
},
|
|
384
|
+
[execute, inputValues]
|
|
385
|
+
);
|
|
386
|
+
if (fetchStatus === "loading") {
|
|
387
|
+
return /* @__PURE__ */ jsxRuntime.jsx(MlinkContainer, { theme: resolvedTheme, className, preset: stylePreset, children: /* @__PURE__ */ jsxRuntime.jsx(MlinkSkeleton, {}) });
|
|
388
|
+
}
|
|
389
|
+
if (fetchStatus === "error" || !metadata) {
|
|
390
|
+
return /* @__PURE__ */ jsxRuntime.jsx(MlinkContainer, { theme: resolvedTheme, className, preset: stylePreset, children: /* @__PURE__ */ jsxRuntime.jsx(MlinkError, { message: fetchError || "Failed to load action" }) });
|
|
391
|
+
}
|
|
392
|
+
if (execStatus === "success" && txHash) {
|
|
393
|
+
return /* @__PURE__ */ jsxRuntime.jsx(MlinkContainer, { theme: resolvedTheme, className, preset: stylePreset, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
394
|
+
MlinkSuccess,
|
|
395
|
+
{
|
|
396
|
+
message: metadata.title,
|
|
397
|
+
txHash,
|
|
398
|
+
onReset: reset
|
|
399
|
+
}
|
|
400
|
+
) });
|
|
401
|
+
}
|
|
402
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(MlinkContainer, { theme: resolvedTheme, className, preset: stylePreset, children: [
|
|
403
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mlink-icon", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: metadata.icon, alt: metadata.title }) }),
|
|
404
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mlink-content", children: [
|
|
405
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mlink-title", children: metadata.title }),
|
|
406
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mlink-description", children: metadata.description })
|
|
407
|
+
] }),
|
|
408
|
+
execError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mlink-error-banner", children: execError }),
|
|
409
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mlink-actions", children: metadata.actions.map((action, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
410
|
+
ActionButtonComponent,
|
|
411
|
+
{
|
|
412
|
+
action,
|
|
413
|
+
inputValue: inputValues[action.value] || "",
|
|
414
|
+
onInputChange: (value) => handleInputChange(action.value, value),
|
|
415
|
+
onExecute: () => handleAction(action),
|
|
416
|
+
loading: execStatus === "executing",
|
|
417
|
+
disabled: metadata.disabled === true || action.disabled === true
|
|
418
|
+
},
|
|
419
|
+
`${action.value}-${index}`
|
|
420
|
+
)) })
|
|
421
|
+
] });
|
|
422
|
+
}
|
|
423
|
+
function MlinkContainer({ theme, className, preset, children }) {
|
|
424
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
425
|
+
"div",
|
|
426
|
+
{
|
|
427
|
+
className: `mlink-container mlink-${preset} ${className}`,
|
|
428
|
+
style: themeToCSS(theme),
|
|
429
|
+
children
|
|
430
|
+
}
|
|
431
|
+
);
|
|
432
|
+
}
|
|
433
|
+
function MlinkSkeleton() {
|
|
434
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mlink-skeleton", children: [
|
|
435
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mlink-skeleton-icon" }),
|
|
436
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mlink-skeleton-content", children: [
|
|
437
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mlink-skeleton-title" }),
|
|
438
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mlink-skeleton-description" })
|
|
439
|
+
] }),
|
|
440
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mlink-skeleton-button" })
|
|
441
|
+
] });
|
|
442
|
+
}
|
|
443
|
+
function MlinkError({ message }) {
|
|
444
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mlink-error", children: [
|
|
445
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mlink-error-icon", children: "!" }),
|
|
446
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mlink-error-message", children: message })
|
|
447
|
+
] });
|
|
448
|
+
}
|
|
449
|
+
function MlinkSuccess({ message, txHash, onReset }) {
|
|
450
|
+
const shortHash = `${txHash.slice(0, 10)}...${txHash.slice(-8)}`;
|
|
451
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mlink-success", children: [
|
|
452
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mlink-success-icon", children: "\u2713" }),
|
|
453
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mlink-success-title", children: "Transaction Sent" }),
|
|
454
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mlink-success-message", children: message }),
|
|
455
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: "mlink-success-hash", children: shortHash }),
|
|
456
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { className: "mlink-button mlink-button-secondary", onClick: onReset, children: "Done" })
|
|
457
|
+
] });
|
|
458
|
+
}
|
|
459
|
+
function ActionButtonComponent({
|
|
460
|
+
action,
|
|
461
|
+
inputValue,
|
|
462
|
+
onInputChange,
|
|
463
|
+
onExecute,
|
|
464
|
+
loading,
|
|
465
|
+
disabled
|
|
466
|
+
}) {
|
|
467
|
+
if (action.type === "input") {
|
|
468
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mlink-input-group", children: [
|
|
469
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
470
|
+
"input",
|
|
471
|
+
{
|
|
472
|
+
type: "text",
|
|
473
|
+
className: "mlink-input",
|
|
474
|
+
placeholder: action.placeholder || action.label,
|
|
475
|
+
value: inputValue,
|
|
476
|
+
onChange: (e) => onInputChange(e.target.value),
|
|
477
|
+
disabled: disabled || loading
|
|
478
|
+
}
|
|
479
|
+
),
|
|
480
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
481
|
+
"button",
|
|
482
|
+
{
|
|
483
|
+
className: "mlink-button",
|
|
484
|
+
onClick: onExecute,
|
|
485
|
+
disabled: disabled || loading || !inputValue.trim(),
|
|
486
|
+
children: loading ? /* @__PURE__ */ jsxRuntime.jsx(MlinkSpinner, {}) : action.label
|
|
487
|
+
}
|
|
488
|
+
)
|
|
489
|
+
] });
|
|
490
|
+
}
|
|
491
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
492
|
+
"button",
|
|
493
|
+
{
|
|
494
|
+
className: "mlink-button",
|
|
495
|
+
onClick: onExecute,
|
|
496
|
+
disabled: disabled || loading,
|
|
497
|
+
children: loading ? /* @__PURE__ */ jsxRuntime.jsx(MlinkSpinner, {}) : action.label
|
|
498
|
+
}
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
function MlinkSpinner() {
|
|
502
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mlink-spinner" });
|
|
503
|
+
}
|
|
504
|
+
var Mlink_default = Mlink;
|
|
505
|
+
function useMlinkWagmiAdapter(config) {
|
|
506
|
+
const { address, isConnected, connect, sendTransaction } = config;
|
|
507
|
+
return react.useMemo(
|
|
508
|
+
() => ({
|
|
509
|
+
connect: async () => {
|
|
510
|
+
await connect();
|
|
511
|
+
if (!address) {
|
|
512
|
+
throw new Error("Failed to connect wallet");
|
|
513
|
+
}
|
|
514
|
+
return address;
|
|
515
|
+
},
|
|
516
|
+
signAndSendTransaction: async (transaction) => {
|
|
517
|
+
const txHash = await sendTransaction({
|
|
518
|
+
to: transaction.to,
|
|
519
|
+
value: BigInt(transaction.value),
|
|
520
|
+
data: transaction.data,
|
|
521
|
+
chainId: transaction.chainId
|
|
522
|
+
});
|
|
523
|
+
return txHash;
|
|
524
|
+
},
|
|
525
|
+
isConnected: () => isConnected,
|
|
526
|
+
getAddress: () => address || null
|
|
527
|
+
}),
|
|
528
|
+
[address, isConnected, connect, sendTransaction]
|
|
529
|
+
);
|
|
530
|
+
}
|
|
531
|
+
function useMlinkEthersAdapter(config) {
|
|
532
|
+
const { signer, connect } = config;
|
|
533
|
+
return react.useMemo(
|
|
534
|
+
() => ({
|
|
535
|
+
connect: async () => {
|
|
536
|
+
await connect();
|
|
537
|
+
if (!signer) {
|
|
538
|
+
throw new Error("Failed to connect wallet");
|
|
539
|
+
}
|
|
540
|
+
return await signer.getAddress();
|
|
541
|
+
},
|
|
542
|
+
signAndSendTransaction: async (transaction) => {
|
|
543
|
+
if (!signer) {
|
|
544
|
+
throw new Error("Wallet not connected");
|
|
545
|
+
}
|
|
546
|
+
const tx = await signer.sendTransaction({
|
|
547
|
+
to: transaction.to,
|
|
548
|
+
value: BigInt(transaction.value),
|
|
549
|
+
data: transaction.data,
|
|
550
|
+
chainId: transaction.chainId
|
|
551
|
+
});
|
|
552
|
+
return tx.hash;
|
|
553
|
+
},
|
|
554
|
+
isConnected: () => signer !== null,
|
|
555
|
+
getAddress: () => null
|
|
556
|
+
// Ethers requires async call
|
|
557
|
+
}),
|
|
558
|
+
[signer, connect]
|
|
559
|
+
);
|
|
560
|
+
}
|
|
561
|
+
function createMlinkAdapter(adapter) {
|
|
562
|
+
return adapter;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
exports.Mlink = Mlink;
|
|
566
|
+
exports.MlinkComponent = Mlink_default;
|
|
567
|
+
exports.MlinkProvider = MlinkProvider;
|
|
568
|
+
exports.createMlinkAdapter = createMlinkAdapter;
|
|
569
|
+
exports.darkTheme = darkTheme;
|
|
570
|
+
exports.lightTheme = lightTheme;
|
|
571
|
+
exports.mantleTheme = mantleTheme;
|
|
572
|
+
exports.resolveTheme = resolveTheme;
|
|
573
|
+
exports.themePresets = themePresets;
|
|
574
|
+
exports.useExecuteMlink = useExecuteMlink;
|
|
575
|
+
exports.useMlink = useMlink;
|
|
576
|
+
exports.useMlinkContext = useMlinkContext;
|
|
577
|
+
exports.useMlinkEthersAdapter = useMlinkEthersAdapter;
|
|
578
|
+
exports.useMlinkWagmiAdapter = useMlinkWagmiAdapter;
|
|
579
|
+
//# sourceMappingURL=index.js.map
|
|
580
|
+
//# sourceMappingURL=index.js.map
|