@arcblock/did-connect-react 3.4.13 → 3.4.15

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.
@@ -1,6 +1,12 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import { Box } from '@mui/material';
3
- import { LOGIN_PROVIDER, LOGIN_PROVIDER_ICON_SIZE, LOGIN_PROVIDER_NAME } from '@arcblock/ux/lib/Util/constant';
3
+ import {
4
+ LOGIN_PROVIDER,
5
+ LOGIN_PROVIDER_ICON_SIZE,
6
+ LOGIN_PROVIDER_NAME,
7
+ LAST_USED_LOGIN_METHOD,
8
+ WALLET_LOGIN_METHOD,
9
+ } from '@arcblock/ux/lib/Util/constant';
4
10
  import { getWebWalletUrl } from '@arcblock/ux/lib/Util/wallet';
5
11
  import noop from 'lodash/noop';
6
12
  import { useMemoizedFn } from 'ahooks';
@@ -59,6 +65,7 @@ export default function ConnectChooseList({
59
65
  });
60
66
  passkeyState.reset();
61
67
  connectState.chooseMethod = item.provider;
68
+ connectState.walletMethod = ''; // 清除 wallet 登录方式,防止状态污染
62
69
 
63
70
  const sourceAppPid = extraParams?.sourceAppPid;
64
71
  try {
@@ -74,6 +81,8 @@ export default function ConnectChooseList({
74
81
  Cookie.remove('connected_wallet_os', cookieOptions);
75
82
 
76
83
  if (loginResult?.sessionToken) {
84
+ // 登录成功后记录最后使用的登录方式(用于显示 Last Used 标签)
85
+ localStorage.setItem(LAST_USED_LOGIN_METHOD, item.provider);
77
86
  await onSuccess(
78
87
  {
79
88
  ...loginResult,
@@ -104,6 +113,7 @@ export default function ConnectChooseList({
104
113
  await onReset();
105
114
  tokenState.status = 'created';
106
115
  connectState.chooseMethod = 'wallet';
116
+ connectState.walletMethod = ''; // 重置 wallet 登录方式,确保扫码登录能正确记录
107
117
  });
108
118
 
109
119
  const emailPlugin = useEmailPlugin({ baseUrl });
@@ -162,7 +172,7 @@ export default function ConnectChooseList({
162
172
  {showMobileLogin && (
163
173
  <MobileLoginItem
164
174
  t={t}
165
- isLatest={lastLoginMethod && lastLoginMethod === LOGIN_PROVIDER.WALLET}
175
+ isLatest={lastLoginMethod && lastLoginMethod === WALLET_LOGIN_METHOD.MOBILE}
166
176
  ref={walletLoginRef}
167
177
  tokenState={tokenState}
168
178
  sx={[size === 'small' ? { p: 1 } : { p: 2 }]}
@@ -184,7 +194,7 @@ export default function ConnectChooseList({
184
194
  )}
185
195
  {showWebLogin && (
186
196
  <WebLoginItem
187
- isLatest={lastLoginMethod && lastLoginMethod === LOGIN_PROVIDER.WALLET}
197
+ isLatest={lastLoginMethod && lastLoginMethod === WALLET_LOGIN_METHOD.WEB}
188
198
  ref={webLoginRef}
189
199
  tokenState={tokenState}
190
200
  webWalletUrl={webWalletUrl}
@@ -264,6 +274,7 @@ export default function ConnectChooseList({
264
274
  localStorage.setItem(GA_LAST_LOGIN_METHOD, LOGIN_PROVIDER.PASSKEY);
265
275
  const connectFn = passkeyLoginRef.current.connect;
266
276
  connectState.chooseMethod = 'passkey';
277
+ connectState.walletMethod = ''; // 清除 wallet 登录方式,防止状态污染
267
278
  connectState.retryConnect = () => {
268
279
  passkeyState.verifying = true;
269
280
  connectState.chooseMethod = 'passkey';
@@ -1,6 +1,12 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import { Box } from '@mui/material';
3
- import { LOGIN_PROVIDER, LOGIN_PROVIDER_NAME, LOGIN_PROVIDER_ICON_SIZE } from '@arcblock/ux/lib/Util/constant';
3
+ import {
4
+ LOGIN_PROVIDER,
5
+ LOGIN_PROVIDER_NAME,
6
+ LOGIN_PROVIDER_ICON_SIZE,
7
+ LAST_USED_LOGIN_METHOD,
8
+ WALLET_LOGIN_METHOD,
9
+ } from '@arcblock/ux/lib/Util/constant';
4
10
  import { checkSameProtocol, getWebWalletUrl } from '@arcblock/ux/lib/Util/wallet';
5
11
  import noop from 'lodash/noop';
6
12
  import { useMemoizedFn, useCreation } from 'ahooks';
@@ -80,6 +86,7 @@ export default function ConnectProviderList({
80
86
  });
81
87
  passkeyState.reset();
82
88
  connectState.chooseMethod = item.provider;
89
+ connectState.walletMethod = ''; // 清除 wallet 登录方式,防止状态污染
83
90
 
84
91
  const sourceAppPid = extraParams?.sourceAppPid;
85
92
  try {
@@ -95,6 +102,8 @@ export default function ConnectProviderList({
95
102
  Cookie.remove('connected_wallet_os', cookieOptions);
96
103
 
97
104
  if (loginResult?.sessionToken) {
105
+ // 登录成功后记录最后使用的登录方式(用于显示 Last Used 标签)
106
+ localStorage.setItem(LAST_USED_LOGIN_METHOD, item.provider);
98
107
  await onSuccess(
99
108
  {
100
109
  ...loginResult,
@@ -125,6 +134,7 @@ export default function ConnectProviderList({
125
134
  await onReset();
126
135
  tokenState.status = 'created';
127
136
  connectState.chooseMethod = 'wallet';
137
+ connectState.walletMethod = ''; // 重置 wallet 登录方式,确保扫码登录能正确记录
128
138
  });
129
139
 
130
140
  const handleMobileLoginClick = useMemoizedFn(async () => {
@@ -217,7 +227,7 @@ export default function ConnectProviderList({
217
227
  return (
218
228
  <MobileLoginItem
219
229
  t={t}
220
- isLatest={lastLoginMethod && lastLoginMethod === LOGIN_PROVIDER.WALLET}
230
+ isLatest={lastLoginMethod && lastLoginMethod === WALLET_LOGIN_METHOD.MOBILE}
221
231
  key={LOGIN_PROVIDER.WALLET}
222
232
  ref={walletLoginRef}
223
233
  tokenState={tokenState}
@@ -237,7 +247,7 @@ export default function ConnectProviderList({
237
247
  return shouldShowWebLoginItem ? (
238
248
  <WebLoginItem
239
249
  t={t}
240
- isLatest={lastLoginMethod && lastLoginMethod === LOGIN_PROVIDER.WALLET}
250
+ isLatest={lastLoginMethod && lastLoginMethod === WALLET_LOGIN_METHOD.WEB}
241
251
  key={LOGIN_PROVIDER.WALLET}
242
252
  ref={webLoginRef}
243
253
  tokenState={tokenState}
@@ -273,6 +283,7 @@ export default function ConnectProviderList({
273
283
  localStorage.setItem(GA_LAST_LOGIN_METHOD, LOGIN_PROVIDER.PASSKEY);
274
284
  const connectFn = passkeyLoginRef.current.connect;
275
285
  connectState.chooseMethod = 'passkey';
286
+ connectState.walletMethod = ''; // 清除 wallet 登录方式,防止状态污染
276
287
  connectState.retryConnect = () => {
277
288
  passkeyState.verifying = true;
278
289
  connectState.chooseMethod = 'passkey';
@@ -7,7 +7,7 @@ import noop from 'lodash/noop';
7
7
  import { useImperativeHandle } from 'react';
8
8
  import { mergeSx } from '@arcblock/ux/lib/Util/style';
9
9
  import ProviderIcon from '@arcblock/ux/lib/DIDConnect/provider-icon';
10
- import { LOGIN_PROVIDER, LOGIN_PROVIDER_ICON_SIZE } from '@arcblock/ux/lib/Util/constant';
10
+ import { LOGIN_PROVIDER, LOGIN_PROVIDER_ICON_SIZE, WALLET_LOGIN_METHOD } from '@arcblock/ux/lib/Util/constant';
11
11
 
12
12
  import { useStateContext } from '../../contexts/state';
13
13
  import LoginMethodItem from './login-method-item';
@@ -27,7 +27,7 @@ export default function MobileLoginItem({
27
27
  const currentState = useReactive({
28
28
  loading: false,
29
29
  });
30
- const { isWalletWebview } = useStateContext();
30
+ const { isWalletWebview, connectState } = useStateContext();
31
31
  const title = 'DID Wallet';
32
32
  const browser = useBrowser();
33
33
 
@@ -120,10 +120,13 @@ export default function MobileLoginItem({
120
120
  }
121
121
 
122
122
  if (isWalletWebview) {
123
+ connectState.walletMethod = WALLET_LOGIN_METHOD.MOBILE;
123
124
  handleWalletConnect();
124
125
  } else if (browser.mobile.any || isTablet) {
126
+ connectState.walletMethod = WALLET_LOGIN_METHOD.MOBILE;
125
127
  handleOpenDeeplink();
126
128
  } else {
129
+ connectState.walletMethod = WALLET_LOGIN_METHOD.SCAN;
127
130
  fallback();
128
131
  }
129
132
  });
@@ -1,7 +1,7 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import { useImperativeHandle, useRef } from 'react';
3
3
  import { useMemoizedFn } from 'ahooks';
4
- import { LOGIN_PROVIDER } from '@arcblock/ux/lib/Util/constant';
4
+ import { LOGIN_PROVIDER, LAST_USED_LOGIN_METHOD } from '@arcblock/ux/lib/Util/constant';
5
5
 
6
6
  import PasskeyActions from '../../../Passkey/actions';
7
7
  import { getAppId } from '../../../utils';
@@ -11,8 +11,10 @@ export default function PasskeyLoginItem({ ref = null, onSuccess, tokenState, be
11
11
  const { extraParams, lastLoginMethod } = useStateContext();
12
12
  const passkeyActionRef = useRef(null);
13
13
 
14
- const handleSuccess = useMemoizedFn((result) =>
15
- onSuccess(
14
+ const handleSuccess = useMemoizedFn((result) => {
15
+ // 登录成功后记录最后使用的登录方式(用于显示 Last Used 标签)
16
+ localStorage.setItem(LAST_USED_LOGIN_METHOD, LOGIN_PROVIDER.PASSKEY);
17
+ return onSuccess(
16
18
  {
17
19
  ...result,
18
20
  encrypted: false,
@@ -22,8 +24,8 @@ export default function PasskeyLoginItem({ ref = null, onSuccess, tokenState, be
22
24
  sourceAppPid: extraParams?.sourceAppPid,
23
25
  connected_app: getAppId(tokenState.appInfo, tokenState.memberAppInfo),
24
26
  }
25
- )
26
- );
27
+ );
28
+ });
27
29
 
28
30
  useImperativeHandle(ref, () => ({
29
31
  connect: passkeyActionRef.current.click,
@@ -7,7 +7,7 @@ import noop from 'lodash/noop';
7
7
  import omit from 'lodash/omit';
8
8
  import { useImperativeHandle } from 'react';
9
9
  import ProviderIcon from '@arcblock/ux/lib/DIDConnect/provider-icon';
10
- import { LOGIN_PROVIDER, LOGIN_PROVIDER_ICON_SIZE } from '@arcblock/ux/lib/Util/constant';
10
+ import { LOGIN_PROVIDER, LOGIN_PROVIDER_ICON_SIZE, WALLET_LOGIN_METHOD } from '@arcblock/ux/lib/Util/constant';
11
11
 
12
12
  import LoginMethodItem from './login-method-item';
13
13
  import { useStateContext } from '../../contexts/state';
@@ -24,7 +24,7 @@ export default function WebLoginItem({
24
24
  autoConnect = true,
25
25
  ...rest
26
26
  }) {
27
- const { browserBrand } = useStateContext();
27
+ const { browserBrand, connectState } = useStateContext();
28
28
  const extension = detectWalletExtension();
29
29
  const currentState = useReactive({
30
30
  loading: false,
@@ -44,6 +44,8 @@ export default function WebLoginItem({
44
44
  appInfo: tokenState.appInfo,
45
45
  memberAppInfo: tokenState.memberAppInfo,
46
46
  });
47
+ // Web Wallet 和扩展都使用 WEB 类型
48
+ connectState.walletMethod = WALLET_LOGIN_METHOD.WEB;
47
49
  if (openResult?.type === 'web') {
48
50
  currentState.loading = false;
49
51
  } else {
@@ -21,6 +21,8 @@ import {
21
21
  OAUTH_PROVIDER,
22
22
  DID_CONNECT_MEDIUM_WIDTH,
23
23
  DID_CONNECT_SMALL_WIDTH,
24
+ LAST_USED_LOGIN_METHOD,
25
+ WALLET_LOGIN_METHOD,
24
26
  } from '@arcblock/ux/lib/Util/constant';
25
27
  import QRCode from '@arcblock/ux/lib/QRCode';
26
28
  import { DIDConnectFooter } from '@arcblock/ux/lib/DIDConnect';
@@ -99,6 +101,16 @@ function Connect({
99
101
  setShowWalletOptions,
100
102
  lastLoginMethod,
101
103
  } = useStateContext();
104
+
105
+ // 包装 onSuccess,在 wallet 登录成功时记录细分的登录方式
106
+ const wrappedOnSuccess = useMemoizedFn((...args) => {
107
+ // walletMethod 存在说明是点击按钮的 wallet 登录,为空说明是直接扫码登录
108
+ // 直接扫码登录不对应任何按钮,设置为 SCAN 避免旧的 last-used 继续显示
109
+ const method = connectState.walletMethod || WALLET_LOGIN_METHOD.SCAN;
110
+ localStorage.setItem(LAST_USED_LOGIN_METHOD, method);
111
+ return onSuccess(...args);
112
+ });
113
+
102
114
  const { state, generate, cancelWhenScanned } = useToken({
103
115
  action,
104
116
  baseUrl,
@@ -108,7 +120,7 @@ function Connect({
108
120
  extraParams,
109
121
  prefix,
110
122
  onError,
111
- onSuccess,
123
+ onSuccess: wrappedOnSuccess,
112
124
  locale,
113
125
  tokenKey,
114
126
  encKey,
@@ -176,8 +188,14 @@ function Connect({
176
188
  );
177
189
  }, [state.status, oauthState.status, passkeyState.status, selectedPlugin?.state?.computedStatus]);
178
190
 
179
- const handleReset = useMemoizedFn(async () => {
191
+ const _onRecreateSession = useMemoizedFn(() => {
192
+ connectState.chooseMethod = 'wallet';
193
+ connectState.walletMethod = '';
180
194
  onRecreateSession();
195
+ });
196
+
197
+ const handleReset = useMemoizedFn(async () => {
198
+ _onRecreateSession();
181
199
  oauthState.reset();
182
200
  passkeyState.reset();
183
201
  await generate(false);
@@ -186,7 +204,7 @@ function Connect({
186
204
  connectState?.retryConnect();
187
205
  });
188
206
  const handleCancel = useMemoizedFn(() => {
189
- onRecreateSession();
207
+ _onRecreateSession();
190
208
  oauthState.reset();
191
209
  passkeyState.reset();
192
210
  selectedPlugin?.state?.reset();
@@ -9,7 +9,7 @@ import { translate } from '@arcblock/ux/lib/Locale/util';
9
9
  import { getCurrentApp, getMaster } from '@arcblock/ux/lib/Util/federated';
10
10
  import { getDIDMotifInfo } from '@arcblock/did-motif';
11
11
  import { getDIDColor, isEthereumDid } from '@arcblock/ux/lib/Util';
12
- import { GA_LAST_LOGIN_METHOD } from '@arcblock/ux/lib/withTracker/constant';
12
+ import { LAST_USED_LOGIN_METHOD } from '@arcblock/ux/lib/Util/constant';
13
13
 
14
14
  import useApps from '../hooks/use-apps';
15
15
  import { SessionContext } from '../../Session/context';
@@ -55,6 +55,7 @@ function StateProvider({
55
55
  autoActiveWebview: true,
56
56
  deeplink: undefined,
57
57
  chooseMethod: '',
58
+ walletMethod: '', // 细分的 wallet 登录方式,如 wallet-ext, wallet-web, wallet-scan 等
58
59
  retryConnect: noop,
59
60
  });
60
61
  const staticState = useRef({
@@ -71,7 +72,7 @@ function StateProvider({
71
72
  });
72
73
  const lastLoginMethod = useCreation(() => {
73
74
  try {
74
- return localStorage.getItem(GA_LAST_LOGIN_METHOD);
75
+ return localStorage.getItem(LAST_USED_LOGIN_METHOD);
75
76
  } catch (error) {
76
77
  return '';
77
78
  }
@@ -1,7 +1,7 @@
1
1
  import { useBrowser } from '@arcblock/react-hooks';
2
2
  import { useCreation, useRequest } from 'ahooks';
3
3
  import isNil from 'lodash/isNil';
4
- import { LOGIN_PROVIDER } from '@arcblock/ux/lib/Util/constant';
4
+ import { LOGIN_PROVIDER, WALLET_LOGIN_METHOD } from '@arcblock/ux/lib/Util/constant';
5
5
  import { getBlockletData, getFederatedEnabled, getMaster } from '@arcblock/ux/lib/Util/federated';
6
6
  import { useState } from 'react';
7
7
 
@@ -102,8 +102,11 @@ export default function useProviderList({
102
102
  .sort((a, b) => {
103
103
  // 优先处理 lastLoginMethod:匹配的项目排在最前面
104
104
  if (lastLoginMethod) {
105
- const aIsLastMethod = a.provider === lastLoginMethod;
106
- const bIsLastMethod = b.provider === lastLoginMethod;
105
+ // 检查是否匹配,wallet 的细分类型需要特殊处理
106
+ const walletMethods = Object.values(WALLET_LOGIN_METHOD);
107
+ const isWalletMethod = walletMethods.includes(lastLoginMethod);
108
+ const aIsLastMethod = isWalletMethod ? a.provider === LOGIN_PROVIDER.WALLET : a.provider === lastLoginMethod;
109
+ const bIsLastMethod = isWalletMethod ? b.provider === LOGIN_PROVIDER.WALLET : b.provider === lastLoginMethod;
107
110
  if (aIsLastMethod && !bIsLastMethod) {
108
111
  return -1;
109
112
  }
@@ -15,6 +15,7 @@ export default function EmailListItem({ ...rest }) {
15
15
  plugin.state.reset();
16
16
  plugin.state.status = 'creating';
17
17
  connectState.chooseMethod = LOGIN_PROVIDER.EMAIL;
18
+ connectState.walletMethod = ''; // 清除 wallet 登录方式,防止状态污染
18
19
  setSelectedPlugin(plugin);
19
20
  });
20
21
 
@@ -8,6 +8,7 @@ import VerificationCode from '@arcblock/ux/lib/VerificationCode';
8
8
  import { useEffect } from 'react';
9
9
  import noop from 'lodash/noop';
10
10
  import ProviderIcon from '@arcblock/ux/lib/DIDConnect/provider-icon';
11
+ import { LOGIN_PROVIDER, LAST_USED_LOGIN_METHOD } from '@arcblock/ux/lib/Util/constant';
11
12
 
12
13
  import BackButton from '../../components/back-button';
13
14
  import ActionButton from '../../components/action-button';
@@ -108,6 +109,8 @@ export default function EmailPlaceholder({
108
109
  sourceAppPid: connectState.sourceAppPid,
109
110
  });
110
111
  debug('Email login succeed (use code)', { loginResult });
112
+ // 登录成功后记录最后使用的登录方式(用于显示 Last Used 标签)
113
+ localStorage.setItem(LAST_USED_LOGIN_METHOD, LOGIN_PROVIDER.EMAIL);
111
114
  await onSuccess(
112
115
  {
113
116
  ...loginResult,
@@ -135,6 +138,8 @@ export default function EmailPlaceholder({
135
138
  magicToken: state.magicToken,
136
139
  });
137
140
  debug('Email login succeed (use magic link)', { loginResult });
141
+ // 登录成功后记录最后使用的登录方式(用于显示 Last Used 标签)
142
+ localStorage.setItem(LAST_USED_LOGIN_METHOD, LOGIN_PROVIDER.EMAIL);
138
143
  await onSuccess(
139
144
  {
140
145
  ...loginResult,
@@ -172,6 +177,8 @@ export default function EmailPlaceholder({
172
177
  if (data.verified) {
173
178
  state.status = 'succeed';
174
179
  reset();
180
+ // 登录成功后记录最后使用的登录方式(用于显示 Last Used 标签)
181
+ localStorage.setItem(LAST_USED_LOGIN_METHOD, LOGIN_PROVIDER.EMAIL);
175
182
  await onSuccess({ encrypted: false }, (val) => val);
176
183
  }
177
184
  } catch (error) {