@blocklet/did-domain-react 0.5.1 → 0.5.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/es/buy.d.ts +15 -0
- package/es/buy.js +156 -0
- package/es/domain.d.ts +7 -0
- package/es/domain.js +89 -0
- package/es/index.d.ts +4 -0
- package/es/index.js +4 -0
- package/es/libs/api.d.ts +3 -0
- package/es/libs/api.js +21 -0
- package/es/libs/util.d.ts +25 -0
- package/es/libs/util.js +91 -0
- package/es/locales/en.d.ts +2 -0
- package/es/locales/en.js +18 -0
- package/es/locales/index.d.ts +4 -0
- package/es/locales/index.js +6 -0
- package/es/locales/zh.d.ts +2 -0
- package/es/locales/zh.js +18 -0
- package/es/types/index.d.ts +0 -0
- package/es/types/index.js +0 -0
- package/es/types/shims.d.ts +15 -0
- package/lib/buy.d.ts +15 -0
- package/lib/buy.js +200 -0
- package/lib/domain.d.ts +7 -0
- package/lib/domain.js +97 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.js +27 -0
- package/lib/libs/api.d.ts +3 -0
- package/lib/libs/api.js +25 -0
- package/lib/libs/util.d.ts +25 -0
- package/lib/libs/util.js +107 -0
- package/lib/locales/en.d.ts +2 -0
- package/lib/locales/en.js +25 -0
- package/lib/locales/index.d.ts +4 -0
- package/lib/locales/index.js +13 -0
- package/lib/locales/zh.d.ts +2 -0
- package/lib/locales/zh.js +25 -0
- package/lib/types/index.d.ts +0 -0
- package/lib/types/index.js +1 -0
- package/lib/types/shims.d.ts +15 -0
- package/package.json +2 -2
package/es/buy.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Locale } from '@arcblock/ux/lib/type';
|
|
2
|
+
interface Props {
|
|
3
|
+
delegatee: string;
|
|
4
|
+
delegateePk: string;
|
|
5
|
+
didDomainURL: string;
|
|
6
|
+
locale: Locale;
|
|
7
|
+
title?: string;
|
|
8
|
+
onSuccess?: (data: {
|
|
9
|
+
nftDid: string;
|
|
10
|
+
domain: string;
|
|
11
|
+
chainHost: string;
|
|
12
|
+
}) => void;
|
|
13
|
+
}
|
|
14
|
+
export default function Buy(props: Props): import("react").JSX.Element;
|
|
15
|
+
export {};
|
package/es/buy.js
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import LoadingButton from "@mui/lab/LoadingButton";
|
|
3
|
+
import Dialog from "@arcblock/ux/lib/Dialog";
|
|
4
|
+
import { LocaleProvider, useLocaleContext } from "@arcblock/ux/lib/Locale/context";
|
|
5
|
+
import CheckCircle from "@mui/icons-material/CheckCircle";
|
|
6
|
+
import ShoppingCart from "@mui/icons-material/ShoppingCart";
|
|
7
|
+
import Alert from "@mui/material/Alert";
|
|
8
|
+
import Box from "@mui/material/Box";
|
|
9
|
+
import CircularProgress from "@mui/material/CircularProgress";
|
|
10
|
+
import Typography from "@mui/material/Typography";
|
|
11
|
+
import { useRequest as useAHooksRequest, useMemoizedFn, useSetState, useUnmount } from "ahooks";
|
|
12
|
+
import { useRef } from "react";
|
|
13
|
+
import { create } from "./libs/api.js";
|
|
14
|
+
import { getDidDomainServiceURL, openPopup } from "./libs/util.js";
|
|
15
|
+
import { translations } from "./locales/index.js";
|
|
16
|
+
var BuyState = /* @__PURE__ */ ((BuyState2) => {
|
|
17
|
+
BuyState2[BuyState2["Prepare"] = 1] = "Prepare";
|
|
18
|
+
BuyState2[BuyState2["InProgress"] = 2] = "InProgress";
|
|
19
|
+
BuyState2[BuyState2["Success"] = 4] = "Success";
|
|
20
|
+
BuyState2[BuyState2["Completed"] = 8] = "Completed";
|
|
21
|
+
return BuyState2;
|
|
22
|
+
})(BuyState || {});
|
|
23
|
+
const preFetch = async ({
|
|
24
|
+
didDomainURL,
|
|
25
|
+
delegatee,
|
|
26
|
+
delegateePk
|
|
27
|
+
}) => {
|
|
28
|
+
const serviceURL = await getDidDomainServiceURL(didDomainURL);
|
|
29
|
+
if (!serviceURL) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const apiRequest = create({ baseURL: serviceURL.api });
|
|
33
|
+
const { data } = await apiRequest.post("/payment/session", {
|
|
34
|
+
delegatee,
|
|
35
|
+
delegateePk
|
|
36
|
+
});
|
|
37
|
+
return {
|
|
38
|
+
sessionId: data.sessionId,
|
|
39
|
+
baseURL: serviceURL.base
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
function Component({
|
|
43
|
+
delegatee,
|
|
44
|
+
delegateePk,
|
|
45
|
+
didDomainURL,
|
|
46
|
+
locale,
|
|
47
|
+
title = "",
|
|
48
|
+
onSuccess = () => {
|
|
49
|
+
},
|
|
50
|
+
...props
|
|
51
|
+
}) {
|
|
52
|
+
const { t } = useLocaleContext();
|
|
53
|
+
const [state, setState] = useSetState({
|
|
54
|
+
currentState: 1 /* Prepare */
|
|
55
|
+
});
|
|
56
|
+
const popup = useRef(null);
|
|
57
|
+
const sessionRequest = useAHooksRequest(
|
|
58
|
+
async () => {
|
|
59
|
+
const data = await preFetch({ didDomainURL, delegatee, delegateePk });
|
|
60
|
+
if (!data) {
|
|
61
|
+
return data;
|
|
62
|
+
}
|
|
63
|
+
return data;
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
debounceWait: 500,
|
|
67
|
+
debounceLeading: true,
|
|
68
|
+
debounceTrailing: false,
|
|
69
|
+
debounceMaxWait: 3e3,
|
|
70
|
+
refreshDeps: [],
|
|
71
|
+
onError(error) {
|
|
72
|
+
console.error(error);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
const onMessage = useMemoizedFn((event) => {
|
|
77
|
+
if (event.data.type === "didDomain.success") {
|
|
78
|
+
onSuccess?.({ nftDid: event.data?.nftDid, domain: event.data?.domain, chainHost: event.data?.chainHost });
|
|
79
|
+
popup.current?.close();
|
|
80
|
+
popup.current = null;
|
|
81
|
+
setState({ currentState: 4 /* Success */ });
|
|
82
|
+
setTimeout(() => {
|
|
83
|
+
setState({ currentState: 8 /* Completed */ });
|
|
84
|
+
}, 2e3);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
useUnmount(() => {
|
|
88
|
+
try {
|
|
89
|
+
window.removeEventListener("message", onMessage);
|
|
90
|
+
popup.current?.close();
|
|
91
|
+
popup.current = null;
|
|
92
|
+
} catch (error) {
|
|
93
|
+
console.warn("Failed to close popup", error);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
const handleCloseDialog = useMemoizedFn(() => {
|
|
97
|
+
setState({ currentState: 1 /* Prepare */ });
|
|
98
|
+
});
|
|
99
|
+
const handleOpenDialog = useMemoizedFn(() => {
|
|
100
|
+
setState({ currentState: 2 /* InProgress */ });
|
|
101
|
+
if (!sessionRequest.data) {
|
|
102
|
+
console.error("Failed to create session");
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
handleCreatedSession({ sessionId: sessionRequest.data.sessionId, baseURL: sessionRequest.data.baseURL });
|
|
106
|
+
});
|
|
107
|
+
const handleCreatedSession = useMemoizedFn(({ sessionId, baseURL }) => {
|
|
108
|
+
window.addEventListener("message", onMessage);
|
|
109
|
+
const urlObj = new URL(baseURL);
|
|
110
|
+
urlObj.searchParams.set("sessionId", sessionId);
|
|
111
|
+
urlObj.searchParams.set("locale", locale);
|
|
112
|
+
urlObj.searchParams.set("embed", "1");
|
|
113
|
+
popup.current = openPopup(urlObj.toString());
|
|
114
|
+
const timer = setInterval(() => {
|
|
115
|
+
if (popup.current?.closed) {
|
|
116
|
+
clearInterval(timer);
|
|
117
|
+
handleCloseDialog();
|
|
118
|
+
}
|
|
119
|
+
}, 1e3);
|
|
120
|
+
return () => clearInterval(timer);
|
|
121
|
+
});
|
|
122
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
123
|
+
/* @__PURE__ */ jsx(
|
|
124
|
+
LoadingButton,
|
|
125
|
+
{
|
|
126
|
+
loading: sessionRequest.loading,
|
|
127
|
+
onClick: handleOpenDialog,
|
|
128
|
+
variant: "contained",
|
|
129
|
+
startIcon: /* @__PURE__ */ jsx(ShoppingCart, {}),
|
|
130
|
+
...props,
|
|
131
|
+
children: title || t("buy.button.title")
|
|
132
|
+
}
|
|
133
|
+
),
|
|
134
|
+
/* @__PURE__ */ jsxs(
|
|
135
|
+
Dialog,
|
|
136
|
+
{
|
|
137
|
+
fullWidth: true,
|
|
138
|
+
maxWidth: "xs",
|
|
139
|
+
open: state.currentState > 1 /* Prepare */ && state.currentState < 8 /* Completed */,
|
|
140
|
+
onClose: handleCloseDialog,
|
|
141
|
+
children: [
|
|
142
|
+
!sessionRequest.error && /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", flexDirection: "column", gap: 2 }, children: [
|
|
143
|
+
state.currentState === 2 /* InProgress */ && /* @__PURE__ */ jsx(CircularProgress, { size: 50 }),
|
|
144
|
+
state.currentState === 4 /* Success */ && /* @__PURE__ */ jsx(CheckCircle, { sx: { color: "primary.main", fontSize: "5rem" } }),
|
|
145
|
+
state.currentState === 2 /* InProgress */ && /* @__PURE__ */ jsx(Typography, { children: t("buy.status.inProgress") }),
|
|
146
|
+
state.currentState === 4 /* Success */ && /* @__PURE__ */ jsx(Typography, { children: t("buy.status.success") })
|
|
147
|
+
] }),
|
|
148
|
+
sessionRequest.error && /* @__PURE__ */ jsx(Alert, { severity: "error", children: t("buy.error.failedToCreateSession") })
|
|
149
|
+
]
|
|
150
|
+
}
|
|
151
|
+
)
|
|
152
|
+
] });
|
|
153
|
+
}
|
|
154
|
+
export default function Buy(props) {
|
|
155
|
+
return /* @__PURE__ */ jsx(LocaleProvider, { locale: props.locale, translations, children: /* @__PURE__ */ jsx(Component, { ...props }) });
|
|
156
|
+
}
|
package/es/domain.d.ts
ADDED
package/es/domain.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
|
|
3
|
+
import { CircularProgress, Tooltip } from "@mui/material";
|
|
4
|
+
import Box from "@mui/material/Box";
|
|
5
|
+
import Popover from "@mui/material/Popover";
|
|
6
|
+
import { useTheme } from "@mui/material/styles";
|
|
7
|
+
import useMediaQuery from "@mui/material/useMediaQuery";
|
|
8
|
+
import { useRef } from "react";
|
|
9
|
+
import { useAsync } from "react-use";
|
|
10
|
+
import useSetState from "react-use/lib/useSetState";
|
|
11
|
+
import { joinURL } from "ufo";
|
|
12
|
+
import { getDidDomainServiceURL, mergeSx } from "./libs/util.js";
|
|
13
|
+
export function Domain({
|
|
14
|
+
nftDid,
|
|
15
|
+
didDomainURL,
|
|
16
|
+
locale,
|
|
17
|
+
sx = {}
|
|
18
|
+
}) {
|
|
19
|
+
const { t } = useLocaleContext();
|
|
20
|
+
const [state, setState] = useSetState({
|
|
21
|
+
safeIframeRef: null,
|
|
22
|
+
popoverAnchorEl: null
|
|
23
|
+
});
|
|
24
|
+
const iframeRef = useRef(null);
|
|
25
|
+
const theme = useTheme();
|
|
26
|
+
const isMobile = useMediaQuery(theme.breakpoints.down("md"));
|
|
27
|
+
const handlePopoverClick = (event) => {
|
|
28
|
+
setState({ popoverAnchorEl: event.currentTarget });
|
|
29
|
+
};
|
|
30
|
+
const handlePopoverClose = () => {
|
|
31
|
+
setState({ popoverAnchorEl: null });
|
|
32
|
+
};
|
|
33
|
+
const urlState = useAsync(async () => {
|
|
34
|
+
const result = await getDidDomainServiceURL(didDomainURL);
|
|
35
|
+
if (!result) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
return result.base;
|
|
39
|
+
});
|
|
40
|
+
if (!urlState.value) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
if (urlState.loading) {
|
|
44
|
+
return /* @__PURE__ */ jsx(CircularProgress, {});
|
|
45
|
+
}
|
|
46
|
+
const iframeSrc = joinURL(urlState.value, `/embed/domain?nft-did=${nftDid}&locale=${locale}`);
|
|
47
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
48
|
+
/* @__PURE__ */ jsx(Tooltip, { title: t("embed.iconTip"), children: /* @__PURE__ */ jsx(
|
|
49
|
+
Box,
|
|
50
|
+
{
|
|
51
|
+
component: "img",
|
|
52
|
+
src: joinURL(didDomainURL, "/.well-known/service/blocklet/logo"),
|
|
53
|
+
alt: "logo",
|
|
54
|
+
onClick: handlePopoverClick,
|
|
55
|
+
sx: [
|
|
56
|
+
{
|
|
57
|
+
width: 16,
|
|
58
|
+
height: 16
|
|
59
|
+
},
|
|
60
|
+
mergeSx({ cursor: "pointer" }, sx)
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
) }),
|
|
64
|
+
/* @__PURE__ */ jsx(
|
|
65
|
+
Popover,
|
|
66
|
+
{
|
|
67
|
+
id: "popover-info",
|
|
68
|
+
open: Boolean(state.popoverAnchorEl),
|
|
69
|
+
anchorEl: state.popoverAnchorEl,
|
|
70
|
+
onClose: handlePopoverClose,
|
|
71
|
+
anchorOrigin: {
|
|
72
|
+
vertical: "bottom",
|
|
73
|
+
horizontal: "right"
|
|
74
|
+
},
|
|
75
|
+
children: /* @__PURE__ */ jsx(
|
|
76
|
+
"iframe",
|
|
77
|
+
{
|
|
78
|
+
ref: iframeRef,
|
|
79
|
+
title: t("common.subscription"),
|
|
80
|
+
width: isMobile ? "320px" : "400px",
|
|
81
|
+
height: "350px",
|
|
82
|
+
style: { border: 0, display: "block" },
|
|
83
|
+
src: iframeSrc
|
|
84
|
+
}
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
)
|
|
88
|
+
] });
|
|
89
|
+
}
|
package/es/index.d.ts
ADDED
package/es/index.js
ADDED
package/es/libs/api.d.ts
ADDED
package/es/libs/api.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { getLocale } from "@arcblock/ux/lib/Locale/context";
|
|
2
|
+
import { createAxios } from "@blocklet/js-sdk";
|
|
3
|
+
import { joinURL } from "ufo";
|
|
4
|
+
const axios = createAxios({});
|
|
5
|
+
axios.interceptors.request.use(
|
|
6
|
+
(config) => {
|
|
7
|
+
const prefix = window.blocklet ? window.blocklet.prefix : "/";
|
|
8
|
+
config.baseURL = prefix || "";
|
|
9
|
+
config.url = joinURL("/api", String(config.url));
|
|
10
|
+
config.timeout = 2e5;
|
|
11
|
+
config.params = config.params || {};
|
|
12
|
+
const searchParams = new URLSearchParams(config.url.split("?")[1]);
|
|
13
|
+
if (!searchParams.has("locale")) {
|
|
14
|
+
config.params.locale = getLocale();
|
|
15
|
+
}
|
|
16
|
+
return config;
|
|
17
|
+
},
|
|
18
|
+
(error) => Promise.reject(error)
|
|
19
|
+
);
|
|
20
|
+
export const create = (...args) => createAxios(...args);
|
|
21
|
+
export default axios;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export declare const SEARCH_BUTTON_WIDTH = 120;
|
|
2
|
+
export declare const COMMON_REQUEST_OPTIONS: {
|
|
3
|
+
debounceWait: number;
|
|
4
|
+
debounceLeading: boolean;
|
|
5
|
+
debounceTrailing: boolean;
|
|
6
|
+
debounceMaxWait: number;
|
|
7
|
+
};
|
|
8
|
+
export declare const formatLocale: (locale?: string) => string;
|
|
9
|
+
export declare const formatError: (err: any, t: any) => any;
|
|
10
|
+
export declare const mergeSx: (initial: any, sx: any) => any;
|
|
11
|
+
export declare const getChainHost: () => any;
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* @param {string} url - 打开一个弹窗
|
|
15
|
+
* @returns
|
|
16
|
+
*/
|
|
17
|
+
export declare const openPopup: (url: string, { width, height, name }?: {
|
|
18
|
+
width?: number | undefined;
|
|
19
|
+
height?: number | undefined;
|
|
20
|
+
name?: string | undefined;
|
|
21
|
+
}) => Window;
|
|
22
|
+
export declare const getDidDomainServiceURL: (url: string) => Promise<{
|
|
23
|
+
base: string;
|
|
24
|
+
api: string;
|
|
25
|
+
} | null>;
|
package/es/libs/util.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { joinURL, withQuery } from "ufo";
|
|
2
|
+
import { create as createAxios } from "./api.js";
|
|
3
|
+
export const SEARCH_BUTTON_WIDTH = 120;
|
|
4
|
+
export const COMMON_REQUEST_OPTIONS = {
|
|
5
|
+
debounceWait: 500,
|
|
6
|
+
debounceLeading: true,
|
|
7
|
+
debounceTrailing: false,
|
|
8
|
+
debounceMaxWait: 3e3
|
|
9
|
+
};
|
|
10
|
+
export const formatLocale = (locale = "en") => {
|
|
11
|
+
if (locale === "tw") {
|
|
12
|
+
return "zh";
|
|
13
|
+
}
|
|
14
|
+
return locale;
|
|
15
|
+
};
|
|
16
|
+
export const formatError = (err, t) => {
|
|
17
|
+
const { errors, response } = err;
|
|
18
|
+
if (Array.isArray(errors)) {
|
|
19
|
+
return errors.map((x) => x.message).join("\n");
|
|
20
|
+
}
|
|
21
|
+
const joiError = err.response?.data?.error;
|
|
22
|
+
if (Array.isArray(joiError?.details)) {
|
|
23
|
+
const formatted = joiError?.details.map((e) => {
|
|
24
|
+
const errorMessage = e.message.replace(/["]/g, "'");
|
|
25
|
+
const errorPath = e.path.join(".");
|
|
26
|
+
return `${errorPath}: ${errorMessage}`;
|
|
27
|
+
});
|
|
28
|
+
return `Validate failed: ${formatted.join(";")}`;
|
|
29
|
+
}
|
|
30
|
+
if (response?.data?.code) {
|
|
31
|
+
return t(`error.${response?.data?.code}`);
|
|
32
|
+
}
|
|
33
|
+
if (response?.data?.message) {
|
|
34
|
+
return response.data.message;
|
|
35
|
+
}
|
|
36
|
+
if (response) {
|
|
37
|
+
return `Request failed: ${response.status} ${response.statusText}: ${JSON.stringify(response.data)}`;
|
|
38
|
+
}
|
|
39
|
+
return err.message;
|
|
40
|
+
};
|
|
41
|
+
export const mergeSx = (initial, sx) => {
|
|
42
|
+
if (!sx) {
|
|
43
|
+
return initial;
|
|
44
|
+
}
|
|
45
|
+
if (!initial) {
|
|
46
|
+
return sx;
|
|
47
|
+
}
|
|
48
|
+
return [initial, ...Array.isArray(sx) ? sx : [sx]];
|
|
49
|
+
};
|
|
50
|
+
export const getChainHost = () => window.blocklet?.preferences?.chainHost || "";
|
|
51
|
+
export const openPopup = (url, { width = 600, height = 700, name = "did-domain:popup" } = {}) => {
|
|
52
|
+
const left = window.screenX + (window.innerWidth - width) / 2;
|
|
53
|
+
const top = window.screenY + (window.innerHeight - height) / 2;
|
|
54
|
+
const windowFeatures = [
|
|
55
|
+
`left=${left}`,
|
|
56
|
+
`top=${top}`,
|
|
57
|
+
`width=${width}`,
|
|
58
|
+
`height=${height}`,
|
|
59
|
+
"resizable=no",
|
|
60
|
+
// not working
|
|
61
|
+
"scrollbars=yes",
|
|
62
|
+
"status=yes",
|
|
63
|
+
"popup=yes"
|
|
64
|
+
];
|
|
65
|
+
const popup = window.open("", name, windowFeatures.join(","));
|
|
66
|
+
if (popup === null) {
|
|
67
|
+
throw new Error("Failed to open popup");
|
|
68
|
+
}
|
|
69
|
+
popup.location.href = withQuery(url, {
|
|
70
|
+
// NOTICE: 携带当前页面的 origin,用于在 popup 中通过该参数判断是否可以发送 postMessage,即使该参数被伪造,最终也只有该域名能接收到消息,所以没有关系
|
|
71
|
+
opener: window.location.origin
|
|
72
|
+
});
|
|
73
|
+
return popup;
|
|
74
|
+
};
|
|
75
|
+
const DID_DOMAIN_SERVICE_DID = "z2qaGosS3rZ7m5ttP3Nd4V4qczR9TryTcRV4p";
|
|
76
|
+
export const getDidDomainServiceURL = async (url) => {
|
|
77
|
+
if (!url || !url?.trim()) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
const axios = createAxios();
|
|
81
|
+
const urlObj = new URL(url);
|
|
82
|
+
urlObj.pathname = "__blocklet__.js";
|
|
83
|
+
urlObj.searchParams.set("type", "json");
|
|
84
|
+
const { data } = await axios.get(urlObj.toString());
|
|
85
|
+
const component = data?.componentMountPoints?.find((x) => x.did === DID_DOMAIN_SERVICE_DID);
|
|
86
|
+
const resultUrlObj = new URL(url);
|
|
87
|
+
resultUrlObj.pathname = component?.mountPoint;
|
|
88
|
+
const baseURL = resultUrlObj.toString();
|
|
89
|
+
const apiURL = joinURL(baseURL, "/api");
|
|
90
|
+
return { base: baseURL, api: apiURL };
|
|
91
|
+
};
|
package/es/locales/en.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import flat from "flat";
|
|
2
|
+
export default flat({
|
|
3
|
+
embed: {
|
|
4
|
+
iconTip: "Click to view subscription details"
|
|
5
|
+
},
|
|
6
|
+
buy: {
|
|
7
|
+
button: {
|
|
8
|
+
title: "Buy DID Domain"
|
|
9
|
+
},
|
|
10
|
+
status: {
|
|
11
|
+
inProgress: "Please wait while we are processing your request, the domain will be automatically resolved to the current app after the purchase...",
|
|
12
|
+
success: "Purchase completed!"
|
|
13
|
+
},
|
|
14
|
+
error: {
|
|
15
|
+
failedToCreateSession: "Failed to create session"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
});
|
package/es/locales/zh.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import flat from "flat";
|
|
2
|
+
export default flat({
|
|
3
|
+
embed: {
|
|
4
|
+
iconTip: "\u70B9\u51FB\u67E5\u770B\u8BA2\u9605\u8BE6\u60C5"
|
|
5
|
+
},
|
|
6
|
+
buy: {
|
|
7
|
+
button: {
|
|
8
|
+
title: "\u8D2D\u4E70 DID \u57DF\u540D"
|
|
9
|
+
},
|
|
10
|
+
status: {
|
|
11
|
+
inProgress: "\u8BF7\u7A0D\u7B49\uFF0C\u6211\u4EEC\u6B63\u5728\u5904\u7406\u60A8\u7684\u8BF7\u6C42\uFF0C\u8D2D\u4E70\u57DF\u540D\u540E\u4F1A\u81EA\u52A8\u89E3\u6790\u5230\u5F53\u524D\u7684\u5E94\u7528...",
|
|
12
|
+
success: "\u8D2D\u4E70\u5B8C\u6210\uFF01"
|
|
13
|
+
},
|
|
14
|
+
error: {
|
|
15
|
+
failedToCreateSession: "\u521B\u5EFA\u4F1A\u8BDD\u5931\u8D25"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
});
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
declare module '@arcblock/ux/*';
|
|
2
|
+
|
|
3
|
+
declare module '@arcblock/did-connect/*';
|
|
4
|
+
|
|
5
|
+
declare module '*.png';
|
|
6
|
+
|
|
7
|
+
declare module 'flat';
|
|
8
|
+
|
|
9
|
+
declare module '@arcblock/*';
|
|
10
|
+
|
|
11
|
+
declare module '@blocklet/*';
|
|
12
|
+
|
|
13
|
+
declare module 'pretty-ms-i18n';
|
|
14
|
+
|
|
15
|
+
declare var blocklet: import('@blocklet/sdk').WindowBlocklet;
|
package/lib/buy.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Locale } from '@arcblock/ux/lib/type';
|
|
2
|
+
interface Props {
|
|
3
|
+
delegatee: string;
|
|
4
|
+
delegateePk: string;
|
|
5
|
+
didDomainURL: string;
|
|
6
|
+
locale: Locale;
|
|
7
|
+
title?: string;
|
|
8
|
+
onSuccess?: (data: {
|
|
9
|
+
nftDid: string;
|
|
10
|
+
domain: string;
|
|
11
|
+
chainHost: string;
|
|
12
|
+
}) => void;
|
|
13
|
+
}
|
|
14
|
+
export default function Buy(props: Props): import("react").JSX.Element;
|
|
15
|
+
export {};
|
package/lib/buy.js
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
module.exports = Buy;
|
|
7
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
8
|
+
var _LoadingButton = _interopRequireDefault(require("@mui/lab/LoadingButton"));
|
|
9
|
+
var _Dialog = _interopRequireDefault(require("@arcblock/ux/lib/Dialog"));
|
|
10
|
+
var _context = require("@arcblock/ux/lib/Locale/context");
|
|
11
|
+
var _CheckCircle = _interopRequireDefault(require("@mui/icons-material/CheckCircle"));
|
|
12
|
+
var _ShoppingCart = _interopRequireDefault(require("@mui/icons-material/ShoppingCart"));
|
|
13
|
+
var _Alert = _interopRequireDefault(require("@mui/material/Alert"));
|
|
14
|
+
var _Box = _interopRequireDefault(require("@mui/material/Box"));
|
|
15
|
+
var _CircularProgress = _interopRequireDefault(require("@mui/material/CircularProgress"));
|
|
16
|
+
var _Typography = _interopRequireDefault(require("@mui/material/Typography"));
|
|
17
|
+
var _ahooks = require("ahooks");
|
|
18
|
+
var _react = require("react");
|
|
19
|
+
var _api = require("./libs/api");
|
|
20
|
+
var _util = require("./libs/util");
|
|
21
|
+
var _locales = require("./locales");
|
|
22
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
23
|
+
var BuyState = /* @__PURE__ */(BuyState2 => {
|
|
24
|
+
BuyState2[BuyState2["Prepare"] = 1] = "Prepare";
|
|
25
|
+
BuyState2[BuyState2["InProgress"] = 2] = "InProgress";
|
|
26
|
+
BuyState2[BuyState2["Success"] = 4] = "Success";
|
|
27
|
+
BuyState2[BuyState2["Completed"] = 8] = "Completed";
|
|
28
|
+
return BuyState2;
|
|
29
|
+
})(BuyState || {});
|
|
30
|
+
const preFetch = async ({
|
|
31
|
+
didDomainURL,
|
|
32
|
+
delegatee,
|
|
33
|
+
delegateePk
|
|
34
|
+
}) => {
|
|
35
|
+
const serviceURL = await (0, _util.getDidDomainServiceURL)(didDomainURL);
|
|
36
|
+
if (!serviceURL) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
const apiRequest = (0, _api.create)({
|
|
40
|
+
baseURL: serviceURL.api
|
|
41
|
+
});
|
|
42
|
+
const {
|
|
43
|
+
data
|
|
44
|
+
} = await apiRequest.post("/payment/session", {
|
|
45
|
+
delegatee,
|
|
46
|
+
delegateePk
|
|
47
|
+
});
|
|
48
|
+
return {
|
|
49
|
+
sessionId: data.sessionId,
|
|
50
|
+
baseURL: serviceURL.base
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
function Component({
|
|
54
|
+
delegatee,
|
|
55
|
+
delegateePk,
|
|
56
|
+
didDomainURL,
|
|
57
|
+
locale,
|
|
58
|
+
title = "",
|
|
59
|
+
onSuccess = () => {},
|
|
60
|
+
...props
|
|
61
|
+
}) {
|
|
62
|
+
const {
|
|
63
|
+
t
|
|
64
|
+
} = (0, _context.useLocaleContext)();
|
|
65
|
+
const [state, setState] = (0, _ahooks.useSetState)({
|
|
66
|
+
currentState: 1 /* Prepare */
|
|
67
|
+
});
|
|
68
|
+
const popup = (0, _react.useRef)(null);
|
|
69
|
+
const sessionRequest = (0, _ahooks.useRequest)(async () => {
|
|
70
|
+
const data = await preFetch({
|
|
71
|
+
didDomainURL,
|
|
72
|
+
delegatee,
|
|
73
|
+
delegateePk
|
|
74
|
+
});
|
|
75
|
+
if (!data) {
|
|
76
|
+
return data;
|
|
77
|
+
}
|
|
78
|
+
return data;
|
|
79
|
+
}, {
|
|
80
|
+
debounceWait: 500,
|
|
81
|
+
debounceLeading: true,
|
|
82
|
+
debounceTrailing: false,
|
|
83
|
+
debounceMaxWait: 3e3,
|
|
84
|
+
refreshDeps: [],
|
|
85
|
+
onError(error) {
|
|
86
|
+
console.error(error);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
const onMessage = (0, _ahooks.useMemoizedFn)(event => {
|
|
90
|
+
if (event.data.type === "didDomain.success") {
|
|
91
|
+
onSuccess?.({
|
|
92
|
+
nftDid: event.data?.nftDid,
|
|
93
|
+
domain: event.data?.domain,
|
|
94
|
+
chainHost: event.data?.chainHost
|
|
95
|
+
});
|
|
96
|
+
popup.current?.close();
|
|
97
|
+
popup.current = null;
|
|
98
|
+
setState({
|
|
99
|
+
currentState: 4 /* Success */
|
|
100
|
+
});
|
|
101
|
+
setTimeout(() => {
|
|
102
|
+
setState({
|
|
103
|
+
currentState: 8 /* Completed */
|
|
104
|
+
});
|
|
105
|
+
}, 2e3);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
(0, _ahooks.useUnmount)(() => {
|
|
109
|
+
try {
|
|
110
|
+
window.removeEventListener("message", onMessage);
|
|
111
|
+
popup.current?.close();
|
|
112
|
+
popup.current = null;
|
|
113
|
+
} catch (error) {
|
|
114
|
+
console.warn("Failed to close popup", error);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
const handleCloseDialog = (0, _ahooks.useMemoizedFn)(() => {
|
|
118
|
+
setState({
|
|
119
|
+
currentState: 1 /* Prepare */
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
const handleOpenDialog = (0, _ahooks.useMemoizedFn)(() => {
|
|
123
|
+
setState({
|
|
124
|
+
currentState: 2 /* InProgress */
|
|
125
|
+
});
|
|
126
|
+
if (!sessionRequest.data) {
|
|
127
|
+
console.error("Failed to create session");
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
handleCreatedSession({
|
|
131
|
+
sessionId: sessionRequest.data.sessionId,
|
|
132
|
+
baseURL: sessionRequest.data.baseURL
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
const handleCreatedSession = (0, _ahooks.useMemoizedFn)(({
|
|
136
|
+
sessionId,
|
|
137
|
+
baseURL
|
|
138
|
+
}) => {
|
|
139
|
+
window.addEventListener("message", onMessage);
|
|
140
|
+
const urlObj = new URL(baseURL);
|
|
141
|
+
urlObj.searchParams.set("sessionId", sessionId);
|
|
142
|
+
urlObj.searchParams.set("locale", locale);
|
|
143
|
+
urlObj.searchParams.set("embed", "1");
|
|
144
|
+
popup.current = (0, _util.openPopup)(urlObj.toString());
|
|
145
|
+
const timer = setInterval(() => {
|
|
146
|
+
if (popup.current?.closed) {
|
|
147
|
+
clearInterval(timer);
|
|
148
|
+
handleCloseDialog();
|
|
149
|
+
}
|
|
150
|
+
}, 1e3);
|
|
151
|
+
return () => clearInterval(timer);
|
|
152
|
+
});
|
|
153
|
+
return /* @__PURE__ */(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
154
|
+
children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_LoadingButton.default, {
|
|
155
|
+
loading: sessionRequest.loading,
|
|
156
|
+
onClick: handleOpenDialog,
|
|
157
|
+
variant: "contained",
|
|
158
|
+
startIcon: /* @__PURE__ */(0, _jsxRuntime.jsx)(_ShoppingCart.default, {}),
|
|
159
|
+
...props,
|
|
160
|
+
children: title || t("buy.button.title")
|
|
161
|
+
}), /* @__PURE__ */(0, _jsxRuntime.jsxs)(_Dialog.default, {
|
|
162
|
+
fullWidth: true,
|
|
163
|
+
maxWidth: "xs",
|
|
164
|
+
open: state.currentState > 1 /* Prepare */ && state.currentState < 8 /* Completed */,
|
|
165
|
+
onClose: handleCloseDialog,
|
|
166
|
+
children: [!sessionRequest.error && /* @__PURE__ */(0, _jsxRuntime.jsxs)(_Box.default, {
|
|
167
|
+
sx: {
|
|
168
|
+
display: "flex",
|
|
169
|
+
alignItems: "center",
|
|
170
|
+
flexDirection: "column",
|
|
171
|
+
gap: 2
|
|
172
|
+
},
|
|
173
|
+
children: [state.currentState === 2 /* InProgress */ && /* @__PURE__ */(0, _jsxRuntime.jsx)(_CircularProgress.default, {
|
|
174
|
+
size: 50
|
|
175
|
+
}), state.currentState === 4 /* Success */ && /* @__PURE__ */(0, _jsxRuntime.jsx)(_CheckCircle.default, {
|
|
176
|
+
sx: {
|
|
177
|
+
color: "primary.main",
|
|
178
|
+
fontSize: "5rem"
|
|
179
|
+
}
|
|
180
|
+
}), state.currentState === 2 /* InProgress */ && /* @__PURE__ */(0, _jsxRuntime.jsx)(_Typography.default, {
|
|
181
|
+
children: t("buy.status.inProgress")
|
|
182
|
+
}), state.currentState === 4 /* Success */ && /* @__PURE__ */(0, _jsxRuntime.jsx)(_Typography.default, {
|
|
183
|
+
children: t("buy.status.success")
|
|
184
|
+
})]
|
|
185
|
+
}), sessionRequest.error && /* @__PURE__ */(0, _jsxRuntime.jsx)(_Alert.default, {
|
|
186
|
+
severity: "error",
|
|
187
|
+
children: t("buy.error.failedToCreateSession")
|
|
188
|
+
})]
|
|
189
|
+
})]
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
function Buy(props) {
|
|
193
|
+
return /* @__PURE__ */(0, _jsxRuntime.jsx)(_context.LocaleProvider, {
|
|
194
|
+
locale: props.locale,
|
|
195
|
+
translations: _locales.translations,
|
|
196
|
+
children: /* @__PURE__ */(0, _jsxRuntime.jsx)(Component, {
|
|
197
|
+
...props
|
|
198
|
+
})
|
|
199
|
+
});
|
|
200
|
+
}
|
package/lib/domain.d.ts
ADDED
package/lib/domain.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Domain = Domain;
|
|
7
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
8
|
+
var _context = require("@arcblock/ux/lib/Locale/context");
|
|
9
|
+
var _material = require("@mui/material");
|
|
10
|
+
var _Box = _interopRequireDefault(require("@mui/material/Box"));
|
|
11
|
+
var _Popover = _interopRequireDefault(require("@mui/material/Popover"));
|
|
12
|
+
var _styles = require("@mui/material/styles");
|
|
13
|
+
var _useMediaQuery = _interopRequireDefault(require("@mui/material/useMediaQuery"));
|
|
14
|
+
var _react = require("react");
|
|
15
|
+
var _reactUse = require("react-use");
|
|
16
|
+
var _useSetState = _interopRequireDefault(require("react-use/lib/useSetState"));
|
|
17
|
+
var _ufo = require("ufo");
|
|
18
|
+
var _util = require("./libs/util");
|
|
19
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
20
|
+
function Domain({
|
|
21
|
+
nftDid,
|
|
22
|
+
didDomainURL,
|
|
23
|
+
locale,
|
|
24
|
+
sx = {}
|
|
25
|
+
}) {
|
|
26
|
+
const {
|
|
27
|
+
t
|
|
28
|
+
} = (0, _context.useLocaleContext)();
|
|
29
|
+
const [state, setState] = (0, _useSetState.default)({
|
|
30
|
+
safeIframeRef: null,
|
|
31
|
+
popoverAnchorEl: null
|
|
32
|
+
});
|
|
33
|
+
const iframeRef = (0, _react.useRef)(null);
|
|
34
|
+
const theme = (0, _styles.useTheme)();
|
|
35
|
+
const isMobile = (0, _useMediaQuery.default)(theme.breakpoints.down("md"));
|
|
36
|
+
const handlePopoverClick = event => {
|
|
37
|
+
setState({
|
|
38
|
+
popoverAnchorEl: event.currentTarget
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
const handlePopoverClose = () => {
|
|
42
|
+
setState({
|
|
43
|
+
popoverAnchorEl: null
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
const urlState = (0, _reactUse.useAsync)(async () => {
|
|
47
|
+
const result = await (0, _util.getDidDomainServiceURL)(didDomainURL);
|
|
48
|
+
if (!result) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
return result.base;
|
|
52
|
+
});
|
|
53
|
+
if (!urlState.value) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
if (urlState.loading) {
|
|
57
|
+
return /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.CircularProgress, {});
|
|
58
|
+
}
|
|
59
|
+
const iframeSrc = (0, _ufo.joinURL)(urlState.value, `/embed/domain?nft-did=${nftDid}&locale=${locale}`);
|
|
60
|
+
return /* @__PURE__ */(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
61
|
+
children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Tooltip, {
|
|
62
|
+
title: t("embed.iconTip"),
|
|
63
|
+
children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_Box.default, {
|
|
64
|
+
component: "img",
|
|
65
|
+
src: (0, _ufo.joinURL)(didDomainURL, "/.well-known/service/blocklet/logo"),
|
|
66
|
+
alt: "logo",
|
|
67
|
+
onClick: handlePopoverClick,
|
|
68
|
+
sx: [{
|
|
69
|
+
width: 16,
|
|
70
|
+
height: 16
|
|
71
|
+
}, (0, _util.mergeSx)({
|
|
72
|
+
cursor: "pointer"
|
|
73
|
+
}, sx)]
|
|
74
|
+
})
|
|
75
|
+
}), /* @__PURE__ */(0, _jsxRuntime.jsx)(_Popover.default, {
|
|
76
|
+
id: "popover-info",
|
|
77
|
+
open: Boolean(state.popoverAnchorEl),
|
|
78
|
+
anchorEl: state.popoverAnchorEl,
|
|
79
|
+
onClose: handlePopoverClose,
|
|
80
|
+
anchorOrigin: {
|
|
81
|
+
vertical: "bottom",
|
|
82
|
+
horizontal: "right"
|
|
83
|
+
},
|
|
84
|
+
children: /* @__PURE__ */(0, _jsxRuntime.jsx)("iframe", {
|
|
85
|
+
ref: iframeRef,
|
|
86
|
+
title: t("common.subscription"),
|
|
87
|
+
width: isMobile ? "320px" : "400px",
|
|
88
|
+
height: "350px",
|
|
89
|
+
style: {
|
|
90
|
+
border: 0,
|
|
91
|
+
display: "block"
|
|
92
|
+
},
|
|
93
|
+
src: iframeSrc
|
|
94
|
+
})
|
|
95
|
+
})]
|
|
96
|
+
});
|
|
97
|
+
}
|
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "Buy", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _buy.default;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "Domain", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _domain.Domain;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "translations", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _locales.translations;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
var _buy = _interopRequireDefault(require("./buy"));
|
|
25
|
+
var _domain = require("./domain");
|
|
26
|
+
var _locales = require("./locales");
|
|
27
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
package/lib/libs/api.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
module.exports = exports.create = void 0;
|
|
7
|
+
var _context = require("@arcblock/ux/lib/Locale/context");
|
|
8
|
+
var _jsSdk = require("@blocklet/js-sdk");
|
|
9
|
+
var _ufo = require("ufo");
|
|
10
|
+
const axios = (0, _jsSdk.createAxios)({});
|
|
11
|
+
axios.interceptors.request.use(config => {
|
|
12
|
+
const prefix = window.blocklet ? window.blocklet.prefix : "/";
|
|
13
|
+
config.baseURL = prefix || "";
|
|
14
|
+
config.url = (0, _ufo.joinURL)("/api", String(config.url));
|
|
15
|
+
config.timeout = 2e5;
|
|
16
|
+
config.params = config.params || {};
|
|
17
|
+
const searchParams = new URLSearchParams(config.url.split("?")[1]);
|
|
18
|
+
if (!searchParams.has("locale")) {
|
|
19
|
+
config.params.locale = (0, _context.getLocale)();
|
|
20
|
+
}
|
|
21
|
+
return config;
|
|
22
|
+
}, error => Promise.reject(error));
|
|
23
|
+
const create = (...args) => (0, _jsSdk.createAxios)(...args);
|
|
24
|
+
exports.create = create;
|
|
25
|
+
module.exports = axios;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export declare const SEARCH_BUTTON_WIDTH = 120;
|
|
2
|
+
export declare const COMMON_REQUEST_OPTIONS: {
|
|
3
|
+
debounceWait: number;
|
|
4
|
+
debounceLeading: boolean;
|
|
5
|
+
debounceTrailing: boolean;
|
|
6
|
+
debounceMaxWait: number;
|
|
7
|
+
};
|
|
8
|
+
export declare const formatLocale: (locale?: string) => string;
|
|
9
|
+
export declare const formatError: (err: any, t: any) => any;
|
|
10
|
+
export declare const mergeSx: (initial: any, sx: any) => any;
|
|
11
|
+
export declare const getChainHost: () => any;
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* @param {string} url - 打开一个弹窗
|
|
15
|
+
* @returns
|
|
16
|
+
*/
|
|
17
|
+
export declare const openPopup: (url: string, { width, height, name }?: {
|
|
18
|
+
width?: number | undefined;
|
|
19
|
+
height?: number | undefined;
|
|
20
|
+
name?: string | undefined;
|
|
21
|
+
}) => Window;
|
|
22
|
+
export declare const getDidDomainServiceURL: (url: string) => Promise<{
|
|
23
|
+
base: string;
|
|
24
|
+
api: string;
|
|
25
|
+
} | null>;
|
package/lib/libs/util.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.openPopup = exports.mergeSx = exports.getDidDomainServiceURL = exports.getChainHost = exports.formatLocale = exports.formatError = exports.SEARCH_BUTTON_WIDTH = exports.COMMON_REQUEST_OPTIONS = void 0;
|
|
7
|
+
var _ufo = require("ufo");
|
|
8
|
+
var _api = require("./api");
|
|
9
|
+
const SEARCH_BUTTON_WIDTH = exports.SEARCH_BUTTON_WIDTH = 120;
|
|
10
|
+
const COMMON_REQUEST_OPTIONS = exports.COMMON_REQUEST_OPTIONS = {
|
|
11
|
+
debounceWait: 500,
|
|
12
|
+
debounceLeading: true,
|
|
13
|
+
debounceTrailing: false,
|
|
14
|
+
debounceMaxWait: 3e3
|
|
15
|
+
};
|
|
16
|
+
const formatLocale = (locale = "en") => {
|
|
17
|
+
if (locale === "tw") {
|
|
18
|
+
return "zh";
|
|
19
|
+
}
|
|
20
|
+
return locale;
|
|
21
|
+
};
|
|
22
|
+
exports.formatLocale = formatLocale;
|
|
23
|
+
const formatError = (err, t) => {
|
|
24
|
+
const {
|
|
25
|
+
errors,
|
|
26
|
+
response
|
|
27
|
+
} = err;
|
|
28
|
+
if (Array.isArray(errors)) {
|
|
29
|
+
return errors.map(x => x.message).join("\n");
|
|
30
|
+
}
|
|
31
|
+
const joiError = err.response?.data?.error;
|
|
32
|
+
if (Array.isArray(joiError?.details)) {
|
|
33
|
+
const formatted = joiError?.details.map(e => {
|
|
34
|
+
const errorMessage = e.message.replace(/["]/g, "'");
|
|
35
|
+
const errorPath = e.path.join(".");
|
|
36
|
+
return `${errorPath}: ${errorMessage}`;
|
|
37
|
+
});
|
|
38
|
+
return `Validate failed: ${formatted.join(";")}`;
|
|
39
|
+
}
|
|
40
|
+
if (response?.data?.code) {
|
|
41
|
+
return t(`error.${response?.data?.code}`);
|
|
42
|
+
}
|
|
43
|
+
if (response?.data?.message) {
|
|
44
|
+
return response.data.message;
|
|
45
|
+
}
|
|
46
|
+
if (response) {
|
|
47
|
+
return `Request failed: ${response.status} ${response.statusText}: ${JSON.stringify(response.data)}`;
|
|
48
|
+
}
|
|
49
|
+
return err.message;
|
|
50
|
+
};
|
|
51
|
+
exports.formatError = formatError;
|
|
52
|
+
const mergeSx = (initial, sx) => {
|
|
53
|
+
if (!sx) {
|
|
54
|
+
return initial;
|
|
55
|
+
}
|
|
56
|
+
if (!initial) {
|
|
57
|
+
return sx;
|
|
58
|
+
}
|
|
59
|
+
return [initial, ...(Array.isArray(sx) ? sx : [sx])];
|
|
60
|
+
};
|
|
61
|
+
exports.mergeSx = mergeSx;
|
|
62
|
+
const getChainHost = () => window.blocklet?.preferences?.chainHost || "";
|
|
63
|
+
exports.getChainHost = getChainHost;
|
|
64
|
+
const openPopup = (url, {
|
|
65
|
+
width = 600,
|
|
66
|
+
height = 700,
|
|
67
|
+
name = "did-domain:popup"
|
|
68
|
+
} = {}) => {
|
|
69
|
+
const left = window.screenX + (window.innerWidth - width) / 2;
|
|
70
|
+
const top = window.screenY + (window.innerHeight - height) / 2;
|
|
71
|
+
const windowFeatures = [`left=${left}`, `top=${top}`, `width=${width}`, `height=${height}`, "resizable=no",
|
|
72
|
+
// not working
|
|
73
|
+
"scrollbars=yes", "status=yes", "popup=yes"];
|
|
74
|
+
const popup = window.open("", name, windowFeatures.join(","));
|
|
75
|
+
if (popup === null) {
|
|
76
|
+
throw new Error("Failed to open popup");
|
|
77
|
+
}
|
|
78
|
+
popup.location.href = (0, _ufo.withQuery)(url, {
|
|
79
|
+
// NOTICE: 携带当前页面的 origin,用于在 popup 中通过该参数判断是否可以发送 postMessage,即使该参数被伪造,最终也只有该域名能接收到消息,所以没有关系
|
|
80
|
+
opener: window.location.origin
|
|
81
|
+
});
|
|
82
|
+
return popup;
|
|
83
|
+
};
|
|
84
|
+
exports.openPopup = openPopup;
|
|
85
|
+
const DID_DOMAIN_SERVICE_DID = "z2qaGosS3rZ7m5ttP3Nd4V4qczR9TryTcRV4p";
|
|
86
|
+
const getDidDomainServiceURL = async url => {
|
|
87
|
+
if (!url || !url?.trim()) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
const axios = (0, _api.create)();
|
|
91
|
+
const urlObj = new URL(url);
|
|
92
|
+
urlObj.pathname = "__blocklet__.js";
|
|
93
|
+
urlObj.searchParams.set("type", "json");
|
|
94
|
+
const {
|
|
95
|
+
data
|
|
96
|
+
} = await axios.get(urlObj.toString());
|
|
97
|
+
const component = data?.componentMountPoints?.find(x => x.did === DID_DOMAIN_SERVICE_DID);
|
|
98
|
+
const resultUrlObj = new URL(url);
|
|
99
|
+
resultUrlObj.pathname = component?.mountPoint;
|
|
100
|
+
const baseURL = resultUrlObj.toString();
|
|
101
|
+
const apiURL = (0, _ufo.joinURL)(baseURL, "/api");
|
|
102
|
+
return {
|
|
103
|
+
base: baseURL,
|
|
104
|
+
api: apiURL
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
exports.getDidDomainServiceURL = getDidDomainServiceURL;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
var _flat = _interopRequireDefault(require("flat"));
|
|
8
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
module.exports = (0, _flat.default)({
|
|
10
|
+
embed: {
|
|
11
|
+
iconTip: "Click to view subscription details"
|
|
12
|
+
},
|
|
13
|
+
buy: {
|
|
14
|
+
button: {
|
|
15
|
+
title: "Buy DID Domain"
|
|
16
|
+
},
|
|
17
|
+
status: {
|
|
18
|
+
inProgress: "Please wait while we are processing your request, the domain will be automatically resolved to the current app after the purchase...",
|
|
19
|
+
success: "Purchase completed!"
|
|
20
|
+
},
|
|
21
|
+
error: {
|
|
22
|
+
failedToCreateSession: "Failed to create session"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.translations = void 0;
|
|
7
|
+
var _en = _interopRequireDefault(require("./en"));
|
|
8
|
+
var _zh = _interopRequireDefault(require("./zh"));
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
+
const translations = exports.translations = {
|
|
11
|
+
zh: _zh.default,
|
|
12
|
+
en: _en.default
|
|
13
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
var _flat = _interopRequireDefault(require("flat"));
|
|
8
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
module.exports = (0, _flat.default)({
|
|
10
|
+
embed: {
|
|
11
|
+
iconTip: "\u70B9\u51FB\u67E5\u770B\u8BA2\u9605\u8BE6\u60C5"
|
|
12
|
+
},
|
|
13
|
+
buy: {
|
|
14
|
+
button: {
|
|
15
|
+
title: "\u8D2D\u4E70 DID \u57DF\u540D"
|
|
16
|
+
},
|
|
17
|
+
status: {
|
|
18
|
+
inProgress: "\u8BF7\u7A0D\u7B49\uFF0C\u6211\u4EEC\u6B63\u5728\u5904\u7406\u60A8\u7684\u8BF7\u6C42\uFF0C\u8D2D\u4E70\u57DF\u540D\u540E\u4F1A\u81EA\u52A8\u89E3\u6790\u5230\u5F53\u524D\u7684\u5E94\u7528...",
|
|
19
|
+
success: "\u8D2D\u4E70\u5B8C\u6210\uFF01"
|
|
20
|
+
},
|
|
21
|
+
error: {
|
|
22
|
+
failedToCreateSession: "\u521B\u5EFA\u4F1A\u8BDD\u5931\u8D25"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
});
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
declare module '@arcblock/ux/*';
|
|
2
|
+
|
|
3
|
+
declare module '@arcblock/did-connect/*';
|
|
4
|
+
|
|
5
|
+
declare module '*.png';
|
|
6
|
+
|
|
7
|
+
declare module 'flat';
|
|
8
|
+
|
|
9
|
+
declare module '@arcblock/*';
|
|
10
|
+
|
|
11
|
+
declare module '@blocklet/*';
|
|
12
|
+
|
|
13
|
+
declare module 'pretty-ms-i18n';
|
|
14
|
+
|
|
15
|
+
declare var blocklet: import('@blocklet/sdk').WindowBlocklet;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/did-domain-react",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "Reusable react components for DID Domain",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"watch": "CONSOLA_LEVEL=1 nodemon -e .jsx,.js,.ts,.tsx -w src -x 'yalc publish --push'",
|
|
24
24
|
"precommit": "CI=1 npm run lint",
|
|
25
25
|
"prepush": "CI=1 npm run lint",
|
|
26
|
-
"
|
|
26
|
+
"prepublishOnly": "npm run build",
|
|
27
27
|
"test": "node tools/jest.js",
|
|
28
28
|
"coverage": "npm run test -- --coverage",
|
|
29
29
|
"storybook": "storybook dev -p 6006",
|