@arcblock/ux 2.11.26 → 2.11.27
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/lib/DID/index.d.ts +15 -17
- package/lib/DID/index.js +195 -119
- package/lib/Header/header.d.ts +1 -1
- package/lib/Util/constant.d.ts +1 -1
- package/lib/Util/constant.js +1 -1
- package/package.json +5 -5
- package/src/DID/index.tsx +203 -141
- package/src/Header/header.tsx +1 -1
- package/src/Util/constant.ts +1 -1
package/lib/DID/index.d.ts
CHANGED
@@ -1,28 +1,26 @@
|
|
1
|
-
import
|
1
|
+
import { ModalProps } from '@mui/material';
|
2
2
|
import { IDidAddressWrapper } from '../Address';
|
3
3
|
import { HTMLDidAddressElement } from '../Address/did-address';
|
4
|
-
|
5
|
-
interface IDIDPropTypes extends IDidAddressWrapper {
|
4
|
+
interface DIDOwnProps {
|
6
5
|
did: string;
|
7
|
-
size?: number;
|
8
|
-
component?: React.ElementType;
|
9
|
-
copyable?: true | false;
|
10
|
-
responsive?: true | false;
|
11
|
-
showCopyButtonInTooltip?: false | true;
|
12
|
-
showAvatar?: true | false;
|
13
|
-
showQrcode?: false | true;
|
14
|
-
inline?: false | true;
|
15
|
-
append?: any;
|
16
|
-
compact?: false | true;
|
17
|
-
startChars?: number;
|
18
|
-
endChars?: number;
|
19
|
-
locale?: Locale;
|
20
6
|
chainId?: string;
|
21
7
|
roleType?: number;
|
8
|
+
showAvatar?: true | false;
|
9
|
+
showQrcode?: false | true;
|
10
|
+
}
|
11
|
+
export interface DIDProps extends DIDOwnProps, Omit<IDidAddressWrapper, 'ref'> {
|
22
12
|
}
|
23
13
|
export interface HTMLDIDElement extends HTMLDidAddressElement {
|
24
14
|
openQRCode: () => void;
|
25
15
|
closeQRCode: () => void;
|
26
16
|
}
|
27
|
-
declare const DID:
|
17
|
+
export declare const DID: import("react").ForwardRefExoticComponent<DIDProps & import("react").RefAttributes<HTMLDIDElement>>;
|
18
|
+
export interface DIDDialogProps extends DIDProps {
|
19
|
+
open: boolean;
|
20
|
+
fullScreen?: false | true;
|
21
|
+
fullWidth?: false | true;
|
22
|
+
scroll?: 'body' | 'paper';
|
23
|
+
onClose?: ModalProps['onClose'];
|
24
|
+
}
|
25
|
+
export declare function DIDDialog({ did, chainId, roleType, showAvatar, open, fullScreen, fullWidth, scroll, onClose, locale, ...rest }: DIDDialogProps): import("react/jsx-runtime").JSX.Element;
|
28
26
|
export default DID;
|
package/lib/DID/index.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { jsx as _jsx,
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
2
2
|
import { getDIDMotifInfo } from '@arcblock/did-motif';
|
3
3
|
import { types } from '@ocap/mcrypto';
|
4
4
|
import QRCode from 'qrcode.react';
|
@@ -6,7 +6,7 @@ import { Icon } from '@iconify/react';
|
|
6
6
|
import IconQrCode from '@iconify-icons/material-symbols/qr-code-rounded';
|
7
7
|
import { Box, Dialog, DialogContent, Typography } from '@mui/material';
|
8
8
|
import { useCreation, useMemoizedFn } from 'ahooks';
|
9
|
-
import
|
9
|
+
import { forwardRef, useImperativeHandle, useRef, useState } from 'react';
|
10
10
|
import Address from '../Address';
|
11
11
|
import Avatar from '../Avatar';
|
12
12
|
import { temp as colors } from '../Colors';
|
@@ -27,6 +27,7 @@ const translations = {
|
|
27
27
|
};
|
28
28
|
const DEFAULT_CHAIN_ID = 'xenon-2020-01-15';
|
29
29
|
const CHAIN_ID_MAP = {
|
30
|
+
main: DEFAULT_CHAIN_ID,
|
30
31
|
'main.abtnetwork.io': DEFAULT_CHAIN_ID,
|
31
32
|
'beta.abtnetwork.io': 'beta'
|
32
33
|
};
|
@@ -68,9 +69,52 @@ const getAvatarSize = (didMotifInfo, isEthDid, size) => {
|
|
68
69
|
}
|
69
70
|
return size;
|
70
71
|
};
|
71
|
-
|
72
|
+
function useDIDInfo({
|
73
|
+
did,
|
74
|
+
showAvatar
|
75
|
+
}) {
|
76
|
+
const isEthDid = isEthereumDid(did);
|
77
|
+
const didMotifInfo = isEthDid ? undefined : getDIDMotifInfo(did);
|
78
|
+
const content = useCreation(() => {
|
79
|
+
if (isEthDid) {
|
80
|
+
return did;
|
81
|
+
}
|
82
|
+
return `${DID_PREFIX}${did}`;
|
83
|
+
}, [did, isEthDid]);
|
84
|
+
const getPrepend = useMemoizedFn((avatarSize, keyPrefix) => [/*#__PURE__*/_jsx("span", {
|
85
|
+
style: {
|
86
|
+
flex: '0 0 auto',
|
87
|
+
color: getFontColor(did, didMotifInfo, isEthDid)
|
88
|
+
},
|
89
|
+
children: "DID:"
|
90
|
+
}, `${keyPrefix}-prefix-did-${avatarSize}`), /*#__PURE__*/_jsxs("span", {
|
91
|
+
className: "did-address-text",
|
92
|
+
children: [isEthDid ? 'ETH' : 'ABT', ":"]
|
93
|
+
}, `${keyPrefix}-prefix-abt-${avatarSize}`), showAvatar && /*#__PURE__*/_jsx(Avatar, {
|
94
|
+
src: "",
|
95
|
+
did: did,
|
96
|
+
size: getAvatarSize(didMotifInfo, isEthDid, avatarSize || 18),
|
97
|
+
style: {
|
98
|
+
display: 'inline-flex',
|
99
|
+
alignItems: 'center',
|
100
|
+
marginLeft: 2,
|
101
|
+
marginRight: 4
|
102
|
+
},
|
103
|
+
blockiesPadding: false,
|
104
|
+
className: "did-address-avatar"
|
105
|
+
}, `${keyPrefix}-avatar-${avatarSize}`)]);
|
106
|
+
return {
|
107
|
+
isEthDid,
|
108
|
+
didMotifInfo,
|
109
|
+
content,
|
110
|
+
getPrepend
|
111
|
+
};
|
112
|
+
}
|
113
|
+
export const DID = /*#__PURE__*/forwardRef((props, ref) => {
|
72
114
|
const {
|
73
115
|
did,
|
116
|
+
chainId,
|
117
|
+
roleType,
|
74
118
|
showAvatar = true,
|
75
119
|
showQrcode = false,
|
76
120
|
locale = 'en',
|
@@ -104,48 +148,14 @@ const DID = /*#__PURE__*/forwardRef((props, ref) => {
|
|
104
148
|
sx
|
105
149
|
};
|
106
150
|
const addressRef = useRef(null);
|
107
|
-
const
|
108
|
-
|
151
|
+
const {
|
152
|
+
content,
|
153
|
+
getPrepend
|
154
|
+
} = useDIDInfo({
|
155
|
+
did,
|
156
|
+
showAvatar
|
109
157
|
});
|
110
|
-
let chainId = props.chainId || '';
|
111
|
-
try {
|
112
|
-
if (!chainId) {
|
113
|
-
const chainHostUrl = window.blocklet?.CHAIN_HOST;
|
114
|
-
if (chainHostUrl) {
|
115
|
-
const chainHost = new URL(chainHostUrl).hostname;
|
116
|
-
if (chainHost) {
|
117
|
-
chainId = CHAIN_ID_MAP[chainHost];
|
118
|
-
}
|
119
|
-
}
|
120
|
-
}
|
121
|
-
} catch {
|
122
|
-
console.warn('Failed to parse chainHost');
|
123
|
-
}
|
124
158
|
const [open, setOpen] = useState(false);
|
125
|
-
const isEthDid = isEthereumDid(did);
|
126
|
-
const didMotifInfo = isEthDid ? undefined : getDIDMotifInfo(did);
|
127
|
-
const getPrepend = (avatarSize, keyPrefix) => [/*#__PURE__*/_jsx("span", {
|
128
|
-
style: {
|
129
|
-
flex: '0 0 auto',
|
130
|
-
color: getFontColor(did, didMotifInfo, isEthDid)
|
131
|
-
},
|
132
|
-
children: "DID:"
|
133
|
-
}, `${keyPrefix}-prefix-did-${avatarSize}`), /*#__PURE__*/_jsx("span", {
|
134
|
-
className: "did-address-text",
|
135
|
-
children: "ABT:"
|
136
|
-
}, `${keyPrefix}-prefix-abt-${avatarSize}`), showAvatar && /*#__PURE__*/_jsx(Avatar, {
|
137
|
-
src: "",
|
138
|
-
did: did,
|
139
|
-
size: getAvatarSize(didMotifInfo, isEthDid, avatarSize || 18),
|
140
|
-
style: {
|
141
|
-
display: 'inline-flex',
|
142
|
-
alignItems: 'center',
|
143
|
-
marginLeft: 2,
|
144
|
-
marginRight: 4
|
145
|
-
},
|
146
|
-
blockiesPadding: false,
|
147
|
-
className: "did-address-avatar"
|
148
|
-
}, `${keyPrefix}-avatar-${avatarSize}`)];
|
149
159
|
const closeQrCode = useMemoizedFn(() => {
|
150
160
|
setOpen(false);
|
151
161
|
});
|
@@ -164,34 +174,10 @@ const DID = /*#__PURE__*/forwardRef((props, ref) => {
|
|
164
174
|
}
|
165
175
|
});
|
166
176
|
});
|
167
|
-
const downloadUrl = useCreation(() => {
|
168
|
-
if (['zh', 'en'].includes(locale)) {
|
169
|
-
return `https://www.didwallet.io/${locale}`;
|
170
|
-
}
|
171
|
-
return 'https://www.didwallet.io/en';
|
172
|
-
}, [locale]);
|
173
|
-
const downloadTips = useCreation(() => {
|
174
|
-
return /*#__PURE__*/_jsxs(_Fragment, {
|
175
|
-
children: [t('downloadTips'), ' ', /*#__PURE__*/_jsx(Box, {
|
176
|
-
component: "a",
|
177
|
-
href: downloadUrl,
|
178
|
-
target: "_blank",
|
179
|
-
rel: "noreferrer",
|
180
|
-
sx: {
|
181
|
-
color: colors.foregroundsFgInteractive,
|
182
|
-
textDecoration: 'none',
|
183
|
-
'&:hover': {
|
184
|
-
textDecoration: 'underline'
|
185
|
-
}
|
186
|
-
},
|
187
|
-
children: t('download')
|
188
|
-
})]
|
189
|
-
});
|
190
|
-
}, [downloadUrl]);
|
191
177
|
return /*#__PURE__*/_jsxs(_Fragment, {
|
192
178
|
children: [/*#__PURE__*/_jsx(Address, {
|
193
179
|
locale: locale,
|
194
|
-
content:
|
180
|
+
content: content,
|
195
181
|
...rest,
|
196
182
|
ref: addressRef,
|
197
183
|
prepend: getPrepend(rest.size, 'address'),
|
@@ -210,62 +196,152 @@ const DID = /*#__PURE__*/forwardRef((props, ref) => {
|
|
210
196
|
}) : null, rest.append]
|
211
197
|
}),
|
212
198
|
children: did
|
213
|
-
}, "address"), /*#__PURE__*/_jsx(
|
199
|
+
}, "address"), /*#__PURE__*/_jsx(DIDDialog, {
|
200
|
+
did: did,
|
201
|
+
chainId: chainId,
|
202
|
+
roleType: roleType,
|
203
|
+
showAvatar: showAvatar,
|
214
204
|
open: open,
|
215
205
|
onClose: closeQrCode,
|
216
|
-
|
217
|
-
|
206
|
+
...rest
|
207
|
+
})]
|
208
|
+
});
|
209
|
+
});
|
210
|
+
export function DIDDialog({
|
211
|
+
did,
|
212
|
+
chainId,
|
213
|
+
roleType,
|
214
|
+
showAvatar = true,
|
215
|
+
// DialogProps
|
216
|
+
open,
|
217
|
+
fullScreen = false,
|
218
|
+
fullWidth = false,
|
219
|
+
scroll = 'paper',
|
220
|
+
onClose,
|
221
|
+
// AddressProps
|
222
|
+
locale = 'en',
|
223
|
+
...rest
|
224
|
+
}) {
|
225
|
+
const t = useMemoizedFn((key, data = {}) => {
|
226
|
+
return translate(translations, key, locale, 'en', data);
|
227
|
+
});
|
228
|
+
const {
|
229
|
+
isEthDid,
|
230
|
+
content,
|
231
|
+
didMotifInfo,
|
232
|
+
getPrepend
|
233
|
+
} = useDIDInfo({
|
234
|
+
did,
|
235
|
+
showAvatar
|
236
|
+
});
|
237
|
+
const downloadUrl = useCreation(() => {
|
238
|
+
if (['zh', 'en'].includes(locale)) {
|
239
|
+
return `https://www.didwallet.io/${locale}`;
|
240
|
+
}
|
241
|
+
return 'https://www.didwallet.io/en';
|
242
|
+
}, [locale]);
|
243
|
+
const downloadTips = useCreation(() => {
|
244
|
+
return /*#__PURE__*/_jsxs(_Fragment, {
|
245
|
+
children: [t('downloadTips'), ' ', /*#__PURE__*/_jsx(Box, {
|
246
|
+
component: "a",
|
247
|
+
href: downloadUrl,
|
248
|
+
target: "_blank",
|
249
|
+
rel: "noreferrer",
|
218
250
|
sx: {
|
219
|
-
|
220
|
-
|
221
|
-
|
251
|
+
color: colors.foregroundsFgInteractive,
|
252
|
+
textDecoration: 'none',
|
253
|
+
'&:hover': {
|
254
|
+
textDecoration: 'underline'
|
255
|
+
}
|
256
|
+
},
|
257
|
+
children: t('download')
|
258
|
+
})]
|
259
|
+
});
|
260
|
+
}, [downloadUrl]);
|
261
|
+
const _chainId = useCreation(() => {
|
262
|
+
if (chainId) {
|
263
|
+
return CHAIN_ID_MAP[chainId] || chainId;
|
264
|
+
}
|
265
|
+
|
266
|
+
// 以太坊 DID 使用默认chainId '1'
|
267
|
+
if (isEthDid) return '1';
|
268
|
+
|
269
|
+
// 解析 chainHost 并获取对应的chainId
|
270
|
+
try {
|
271
|
+
const chainHostUrl = window.blocklet?.CHAIN_HOST;
|
272
|
+
const chainHost = new URL(chainHostUrl).hostname;
|
273
|
+
if (chainHost) {
|
274
|
+
return CHAIN_ID_MAP[chainHost] || DEFAULT_CHAIN_ID;
|
275
|
+
}
|
276
|
+
} catch (error) {
|
277
|
+
console.warn('Failed to parse chainHost:', error);
|
278
|
+
}
|
279
|
+
return DEFAULT_CHAIN_ID;
|
280
|
+
}, [isEthDid, chainId]);
|
281
|
+
const qrCodeLink = useCreation(() => {
|
282
|
+
if (isEthDid) {
|
283
|
+
return `ethereum:abtwallet.io/i?address=${content}&action=didRecognize&chainID=${_chainId}`;
|
284
|
+
}
|
285
|
+
return `abt://abtwallet.io/i?did=${content}&action=didRecognize&chainID=${_chainId}`;
|
286
|
+
}, [content, isEthDid, _chainId]);
|
287
|
+
return /*#__PURE__*/_jsx(Dialog, {
|
288
|
+
open: open,
|
289
|
+
onClose: onClose,
|
290
|
+
fullScreen: fullScreen,
|
291
|
+
fullWidth: fullWidth,
|
292
|
+
scroll: scroll,
|
293
|
+
maxWidth: "sm",
|
294
|
+
PaperProps: {
|
295
|
+
sx: {
|
296
|
+
boxShadow: 'none',
|
297
|
+
borderRadius: '12px'
|
298
|
+
}
|
299
|
+
},
|
300
|
+
children: /*#__PURE__*/_jsxs(DialogContent, {
|
301
|
+
align: "center",
|
302
|
+
sx: {
|
303
|
+
p: 3
|
222
304
|
},
|
223
|
-
children: /*#__PURE__*/
|
224
|
-
align: "center",
|
305
|
+
children: [/*#__PURE__*/_jsx(Typography, {
|
225
306
|
sx: {
|
226
|
-
|
307
|
+
mb: 2,
|
308
|
+
fontWeight: 500,
|
309
|
+
fontSize: 18
|
227
310
|
},
|
228
|
-
children:
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
}
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
fontSize: '12px',
|
263
|
-
mt: 1
|
264
|
-
},
|
265
|
-
children: downloadTips
|
266
|
-
})]
|
267
|
-
})
|
268
|
-
})]
|
311
|
+
children: t('scanQrcode', {
|
312
|
+
role: getRoleName(roleType || didMotifInfo?.roleType)
|
313
|
+
})
|
314
|
+
}), /*#__PURE__*/_jsx(QRCode
|
315
|
+
// eslint-disable-next-line max-len
|
316
|
+
, {
|
317
|
+
value: qrCodeLink,
|
318
|
+
size: 256,
|
319
|
+
renderAs: "svg",
|
320
|
+
level: "M"
|
321
|
+
}), /*#__PURE__*/_jsx(Box, {
|
322
|
+
sx: {
|
323
|
+
mt: 1.5,
|
324
|
+
textAlign: 'center'
|
325
|
+
},
|
326
|
+
children: /*#__PURE__*/_jsx(Address, {
|
327
|
+
locale: locale,
|
328
|
+
content: content,
|
329
|
+
prepend: getPrepend(16, 'dialog'),
|
330
|
+
...rest,
|
331
|
+
size: 16,
|
332
|
+
copyable: true,
|
333
|
+
children: did
|
334
|
+
}, "dialog-address")
|
335
|
+
}), /*#__PURE__*/_jsx(Typography, {
|
336
|
+
variant: "body2",
|
337
|
+
sx: {
|
338
|
+
color: colors.textSubtitle,
|
339
|
+
fontSize: '12px',
|
340
|
+
mt: 1
|
341
|
+
},
|
342
|
+
children: downloadTips
|
343
|
+
})]
|
344
|
+
})
|
269
345
|
});
|
270
|
-
}
|
346
|
+
}
|
271
347
|
export default DID;
|
package/lib/Header/header.d.ts
CHANGED
@@ -14,7 +14,7 @@ export interface HeaderProps extends Omit<BoxProps, 'maxWidth'> {
|
|
14
14
|
prepend?: React.ReactNode;
|
15
15
|
align?: 'left' | 'right';
|
16
16
|
maxWidth?: Breakpoint | false;
|
17
|
-
homeLink?: string | ((brandContent: React.ReactNode) =>
|
17
|
+
homeLink?: string | ((brandContent: React.ReactNode) => JSX.Element | null);
|
18
18
|
}
|
19
19
|
/**
|
20
20
|
* Header 组件
|
package/lib/Util/constant.d.ts
CHANGED
@@ -7,7 +7,7 @@ export declare const RELAY_SOCKET_PREFIX = "/.well-known/service";
|
|
7
7
|
export declare const API_DID_PREFIX = "/api/did";
|
8
8
|
export declare const DASHBOARD_URL = "/.well-known/service/admin";
|
9
9
|
export declare const PROFILE_URL = "/.well-known/service/user";
|
10
|
-
export declare const DID_SPACE_URL = "/.well-known/service/user/
|
10
|
+
export declare const DID_SPACE_URL = "/.well-known/service/user/did-spaces";
|
11
11
|
export declare const NAVIGATION_URL = "/.well-known/service/admin/navigation";
|
12
12
|
export declare const DID_PREFIX = "did:abt:";
|
13
13
|
export declare const PASSPORT_STATUS: {
|
package/lib/Util/constant.js
CHANGED
@@ -7,7 +7,7 @@ export const RELAY_SOCKET_PREFIX = '/.well-known/service';
|
|
7
7
|
export const API_DID_PREFIX = '/api/did';
|
8
8
|
export const DASHBOARD_URL = `${BLOCKLET_SERVICE_PATH_PREFIX}/admin`;
|
9
9
|
export const PROFILE_URL = `${BLOCKLET_SERVICE_PATH_PREFIX}/user`;
|
10
|
-
export const DID_SPACE_URL = `${BLOCKLET_SERVICE_PATH_PREFIX}/user/
|
10
|
+
export const DID_SPACE_URL = `${BLOCKLET_SERVICE_PATH_PREFIX}/user/did-spaces`;
|
11
11
|
export const NAVIGATION_URL = `${BLOCKLET_SERVICE_PATH_PREFIX}/admin/navigation`;
|
12
12
|
export const DID_PREFIX = 'did:abt:';
|
13
13
|
export const PASSPORT_STATUS = {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@arcblock/ux",
|
3
|
-
"version": "2.11.
|
3
|
+
"version": "2.11.27",
|
4
4
|
"description": "Common used react components for arcblock products",
|
5
5
|
"keywords": [
|
6
6
|
"react",
|
@@ -68,12 +68,12 @@
|
|
68
68
|
"react": ">=18.2.0",
|
69
69
|
"react-router-dom": ">=6.22.3"
|
70
70
|
},
|
71
|
-
"gitHead": "
|
71
|
+
"gitHead": "cfe12067f89f858787bcbea4822f940a2e850b76",
|
72
72
|
"dependencies": {
|
73
73
|
"@arcblock/did-motif": "^1.1.13",
|
74
|
-
"@arcblock/icons": "^2.11.
|
75
|
-
"@arcblock/nft-display": "^2.11.
|
76
|
-
"@arcblock/react-hooks": "^2.11.
|
74
|
+
"@arcblock/icons": "^2.11.27",
|
75
|
+
"@arcblock/nft-display": "^2.11.27",
|
76
|
+
"@arcblock/react-hooks": "^2.11.27",
|
77
77
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
78
78
|
"@fontsource/inter": "^5.0.16",
|
79
79
|
"@fontsource/ubuntu-mono": "^5.0.18",
|
package/src/DID/index.tsx
CHANGED
@@ -3,9 +3,9 @@ import { types } from '@ocap/mcrypto';
|
|
3
3
|
import QRCode from 'qrcode.react';
|
4
4
|
import { Icon } from '@iconify/react';
|
5
5
|
import IconQrCode from '@iconify-icons/material-symbols/qr-code-rounded';
|
6
|
-
import { Box, Dialog, DialogContent, Typography } from '@mui/material';
|
6
|
+
import { Box, Dialog, DialogContent, ModalProps, Typography } from '@mui/material';
|
7
7
|
import { useCreation, useMemoizedFn } from 'ahooks';
|
8
|
-
import
|
8
|
+
import { forwardRef, useImperativeHandle, useRef, useState } from 'react';
|
9
9
|
|
10
10
|
import Address, { IDidAddressWrapper } from '../Address';
|
11
11
|
import Avatar from '../Avatar';
|
@@ -15,7 +15,6 @@ import { DID_PREFIX } from '../Util/constant';
|
|
15
15
|
import { HTMLDidAddressElement } from '../Address/did-address';
|
16
16
|
import { translate } from '../Locale/util';
|
17
17
|
import { getDIDColor, isEthereumDid } from '../Util';
|
18
|
-
import type { Locale } from '../type';
|
19
18
|
|
20
19
|
const translations = {
|
21
20
|
en: {
|
@@ -30,28 +29,10 @@ const translations = {
|
|
30
29
|
},
|
31
30
|
};
|
32
31
|
|
33
|
-
interface IDIDPropTypes extends IDidAddressWrapper {
|
34
|
-
did: string;
|
35
|
-
size?: number;
|
36
|
-
component?: React.ElementType;
|
37
|
-
copyable?: true | false;
|
38
|
-
responsive?: true | false;
|
39
|
-
showCopyButtonInTooltip?: false | true;
|
40
|
-
showAvatar?: true | false;
|
41
|
-
showQrcode?: false | true;
|
42
|
-
inline?: false | true;
|
43
|
-
append?: any;
|
44
|
-
compact?: false | true;
|
45
|
-
startChars?: number;
|
46
|
-
endChars?: number;
|
47
|
-
locale?: Locale;
|
48
|
-
chainId?: string;
|
49
|
-
roleType?: number;
|
50
|
-
}
|
51
|
-
|
52
32
|
const DEFAULT_CHAIN_ID = 'xenon-2020-01-15';
|
53
33
|
|
54
34
|
const CHAIN_ID_MAP: Record<string, string> = {
|
35
|
+
main: DEFAULT_CHAIN_ID,
|
55
36
|
'main.abtnetwork.io': DEFAULT_CHAIN_ID,
|
56
37
|
'beta.abtnetwork.io': 'beta',
|
57
38
|
};
|
@@ -99,14 +80,66 @@ const getAvatarSize = (didMotifInfo: any, isEthDid: boolean, size: number) => {
|
|
99
80
|
return size;
|
100
81
|
};
|
101
82
|
|
83
|
+
function useDIDInfo({ did, showAvatar }: { did: string; showAvatar?: boolean }) {
|
84
|
+
const isEthDid = isEthereumDid(did);
|
85
|
+
const didMotifInfo = isEthDid ? undefined : getDIDMotifInfo(did);
|
86
|
+
const content = useCreation(() => {
|
87
|
+
if (isEthDid) {
|
88
|
+
return did;
|
89
|
+
}
|
90
|
+
return `${DID_PREFIX}${did}`;
|
91
|
+
}, [did, isEthDid]);
|
92
|
+
|
93
|
+
const getPrepend = useMemoizedFn((avatarSize: number, keyPrefix: string) => [
|
94
|
+
<span
|
95
|
+
key={`${keyPrefix}-prefix-did-${avatarSize}`}
|
96
|
+
style={{ flex: '0 0 auto', color: getFontColor(did, didMotifInfo, isEthDid) }}>
|
97
|
+
DID:
|
98
|
+
</span>,
|
99
|
+
<span key={`${keyPrefix}-prefix-abt-${avatarSize}`} className="did-address-text">
|
100
|
+
{isEthDid ? 'ETH' : 'ABT'}:
|
101
|
+
</span>,
|
102
|
+
showAvatar && (
|
103
|
+
<Avatar
|
104
|
+
key={`${keyPrefix}-avatar-${avatarSize}`}
|
105
|
+
src=""
|
106
|
+
did={did}
|
107
|
+
size={getAvatarSize(didMotifInfo, isEthDid, avatarSize || 18)}
|
108
|
+
style={{ display: 'inline-flex', alignItems: 'center', marginLeft: 2, marginRight: 4 }}
|
109
|
+
blockiesPadding={false}
|
110
|
+
className="did-address-avatar"
|
111
|
+
/>
|
112
|
+
),
|
113
|
+
]);
|
114
|
+
|
115
|
+
return {
|
116
|
+
isEthDid,
|
117
|
+
didMotifInfo,
|
118
|
+
content,
|
119
|
+
getPrepend,
|
120
|
+
};
|
121
|
+
}
|
122
|
+
|
123
|
+
interface DIDOwnProps {
|
124
|
+
did: string;
|
125
|
+
chainId?: string;
|
126
|
+
roleType?: number;
|
127
|
+
showAvatar?: true | false;
|
128
|
+
showQrcode?: false | true;
|
129
|
+
}
|
130
|
+
|
131
|
+
export interface DIDProps extends DIDOwnProps, Omit<IDidAddressWrapper, 'ref'> {}
|
132
|
+
|
102
133
|
export interface HTMLDIDElement extends HTMLDidAddressElement {
|
103
134
|
openQRCode: () => void;
|
104
135
|
closeQRCode: () => void;
|
105
136
|
}
|
106
137
|
|
107
|
-
const DID = forwardRef<HTMLDIDElement,
|
138
|
+
export const DID = forwardRef<HTMLDIDElement, DIDProps>((props, ref) => {
|
108
139
|
const {
|
109
140
|
did,
|
141
|
+
chainId,
|
142
|
+
roleType,
|
110
143
|
showAvatar = true,
|
111
144
|
showQrcode = false,
|
112
145
|
locale = 'en',
|
@@ -142,50 +175,9 @@ const DID = forwardRef<HTMLDIDElement, IDIDPropTypes>((props, ref) => {
|
|
142
175
|
};
|
143
176
|
|
144
177
|
const addressRef = useRef<any>(null);
|
145
|
-
|
146
|
-
const t = useMemoizedFn((key, data = {}) => {
|
147
|
-
return translate(translations, key, locale, 'en', data);
|
148
|
-
});
|
149
|
-
|
150
|
-
let chainId = props.chainId || '';
|
151
|
-
try {
|
152
|
-
if (!chainId) {
|
153
|
-
const chainHostUrl = (window as any).blocklet?.CHAIN_HOST;
|
154
|
-
if (chainHostUrl) {
|
155
|
-
const chainHost = new URL(chainHostUrl).hostname;
|
156
|
-
if (chainHost) {
|
157
|
-
chainId = CHAIN_ID_MAP[chainHost];
|
158
|
-
}
|
159
|
-
}
|
160
|
-
}
|
161
|
-
} catch {
|
162
|
-
console.warn('Failed to parse chainHost');
|
163
|
-
}
|
178
|
+
const { content, getPrepend } = useDIDInfo({ did, showAvatar });
|
164
179
|
const [open, setOpen] = useState(false);
|
165
|
-
const isEthDid = isEthereumDid(did);
|
166
|
-
const didMotifInfo = isEthDid ? undefined : getDIDMotifInfo(did);
|
167
180
|
|
168
|
-
const getPrepend = (avatarSize: number, keyPrefix: string) => [
|
169
|
-
<span
|
170
|
-
key={`${keyPrefix}-prefix-did-${avatarSize}`}
|
171
|
-
style={{ flex: '0 0 auto', color: getFontColor(did, didMotifInfo, isEthDid) }}>
|
172
|
-
DID:
|
173
|
-
</span>,
|
174
|
-
<span key={`${keyPrefix}-prefix-abt-${avatarSize}`} className="did-address-text">
|
175
|
-
ABT:
|
176
|
-
</span>,
|
177
|
-
showAvatar && (
|
178
|
-
<Avatar
|
179
|
-
key={`${keyPrefix}-avatar-${avatarSize}`}
|
180
|
-
src=""
|
181
|
-
did={did}
|
182
|
-
size={getAvatarSize(didMotifInfo, isEthDid, avatarSize || 18)}
|
183
|
-
style={{ display: 'inline-flex', alignItems: 'center', marginLeft: 2, marginRight: 4 }}
|
184
|
-
blockiesPadding={false}
|
185
|
-
className="did-address-avatar"
|
186
|
-
/>
|
187
|
-
),
|
188
|
-
];
|
189
181
|
const closeQrCode = useMemoizedFn(() => {
|
190
182
|
setOpen(false);
|
191
183
|
});
|
@@ -209,41 +201,12 @@ const DID = forwardRef<HTMLDIDElement, IDIDPropTypes>((props, ref) => {
|
|
209
201
|
);
|
210
202
|
});
|
211
203
|
|
212
|
-
const downloadUrl = useCreation(() => {
|
213
|
-
if (['zh', 'en'].includes(locale)) {
|
214
|
-
return `https://www.didwallet.io/${locale}`;
|
215
|
-
}
|
216
|
-
return 'https://www.didwallet.io/en';
|
217
|
-
}, [locale]);
|
218
|
-
|
219
|
-
const downloadTips = useCreation(() => {
|
220
|
-
return (
|
221
|
-
<>
|
222
|
-
{t('downloadTips')}{' '}
|
223
|
-
<Box
|
224
|
-
component="a"
|
225
|
-
href={downloadUrl}
|
226
|
-
target="_blank"
|
227
|
-
rel="noreferrer"
|
228
|
-
sx={{
|
229
|
-
color: colors.foregroundsFgInteractive,
|
230
|
-
textDecoration: 'none',
|
231
|
-
'&:hover': {
|
232
|
-
textDecoration: 'underline',
|
233
|
-
},
|
234
|
-
}}>
|
235
|
-
{t('download')}
|
236
|
-
</Box>
|
237
|
-
</>
|
238
|
-
);
|
239
|
-
}, [downloadUrl]);
|
240
|
-
|
241
204
|
return (
|
242
205
|
<>
|
243
206
|
<Address
|
244
207
|
key="address"
|
245
208
|
locale={locale}
|
246
|
-
content={
|
209
|
+
content={content}
|
247
210
|
{...rest}
|
248
211
|
ref={addressRef}
|
249
212
|
prepend={getPrepend(rest.size, 'address')}
|
@@ -268,56 +231,155 @@ const DID = forwardRef<HTMLDIDElement, IDIDPropTypes>((props, ref) => {
|
|
268
231
|
}>
|
269
232
|
{did}
|
270
233
|
</Address>
|
271
|
-
|
272
|
-
|
234
|
+
<DIDDialog
|
235
|
+
did={did}
|
236
|
+
chainId={chainId}
|
237
|
+
roleType={roleType}
|
238
|
+
showAvatar={showAvatar}
|
273
239
|
open={open}
|
274
240
|
onClose={closeQrCode}
|
275
|
-
|
276
|
-
|
277
|
-
sx: {
|
278
|
-
boxShadow: 'none',
|
279
|
-
borderRadius: '12px',
|
280
|
-
},
|
281
|
-
}}>
|
282
|
-
{/* @ts-ignore */}
|
283
|
-
<DialogContent align="center" sx={{ p: 3 }}>
|
284
|
-
<Typography sx={{ mb: 2, fontWeight: 500, fontSize: 18 }}>
|
285
|
-
{t('scanQrcode', { role: getRoleName(props.roleType || didMotifInfo?.roleType) })}
|
286
|
-
</Typography>
|
287
|
-
<QRCode
|
288
|
-
// eslint-disable-next-line max-len
|
289
|
-
value={`abt://abtwallet.io/i?did=${DID_PREFIX}${did}&action=didRecognize&chainID=${
|
290
|
-
chainId || DEFAULT_CHAIN_ID
|
291
|
-
}`}
|
292
|
-
size={256}
|
293
|
-
renderAs="svg"
|
294
|
-
level="M"
|
295
|
-
/>
|
296
|
-
<Box sx={{ mt: 1.5, textAlign: 'center' }}>
|
297
|
-
<Address
|
298
|
-
key="dialog-address"
|
299
|
-
locale={locale}
|
300
|
-
content={`${DID_PREFIX}${did}`}
|
301
|
-
prepend={getPrepend(16, 'dialog')}
|
302
|
-
{...rest}
|
303
|
-
size={16}
|
304
|
-
copyable>
|
305
|
-
{did}
|
306
|
-
</Address>
|
307
|
-
</Box>
|
308
|
-
<Typography
|
309
|
-
variant="body2"
|
310
|
-
sx={{
|
311
|
-
color: colors.textSubtitle,
|
312
|
-
fontSize: '12px',
|
313
|
-
mt: 1,
|
314
|
-
}}>
|
315
|
-
{downloadTips}
|
316
|
-
</Typography>
|
317
|
-
</DialogContent>
|
318
|
-
</Dialog>
|
241
|
+
{...rest}
|
242
|
+
/>
|
319
243
|
</>
|
320
244
|
);
|
321
245
|
});
|
322
246
|
|
247
|
+
export interface DIDDialogProps extends DIDProps {
|
248
|
+
// DialogProps
|
249
|
+
open: boolean;
|
250
|
+
fullScreen?: false | true;
|
251
|
+
fullWidth?: false | true;
|
252
|
+
scroll?: 'body' | 'paper';
|
253
|
+
onClose?: ModalProps['onClose'];
|
254
|
+
}
|
255
|
+
export function DIDDialog({
|
256
|
+
did,
|
257
|
+
chainId,
|
258
|
+
roleType,
|
259
|
+
showAvatar = true,
|
260
|
+
// DialogProps
|
261
|
+
open,
|
262
|
+
fullScreen = false,
|
263
|
+
fullWidth = false,
|
264
|
+
scroll = 'paper',
|
265
|
+
onClose,
|
266
|
+
// AddressProps
|
267
|
+
locale = 'en',
|
268
|
+
...rest
|
269
|
+
}: DIDDialogProps) {
|
270
|
+
const t = useMemoizedFn((key, data = {}) => {
|
271
|
+
return translate(translations, key, locale, 'en', data);
|
272
|
+
});
|
273
|
+
|
274
|
+
const { isEthDid, content, didMotifInfo, getPrepend } = useDIDInfo({ did, showAvatar });
|
275
|
+
|
276
|
+
const downloadUrl = useCreation(() => {
|
277
|
+
if (['zh', 'en'].includes(locale)) {
|
278
|
+
return `https://www.didwallet.io/${locale}`;
|
279
|
+
}
|
280
|
+
return 'https://www.didwallet.io/en';
|
281
|
+
}, [locale]);
|
282
|
+
|
283
|
+
const downloadTips = useCreation(() => {
|
284
|
+
return (
|
285
|
+
<>
|
286
|
+
{t('downloadTips')}{' '}
|
287
|
+
<Box
|
288
|
+
component="a"
|
289
|
+
href={downloadUrl}
|
290
|
+
target="_blank"
|
291
|
+
rel="noreferrer"
|
292
|
+
sx={{
|
293
|
+
color: colors.foregroundsFgInteractive,
|
294
|
+
textDecoration: 'none',
|
295
|
+
'&:hover': {
|
296
|
+
textDecoration: 'underline',
|
297
|
+
},
|
298
|
+
}}>
|
299
|
+
{t('download')}
|
300
|
+
</Box>
|
301
|
+
</>
|
302
|
+
);
|
303
|
+
}, [downloadUrl]);
|
304
|
+
|
305
|
+
const _chainId = useCreation(() => {
|
306
|
+
if (chainId) {
|
307
|
+
return CHAIN_ID_MAP[chainId] || chainId;
|
308
|
+
}
|
309
|
+
|
310
|
+
// 以太坊 DID 使用默认chainId '1'
|
311
|
+
if (isEthDid) return '1';
|
312
|
+
|
313
|
+
// 解析 chainHost 并获取对应的chainId
|
314
|
+
try {
|
315
|
+
const chainHostUrl = (window as any).blocklet?.CHAIN_HOST;
|
316
|
+
const chainHost = new URL(chainHostUrl).hostname;
|
317
|
+
if (chainHost) {
|
318
|
+
return CHAIN_ID_MAP[chainHost] || DEFAULT_CHAIN_ID;
|
319
|
+
}
|
320
|
+
} catch (error) {
|
321
|
+
console.warn('Failed to parse chainHost:', error);
|
322
|
+
}
|
323
|
+
return DEFAULT_CHAIN_ID;
|
324
|
+
}, [isEthDid, chainId]);
|
325
|
+
|
326
|
+
const qrCodeLink = useCreation(() => {
|
327
|
+
if (isEthDid) {
|
328
|
+
return `ethereum:abtwallet.io/i?address=${content}&action=didRecognize&chainID=${_chainId}`;
|
329
|
+
}
|
330
|
+
return `abt://abtwallet.io/i?did=${content}&action=didRecognize&chainID=${_chainId}`;
|
331
|
+
}, [content, isEthDid, _chainId]);
|
332
|
+
|
333
|
+
return (
|
334
|
+
<Dialog
|
335
|
+
open={open}
|
336
|
+
onClose={onClose}
|
337
|
+
fullScreen={fullScreen}
|
338
|
+
fullWidth={fullWidth}
|
339
|
+
scroll={scroll}
|
340
|
+
maxWidth="sm"
|
341
|
+
PaperProps={{
|
342
|
+
sx: {
|
343
|
+
boxShadow: 'none',
|
344
|
+
borderRadius: '12px',
|
345
|
+
},
|
346
|
+
}}>
|
347
|
+
{/* @ts-ignore */}
|
348
|
+
<DialogContent align="center" sx={{ p: 3 }}>
|
349
|
+
<Typography sx={{ mb: 2, fontWeight: 500, fontSize: 18 }}>
|
350
|
+
{t('scanQrcode', { role: getRoleName(roleType || didMotifInfo?.roleType) })}
|
351
|
+
</Typography>
|
352
|
+
<QRCode
|
353
|
+
// eslint-disable-next-line max-len
|
354
|
+
value={qrCodeLink}
|
355
|
+
size={256}
|
356
|
+
renderAs="svg"
|
357
|
+
level="M"
|
358
|
+
/>
|
359
|
+
<Box sx={{ mt: 1.5, textAlign: 'center' }}>
|
360
|
+
<Address
|
361
|
+
key="dialog-address"
|
362
|
+
locale={locale}
|
363
|
+
content={content}
|
364
|
+
prepend={getPrepend(16, 'dialog')}
|
365
|
+
{...rest}
|
366
|
+
size={16}
|
367
|
+
copyable>
|
368
|
+
{did}
|
369
|
+
</Address>
|
370
|
+
</Box>
|
371
|
+
<Typography
|
372
|
+
variant="body2"
|
373
|
+
sx={{
|
374
|
+
color: colors.textSubtitle,
|
375
|
+
fontSize: '12px',
|
376
|
+
mt: 1,
|
377
|
+
}}>
|
378
|
+
{downloadTips}
|
379
|
+
</Typography>
|
380
|
+
</DialogContent>
|
381
|
+
</Dialog>
|
382
|
+
);
|
383
|
+
}
|
384
|
+
|
323
385
|
export default DID;
|
package/src/Header/header.tsx
CHANGED
@@ -18,7 +18,7 @@ export interface HeaderProps extends Omit<BoxProps, 'maxWidth'> {
|
|
18
18
|
prepend?: React.ReactNode;
|
19
19
|
align?: 'left' | 'right';
|
20
20
|
maxWidth?: Breakpoint | false;
|
21
|
-
homeLink?: string | ((brandContent: React.ReactNode) =>
|
21
|
+
homeLink?: string | ((brandContent: React.ReactNode) => JSX.Element | null);
|
22
22
|
}
|
23
23
|
|
24
24
|
/**
|
package/src/Util/constant.ts
CHANGED
@@ -9,7 +9,7 @@ export const API_DID_PREFIX = '/api/did';
|
|
9
9
|
|
10
10
|
export const DASHBOARD_URL = `${BLOCKLET_SERVICE_PATH_PREFIX}/admin`;
|
11
11
|
export const PROFILE_URL = `${BLOCKLET_SERVICE_PATH_PREFIX}/user`;
|
12
|
-
export const DID_SPACE_URL = `${BLOCKLET_SERVICE_PATH_PREFIX}/user/
|
12
|
+
export const DID_SPACE_URL = `${BLOCKLET_SERVICE_PATH_PREFIX}/user/did-spaces`;
|
13
13
|
export const NAVIGATION_URL = `${BLOCKLET_SERVICE_PATH_PREFIX}/admin/navigation`;
|
14
14
|
|
15
15
|
export const DID_PREFIX = 'did:abt:';
|