@dipansrimany/mlink-sdk 0.4.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/index.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -1
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +35 -3
- package/dist/react/index.d.ts +35 -3
- package/dist/react/index.js +115 -7
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +115 -7
- package/dist/react/index.mjs.map +1 -1
- package/dist/styles.css +57 -0
- package/package.json +1 -1
package/dist/react/index.d.ts
CHANGED
|
@@ -2,13 +2,29 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import { E as EVMTransaction, C as ChainConfig, A as ActionMetadata } from '../types-DD9rJ58Y.js';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
|
|
5
|
-
type MlinkStatus = 'idle' | 'loading' | 'ready' | 'executing' | 'success' | 'error';
|
|
5
|
+
type MlinkStatus = 'idle' | 'loading' | 'validating' | 'ready' | 'executing' | 'success' | 'error' | 'unregistered' | 'blocked';
|
|
6
|
+
type RegistrationStatus = 'pending' | 'approved' | 'blocked' | null;
|
|
7
|
+
interface RegistrationResult {
|
|
8
|
+
isRegistered: boolean;
|
|
9
|
+
status: RegistrationStatus;
|
|
10
|
+
error?: string;
|
|
11
|
+
warning?: string;
|
|
12
|
+
mlink?: {
|
|
13
|
+
mlinkId: string;
|
|
14
|
+
name: string;
|
|
15
|
+
description: string;
|
|
16
|
+
icon: string;
|
|
17
|
+
status: RegistrationStatus;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
6
20
|
interface MlinkInstance {
|
|
7
21
|
status: MlinkStatus;
|
|
8
22
|
metadata: ActionMetadata | null;
|
|
9
23
|
error: string | null;
|
|
10
24
|
url: string;
|
|
11
25
|
refresh: () => Promise<void>;
|
|
26
|
+
registration: RegistrationResult | null;
|
|
27
|
+
isRegistered: boolean;
|
|
12
28
|
}
|
|
13
29
|
interface MlinkAdapter {
|
|
14
30
|
connect: () => Promise<string>;
|
|
@@ -78,6 +94,14 @@ interface MlinkProps {
|
|
|
78
94
|
onError?: (error: string) => void;
|
|
79
95
|
className?: string;
|
|
80
96
|
stylePreset?: 'default' | 'compact' | 'minimal';
|
|
97
|
+
/** Registry URL for validation (defaults to https://mlinks-fe.vercel.app) */
|
|
98
|
+
registryUrl?: string;
|
|
99
|
+
/** Whether to require registration for the mlink to work (defaults to true) */
|
|
100
|
+
requireRegistration?: boolean;
|
|
101
|
+
/** Whether to allow pending mlinks (defaults to true) */
|
|
102
|
+
allowPending?: boolean;
|
|
103
|
+
/** Whether to allow blocked mlinks (defaults to false) */
|
|
104
|
+
allowBlocked?: boolean;
|
|
81
105
|
}
|
|
82
106
|
interface ActionButtonProps {
|
|
83
107
|
label: string;
|
|
@@ -97,6 +121,14 @@ interface ExecutionResult {
|
|
|
97
121
|
interface UseMlinkOptions {
|
|
98
122
|
refreshInterval?: number;
|
|
99
123
|
enabled?: boolean;
|
|
124
|
+
/** Registry URL for validation (defaults to https://mlinks-fe.vercel.app) */
|
|
125
|
+
registryUrl?: string;
|
|
126
|
+
/** Whether to require registration for the mlink to work (defaults to true) */
|
|
127
|
+
requireRegistration?: boolean;
|
|
128
|
+
/** Whether to allow pending mlinks (defaults to true) */
|
|
129
|
+
allowPending?: boolean;
|
|
130
|
+
/** Whether to allow blocked mlinks (defaults to false) */
|
|
131
|
+
allowBlocked?: boolean;
|
|
100
132
|
}
|
|
101
133
|
interface UseExecuteMlinkReturn {
|
|
102
134
|
execute: (action: string, input?: string) => Promise<ExecutionResult>;
|
|
@@ -106,7 +138,7 @@ interface UseExecuteMlinkReturn {
|
|
|
106
138
|
reset: () => void;
|
|
107
139
|
}
|
|
108
140
|
|
|
109
|
-
declare function Mlink({ url, adapter, theme: themeProp, onSuccess, onError, className, stylePreset, }: MlinkProps): react_jsx_runtime.JSX.Element;
|
|
141
|
+
declare function Mlink({ url, adapter, theme: themeProp, onSuccess, onError, className, stylePreset, registryUrl, requireRegistration, allowPending, allowBlocked, }: MlinkProps): react_jsx_runtime.JSX.Element;
|
|
110
142
|
|
|
111
143
|
interface MlinkContextValue {
|
|
112
144
|
theme: MlinkTheme;
|
|
@@ -211,4 +243,4 @@ declare const mantleTheme: MlinkTheme;
|
|
|
211
243
|
declare const themePresets: Record<MlinkThemePreset, MlinkTheme>;
|
|
212
244
|
declare function resolveTheme(theme?: Partial<MlinkTheme> | MlinkThemePreset): MlinkTheme;
|
|
213
245
|
|
|
214
|
-
export { type ActionButtonProps, type EthersAdapterConfig, type ExecutionResult, Mlink, type MlinkAdapter, Mlink as MlinkComponent, type MlinkInstance, type MlinkProps, MlinkProvider, type MlinkProviderConfig, type MlinkStatus, type MlinkTheme, type MlinkThemePreset, type UseExecuteMlinkReturn, type UseExecuteMlinkReturnEnhanced, type UseMlinkOptions, type WagmiAdapterConfig, createMlinkAdapter, darkTheme, lightTheme, mantleTheme, resolveTheme, themePresets, useExecuteMlink, useMlink, useMlinkContext, useMlinkEthersAdapter, useMlinkWagmiAdapter };
|
|
246
|
+
export { type ActionButtonProps, type EthersAdapterConfig, type ExecutionResult, Mlink, type MlinkAdapter, Mlink as MlinkComponent, type MlinkInstance, type MlinkProps, MlinkProvider, type MlinkProviderConfig, type MlinkStatus, type MlinkTheme, type MlinkThemePreset, type RegistrationResult, type RegistrationStatus, type UseExecuteMlinkReturn, type UseExecuteMlinkReturnEnhanced, type UseMlinkOptions, type WagmiAdapterConfig, createMlinkAdapter, darkTheme, lightTheme, mantleTheme, resolveTheme, themePresets, useExecuteMlink, useMlink, useMlinkContext, useMlinkEthersAdapter, useMlinkWagmiAdapter };
|
package/dist/react/index.js
CHANGED
|
@@ -18,6 +18,8 @@ var MANTLE_SEPOLIA = {
|
|
|
18
18
|
};
|
|
19
19
|
var DEFAULT_CHAIN = MANTLE_SEPOLIA;
|
|
20
20
|
var ACTION_QUERY_PARAM = "action";
|
|
21
|
+
var REGISTRY_URL = "https://mlinks-fe.vercel.app";
|
|
22
|
+
var REGISTRY_VALIDATE_ENDPOINT = "/api/registry/validate";
|
|
21
23
|
|
|
22
24
|
// src/utils.ts
|
|
23
25
|
function parseBlinkUrl(blinkUrl) {
|
|
@@ -182,22 +184,73 @@ function validateActionMetadata(data) {
|
|
|
182
184
|
// src/react/useMlink.ts
|
|
183
185
|
var DEFAULT_REFRESH_INTERVAL = 10 * 60 * 1e3;
|
|
184
186
|
function useMlink(url, options = {}) {
|
|
185
|
-
const {
|
|
187
|
+
const {
|
|
188
|
+
refreshInterval = DEFAULT_REFRESH_INTERVAL,
|
|
189
|
+
enabled = true,
|
|
190
|
+
registryUrl = REGISTRY_URL,
|
|
191
|
+
requireRegistration = true,
|
|
192
|
+
allowPending = true,
|
|
193
|
+
allowBlocked = false
|
|
194
|
+
} = options;
|
|
186
195
|
const [status, setStatus] = react.useState("idle");
|
|
187
196
|
const [metadata, setMetadata] = react.useState(null);
|
|
188
197
|
const [error, setError] = react.useState(null);
|
|
198
|
+
const [registration, setRegistration] = react.useState(null);
|
|
189
199
|
const abortControllerRef = react.useRef(null);
|
|
190
200
|
const intervalRef = react.useRef(null);
|
|
191
201
|
const actionUrl = parseBlinkUrl(url) || url;
|
|
202
|
+
const validateRegistration = react.useCallback(async () => {
|
|
203
|
+
if (!actionUrl || !requireRegistration) return null;
|
|
204
|
+
try {
|
|
205
|
+
const validateUrl = `${registryUrl}${REGISTRY_VALIDATE_ENDPOINT}?url=${encodeURIComponent(actionUrl)}`;
|
|
206
|
+
const response = await fetch(validateUrl, {
|
|
207
|
+
method: "GET",
|
|
208
|
+
headers: {
|
|
209
|
+
Accept: "application/json"
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
const data = await response.json();
|
|
213
|
+
return data;
|
|
214
|
+
} catch (err) {
|
|
215
|
+
console.error("Registry validation error:", err);
|
|
216
|
+
return {
|
|
217
|
+
isRegistered: false,
|
|
218
|
+
status: null,
|
|
219
|
+
error: "Unable to validate against registry. Please try again later."
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
}, [actionUrl, registryUrl, requireRegistration]);
|
|
192
223
|
const fetchMetadata = react.useCallback(async () => {
|
|
193
224
|
if (!actionUrl || !enabled) return;
|
|
194
225
|
if (abortControllerRef.current) {
|
|
195
226
|
abortControllerRef.current.abort();
|
|
196
227
|
}
|
|
197
228
|
abortControllerRef.current = new AbortController();
|
|
198
|
-
setStatus("
|
|
229
|
+
setStatus("validating");
|
|
199
230
|
setError(null);
|
|
200
231
|
try {
|
|
232
|
+
if (requireRegistration) {
|
|
233
|
+
const registrationResult = await validateRegistration();
|
|
234
|
+
setRegistration(registrationResult);
|
|
235
|
+
if (registrationResult) {
|
|
236
|
+
if (!registrationResult.isRegistered) {
|
|
237
|
+
setError(registrationResult.error || "This MLink is not registered.");
|
|
238
|
+
setStatus("unregistered");
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
if (registrationResult.status === "blocked" && !allowBlocked) {
|
|
242
|
+
setError("This MLink has been blocked for policy violations.");
|
|
243
|
+
setStatus("blocked");
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
if (registrationResult.status === "pending" && !allowPending) {
|
|
247
|
+
setError("This MLink is pending review and not yet available.");
|
|
248
|
+
setStatus("error");
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
setStatus("loading");
|
|
201
254
|
const response = await fetch(actionUrl, {
|
|
202
255
|
method: "GET",
|
|
203
256
|
headers: {
|
|
@@ -223,7 +276,7 @@ function useMlink(url, options = {}) {
|
|
|
223
276
|
setError(errorMessage);
|
|
224
277
|
setStatus("error");
|
|
225
278
|
}
|
|
226
|
-
}, [actionUrl, enabled]);
|
|
279
|
+
}, [actionUrl, enabled, requireRegistration, validateRegistration, allowBlocked, allowPending]);
|
|
227
280
|
react.useEffect(() => {
|
|
228
281
|
if (enabled) {
|
|
229
282
|
fetchMetadata();
|
|
@@ -250,7 +303,9 @@ function useMlink(url, options = {}) {
|
|
|
250
303
|
metadata,
|
|
251
304
|
error,
|
|
252
305
|
url: actionUrl,
|
|
253
|
-
refresh: fetchMetadata
|
|
306
|
+
refresh: fetchMetadata,
|
|
307
|
+
registration,
|
|
308
|
+
isRegistered: registration?.isRegistered ?? false
|
|
254
309
|
};
|
|
255
310
|
}
|
|
256
311
|
function useExecuteMlink(options) {
|
|
@@ -477,11 +532,20 @@ function Mlink({
|
|
|
477
532
|
onSuccess,
|
|
478
533
|
onError,
|
|
479
534
|
className = "",
|
|
480
|
-
stylePreset = "default"
|
|
535
|
+
stylePreset = "default",
|
|
536
|
+
registryUrl,
|
|
537
|
+
requireRegistration = true,
|
|
538
|
+
allowPending = true,
|
|
539
|
+
allowBlocked = false
|
|
481
540
|
}) {
|
|
482
541
|
const context = useMlinkContext();
|
|
483
542
|
const resolvedTheme = themeProp ? resolveTheme(themeProp) : context.theme;
|
|
484
|
-
const { status: fetchStatus, metadata, error: fetchError } = useMlink(url
|
|
543
|
+
const { status: fetchStatus, metadata, error: fetchError, registration } = useMlink(url, {
|
|
544
|
+
registryUrl,
|
|
545
|
+
requireRegistration,
|
|
546
|
+
allowPending,
|
|
547
|
+
allowBlocked
|
|
548
|
+
});
|
|
485
549
|
const {
|
|
486
550
|
execute,
|
|
487
551
|
status: execStatus,
|
|
@@ -544,9 +608,21 @@ function Mlink({
|
|
|
544
608
|
const hasLinkedActions = react.useMemo(() => {
|
|
545
609
|
return metadata?.links?.actions && metadata.links.actions.length > 0;
|
|
546
610
|
}, [metadata]);
|
|
547
|
-
if (fetchStatus === "loading") {
|
|
611
|
+
if (fetchStatus === "loading" || fetchStatus === "validating") {
|
|
548
612
|
return /* @__PURE__ */ jsxRuntime.jsx(MlinkContainer, { theme: resolvedTheme, className, preset: stylePreset, children: /* @__PURE__ */ jsxRuntime.jsx(MlinkSkeleton, {}) });
|
|
549
613
|
}
|
|
614
|
+
if (fetchStatus === "unregistered") {
|
|
615
|
+
return /* @__PURE__ */ jsxRuntime.jsx(MlinkContainer, { theme: resolvedTheme, className, preset: stylePreset, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
616
|
+
MlinkUnregistered,
|
|
617
|
+
{
|
|
618
|
+
message: fetchError || "This MLink is not registered.",
|
|
619
|
+
registryUrl
|
|
620
|
+
}
|
|
621
|
+
) });
|
|
622
|
+
}
|
|
623
|
+
if (fetchStatus === "blocked") {
|
|
624
|
+
return /* @__PURE__ */ jsxRuntime.jsx(MlinkContainer, { theme: resolvedTheme, className, preset: stylePreset, children: /* @__PURE__ */ jsxRuntime.jsx(MlinkBlocked, { message: fetchError || "This MLink has been blocked." }) });
|
|
625
|
+
}
|
|
550
626
|
if (fetchStatus === "error" || !metadata) {
|
|
551
627
|
return /* @__PURE__ */ jsxRuntime.jsx(MlinkContainer, { theme: resolvedTheme, className, preset: stylePreset, children: /* @__PURE__ */ jsxRuntime.jsx(MlinkError, { message: fetchError || "Failed to load action" }) });
|
|
552
628
|
}
|
|
@@ -823,6 +899,38 @@ function MlinkError({ message }) {
|
|
|
823
899
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mlink-error-message", children: message })
|
|
824
900
|
] });
|
|
825
901
|
}
|
|
902
|
+
function MlinkUnregistered({ message, registryUrl }) {
|
|
903
|
+
const registerUrl = registryUrl ? `${registryUrl}/dashboard/register` : "https://mlinks-fe.vercel.app/dashboard/register";
|
|
904
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mlink-unregistered", children: [
|
|
905
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mlink-unregistered-icon", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
906
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "10" }),
|
|
907
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
|
|
908
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
|
|
909
|
+
] }) }),
|
|
910
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mlink-unregistered-title", children: "Unregistered MLink" }),
|
|
911
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mlink-unregistered-message", children: message }),
|
|
912
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
913
|
+
"a",
|
|
914
|
+
{
|
|
915
|
+
href: registerUrl,
|
|
916
|
+
target: "_blank",
|
|
917
|
+
rel: "noopener noreferrer",
|
|
918
|
+
className: "mlink-button",
|
|
919
|
+
children: "Register MLink"
|
|
920
|
+
}
|
|
921
|
+
)
|
|
922
|
+
] });
|
|
923
|
+
}
|
|
924
|
+
function MlinkBlocked({ message }) {
|
|
925
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mlink-blocked", children: [
|
|
926
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mlink-blocked-icon", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
927
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "10" }),
|
|
928
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "4.93", y1: "4.93", x2: "19.07", y2: "19.07" })
|
|
929
|
+
] }) }),
|
|
930
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mlink-blocked-title", children: "Blocked MLink" }),
|
|
931
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mlink-blocked-message", children: message })
|
|
932
|
+
] });
|
|
933
|
+
}
|
|
826
934
|
function MlinkSuccess({ message, txHash, onReset }) {
|
|
827
935
|
const shortHash = `${txHash.slice(0, 10)}...${txHash.slice(-8)}`;
|
|
828
936
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mlink-success", children: [
|