@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.mjs
CHANGED
|
@@ -16,6 +16,8 @@ var MANTLE_SEPOLIA = {
|
|
|
16
16
|
};
|
|
17
17
|
var DEFAULT_CHAIN = MANTLE_SEPOLIA;
|
|
18
18
|
var ACTION_QUERY_PARAM = "action";
|
|
19
|
+
var REGISTRY_URL = "https://mlinks-fe.vercel.app";
|
|
20
|
+
var REGISTRY_VALIDATE_ENDPOINT = "/api/registry/validate";
|
|
19
21
|
|
|
20
22
|
// src/utils.ts
|
|
21
23
|
function parseBlinkUrl(blinkUrl) {
|
|
@@ -180,22 +182,73 @@ function validateActionMetadata(data) {
|
|
|
180
182
|
// src/react/useMlink.ts
|
|
181
183
|
var DEFAULT_REFRESH_INTERVAL = 10 * 60 * 1e3;
|
|
182
184
|
function useMlink(url, options = {}) {
|
|
183
|
-
const {
|
|
185
|
+
const {
|
|
186
|
+
refreshInterval = DEFAULT_REFRESH_INTERVAL,
|
|
187
|
+
enabled = true,
|
|
188
|
+
registryUrl = REGISTRY_URL,
|
|
189
|
+
requireRegistration = true,
|
|
190
|
+
allowPending = true,
|
|
191
|
+
allowBlocked = false
|
|
192
|
+
} = options;
|
|
184
193
|
const [status, setStatus] = useState("idle");
|
|
185
194
|
const [metadata, setMetadata] = useState(null);
|
|
186
195
|
const [error, setError] = useState(null);
|
|
196
|
+
const [registration, setRegistration] = useState(null);
|
|
187
197
|
const abortControllerRef = useRef(null);
|
|
188
198
|
const intervalRef = useRef(null);
|
|
189
199
|
const actionUrl = parseBlinkUrl(url) || url;
|
|
200
|
+
const validateRegistration = useCallback(async () => {
|
|
201
|
+
if (!actionUrl || !requireRegistration) return null;
|
|
202
|
+
try {
|
|
203
|
+
const validateUrl = `${registryUrl}${REGISTRY_VALIDATE_ENDPOINT}?url=${encodeURIComponent(actionUrl)}`;
|
|
204
|
+
const response = await fetch(validateUrl, {
|
|
205
|
+
method: "GET",
|
|
206
|
+
headers: {
|
|
207
|
+
Accept: "application/json"
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
const data = await response.json();
|
|
211
|
+
return data;
|
|
212
|
+
} catch (err) {
|
|
213
|
+
console.error("Registry validation error:", err);
|
|
214
|
+
return {
|
|
215
|
+
isRegistered: false,
|
|
216
|
+
status: null,
|
|
217
|
+
error: "Unable to validate against registry. Please try again later."
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
}, [actionUrl, registryUrl, requireRegistration]);
|
|
190
221
|
const fetchMetadata = useCallback(async () => {
|
|
191
222
|
if (!actionUrl || !enabled) return;
|
|
192
223
|
if (abortControllerRef.current) {
|
|
193
224
|
abortControllerRef.current.abort();
|
|
194
225
|
}
|
|
195
226
|
abortControllerRef.current = new AbortController();
|
|
196
|
-
setStatus("
|
|
227
|
+
setStatus("validating");
|
|
197
228
|
setError(null);
|
|
198
229
|
try {
|
|
230
|
+
if (requireRegistration) {
|
|
231
|
+
const registrationResult = await validateRegistration();
|
|
232
|
+
setRegistration(registrationResult);
|
|
233
|
+
if (registrationResult) {
|
|
234
|
+
if (!registrationResult.isRegistered) {
|
|
235
|
+
setError(registrationResult.error || "This MLink is not registered.");
|
|
236
|
+
setStatus("unregistered");
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
if (registrationResult.status === "blocked" && !allowBlocked) {
|
|
240
|
+
setError("This MLink has been blocked for policy violations.");
|
|
241
|
+
setStatus("blocked");
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (registrationResult.status === "pending" && !allowPending) {
|
|
245
|
+
setError("This MLink is pending review and not yet available.");
|
|
246
|
+
setStatus("error");
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
setStatus("loading");
|
|
199
252
|
const response = await fetch(actionUrl, {
|
|
200
253
|
method: "GET",
|
|
201
254
|
headers: {
|
|
@@ -221,7 +274,7 @@ function useMlink(url, options = {}) {
|
|
|
221
274
|
setError(errorMessage);
|
|
222
275
|
setStatus("error");
|
|
223
276
|
}
|
|
224
|
-
}, [actionUrl, enabled]);
|
|
277
|
+
}, [actionUrl, enabled, requireRegistration, validateRegistration, allowBlocked, allowPending]);
|
|
225
278
|
useEffect(() => {
|
|
226
279
|
if (enabled) {
|
|
227
280
|
fetchMetadata();
|
|
@@ -248,7 +301,9 @@ function useMlink(url, options = {}) {
|
|
|
248
301
|
metadata,
|
|
249
302
|
error,
|
|
250
303
|
url: actionUrl,
|
|
251
|
-
refresh: fetchMetadata
|
|
304
|
+
refresh: fetchMetadata,
|
|
305
|
+
registration,
|
|
306
|
+
isRegistered: registration?.isRegistered ?? false
|
|
252
307
|
};
|
|
253
308
|
}
|
|
254
309
|
function useExecuteMlink(options) {
|
|
@@ -475,11 +530,20 @@ function Mlink({
|
|
|
475
530
|
onSuccess,
|
|
476
531
|
onError,
|
|
477
532
|
className = "",
|
|
478
|
-
stylePreset = "default"
|
|
533
|
+
stylePreset = "default",
|
|
534
|
+
registryUrl,
|
|
535
|
+
requireRegistration = true,
|
|
536
|
+
allowPending = true,
|
|
537
|
+
allowBlocked = false
|
|
479
538
|
}) {
|
|
480
539
|
const context = useMlinkContext();
|
|
481
540
|
const resolvedTheme = themeProp ? resolveTheme(themeProp) : context.theme;
|
|
482
|
-
const { status: fetchStatus, metadata, error: fetchError } = useMlink(url
|
|
541
|
+
const { status: fetchStatus, metadata, error: fetchError, registration } = useMlink(url, {
|
|
542
|
+
registryUrl,
|
|
543
|
+
requireRegistration,
|
|
544
|
+
allowPending,
|
|
545
|
+
allowBlocked
|
|
546
|
+
});
|
|
483
547
|
const {
|
|
484
548
|
execute,
|
|
485
549
|
status: execStatus,
|
|
@@ -542,9 +606,21 @@ function Mlink({
|
|
|
542
606
|
const hasLinkedActions = useMemo(() => {
|
|
543
607
|
return metadata?.links?.actions && metadata.links.actions.length > 0;
|
|
544
608
|
}, [metadata]);
|
|
545
|
-
if (fetchStatus === "loading") {
|
|
609
|
+
if (fetchStatus === "loading" || fetchStatus === "validating") {
|
|
546
610
|
return /* @__PURE__ */ jsx(MlinkContainer, { theme: resolvedTheme, className, preset: stylePreset, children: /* @__PURE__ */ jsx(MlinkSkeleton, {}) });
|
|
547
611
|
}
|
|
612
|
+
if (fetchStatus === "unregistered") {
|
|
613
|
+
return /* @__PURE__ */ jsx(MlinkContainer, { theme: resolvedTheme, className, preset: stylePreset, children: /* @__PURE__ */ jsx(
|
|
614
|
+
MlinkUnregistered,
|
|
615
|
+
{
|
|
616
|
+
message: fetchError || "This MLink is not registered.",
|
|
617
|
+
registryUrl
|
|
618
|
+
}
|
|
619
|
+
) });
|
|
620
|
+
}
|
|
621
|
+
if (fetchStatus === "blocked") {
|
|
622
|
+
return /* @__PURE__ */ jsx(MlinkContainer, { theme: resolvedTheme, className, preset: stylePreset, children: /* @__PURE__ */ jsx(MlinkBlocked, { message: fetchError || "This MLink has been blocked." }) });
|
|
623
|
+
}
|
|
548
624
|
if (fetchStatus === "error" || !metadata) {
|
|
549
625
|
return /* @__PURE__ */ jsx(MlinkContainer, { theme: resolvedTheme, className, preset: stylePreset, children: /* @__PURE__ */ jsx(MlinkError, { message: fetchError || "Failed to load action" }) });
|
|
550
626
|
}
|
|
@@ -821,6 +897,38 @@ function MlinkError({ message }) {
|
|
|
821
897
|
/* @__PURE__ */ jsx("p", { className: "mlink-error-message", children: message })
|
|
822
898
|
] });
|
|
823
899
|
}
|
|
900
|
+
function MlinkUnregistered({ message, registryUrl }) {
|
|
901
|
+
const registerUrl = registryUrl ? `${registryUrl}/dashboard/register` : "https://mlinks-fe.vercel.app/dashboard/register";
|
|
902
|
+
return /* @__PURE__ */ jsxs("div", { className: "mlink-unregistered", children: [
|
|
903
|
+
/* @__PURE__ */ jsx("div", { className: "mlink-unregistered-icon", children: /* @__PURE__ */ jsxs("svg", { width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
904
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
|
|
905
|
+
/* @__PURE__ */ jsx("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
|
|
906
|
+
/* @__PURE__ */ jsx("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
|
|
907
|
+
] }) }),
|
|
908
|
+
/* @__PURE__ */ jsx("h3", { className: "mlink-unregistered-title", children: "Unregistered MLink" }),
|
|
909
|
+
/* @__PURE__ */ jsx("p", { className: "mlink-unregistered-message", children: message }),
|
|
910
|
+
/* @__PURE__ */ jsx(
|
|
911
|
+
"a",
|
|
912
|
+
{
|
|
913
|
+
href: registerUrl,
|
|
914
|
+
target: "_blank",
|
|
915
|
+
rel: "noopener noreferrer",
|
|
916
|
+
className: "mlink-button",
|
|
917
|
+
children: "Register MLink"
|
|
918
|
+
}
|
|
919
|
+
)
|
|
920
|
+
] });
|
|
921
|
+
}
|
|
922
|
+
function MlinkBlocked({ message }) {
|
|
923
|
+
return /* @__PURE__ */ jsxs("div", { className: "mlink-blocked", children: [
|
|
924
|
+
/* @__PURE__ */ jsx("div", { className: "mlink-blocked-icon", children: /* @__PURE__ */ jsxs("svg", { width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
925
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
|
|
926
|
+
/* @__PURE__ */ jsx("line", { x1: "4.93", y1: "4.93", x2: "19.07", y2: "19.07" })
|
|
927
|
+
] }) }),
|
|
928
|
+
/* @__PURE__ */ jsx("h3", { className: "mlink-blocked-title", children: "Blocked MLink" }),
|
|
929
|
+
/* @__PURE__ */ jsx("p", { className: "mlink-blocked-message", children: message })
|
|
930
|
+
] });
|
|
931
|
+
}
|
|
824
932
|
function MlinkSuccess({ message, txHash, onReset }) {
|
|
825
933
|
const shortHash = `${txHash.slice(0, 10)}...${txHash.slice(-8)}`;
|
|
826
934
|
return /* @__PURE__ */ jsxs("div", { className: "mlink-success", children: [
|