@rango-dev/widget-embedded 0.46.2-next.2 → 0.46.2-next.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rango-dev/widget-embedded",
3
- "version": "0.46.2-next.2",
3
+ "version": "0.46.2-next.3",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "source": "./src/index.ts",
@@ -25,15 +25,15 @@
25
25
  "@lingui/core": "4.2.1",
26
26
  "@lingui/react": "4.2.1",
27
27
  "@rango-dev/logging-core": "^0.10.1-next.0",
28
- "@rango-dev/provider-all": "^0.49.1-next.2",
28
+ "@rango-dev/provider-all": "^0.49.1-next.3",
29
29
  "@rango-dev/queue-manager-core": "^0.31.1-next.0",
30
- "@rango-dev/queue-manager-rango-preset": "^0.48.2-next.2",
30
+ "@rango-dev/queue-manager-rango-preset": "^0.48.2-next.3",
31
31
  "@rango-dev/queue-manager-react": "^0.31.1-next.0",
32
32
  "@rango-dev/signer-solana": "^0.42.1-next.0",
33
- "@rango-dev/ui": "^0.49.1-next.2",
33
+ "@rango-dev/ui": "^0.49.1-next.3",
34
34
  "@rango-dev/wallets-core": "^0.46.1-next.2",
35
- "@rango-dev/wallets-react": "^0.33.1-next.2",
36
- "@rango-dev/wallets-shared": "^0.47.1-next.2",
35
+ "@rango-dev/wallets-react": "^0.33.1-next.3",
36
+ "@rango-dev/wallets-shared": "^0.47.1-next.3",
37
37
  "bignumber.js": "^9.1.1",
38
38
  "copy-to-clipboard": "^3.3.3",
39
39
  "dayjs": "^1.11.7",
@@ -1,5 +1,6 @@
1
1
  import type { SwapDetailsProps } from './SwapDetails.types';
2
2
  import type { ModalState } from '../SwapDetailsModal';
3
+ import type { SwitchNetworkModalState } from '../SwapDetailsModal/SwapDetailsModal.types';
3
4
 
4
5
  import { i18n } from '@lingui/core';
5
6
  import {
@@ -71,6 +72,8 @@ import {
71
72
  titleStepsStyles,
72
73
  } from './SwapDetails.styles';
73
74
 
75
+ const SUCCESS_SWITCH_NETWORK_MODAL_CLOSE_DELAY = 3000;
76
+
74
77
  export function SwapDetails(props: SwapDetailsProps) {
75
78
  const { swap, requestId, onDelete, onCancel } = props;
76
79
  const { canSwitchNetworkTo, connect, getWalletInfo } = useWallets();
@@ -82,10 +85,14 @@ export function SwapDetails(props: SwapDetailsProps) {
82
85
  const containerRef = useRef<HTMLDivElement | null>(null);
83
86
  const [isModalOpen, setIsModalOpen] = useState(false);
84
87
  const [modalState, setModalState] = useState<ModalState>(null);
88
+ const [switchNetworkModalState, setSwitchNetworkModalState] =
89
+ useState<SwitchNetworkModalState | null>(null);
85
90
  const [showCompletedModal, setShowCompletedModal] = useState<
86
91
  'success' | 'failed' | null
87
92
  >(null);
88
- const showSwitchNetworkRef = useRef(false);
93
+
94
+ const modalStateRef = useRef(modalState);
95
+ const switchNetworkModalStateRef = useRef(switchNetworkModalState);
89
96
 
90
97
  const getNotifications = useNotificationStore.use.getNotifications();
91
98
  const removeNotification = useNotificationStore.use.removeNotification();
@@ -102,42 +109,27 @@ export function SwapDetails(props: SwapDetailsProps) {
102
109
  setIsModalOpen(false);
103
110
  };
104
111
 
105
- useEffect(() => {
106
- const existNotification = notifications.find(
107
- (n) => n.requestId === swap.requestId
108
- );
109
- if (existNotification) {
110
- if (swap.status === 'success' || swap.status === 'failed') {
111
- setShowCompletedModal(swap.status);
112
- removeNotification(swap.requestId);
113
- handleCloseModal();
114
- } else if (showCompletedModal) {
115
- setShowCompletedModal(null);
116
- }
117
- }
118
- }, [swap.status, swap.requestId]);
119
-
120
- useEffect(() => {
121
- if (showSwitchNetwork) {
122
- handleChangeModalState(PendingSwapNetworkStatus.WaitingForNetworkChange);
123
- } else if (
124
- currentStepNetworkStatus ===
125
- PendingSwapNetworkStatus.WaitingForConnectingWallet
126
- ) {
127
- handleChangeModalState(
128
- PendingSwapNetworkStatus.WaitingForConnectingWallet
129
- );
130
- } else if (
131
- currentStepNetworkStatus === PendingSwapNetworkStatus.NetworkChanged
132
- ) {
133
- handleChangeModalState(PendingSwapNetworkStatus.NetworkChanged);
134
- }
135
-
136
- if (!showSwitchNetwork && showSwitchNetworkRef.current) {
137
- handleCloseModal();
138
- }
139
- showSwitchNetworkRef.current = showSwitchNetwork;
140
- }, [currentStepNetworkStatus]);
112
+ const handleShowSwitchNetworkLoading = () => {
113
+ setSwitchNetworkModalState({
114
+ type: 'loading',
115
+ title: i18n.t('Change Network'),
116
+ description: `We’re switching the connected network to ${currentStepNamespace?.network}. Please check your wallet.`,
117
+ });
118
+ };
119
+ const handleShowSwitchNetworkSucceeded = () => {
120
+ setSwitchNetworkModalState({
121
+ type: 'success',
122
+ title: i18n.t('Network Changed'),
123
+ description: 'The network has been successfully changed.',
124
+ });
125
+ };
126
+ const handleShowSwitchNetworkFailed = (error?: Error) => {
127
+ setSwitchNetworkModalState({
128
+ type: 'error',
129
+ title: i18n.t('Network Switch Failed'),
130
+ description: error?.message || stepMessage.detailedMessage.content,
131
+ });
132
+ };
141
133
 
142
134
  const lastConvertedTokenInFailedSwap =
143
135
  getLastConvertedTokenInFailedSwap(swap);
@@ -152,34 +144,60 @@ export function SwapDetails(props: SwapDetailsProps) {
152
144
  const swapDate = getSwapDate(swap);
153
145
  const shouldRetry = shouldRetrySwap(swap);
154
146
 
155
- const isMobileWallet = (walletType: string): boolean =>
147
+ const checkIsMobileWallet = (walletType: string): boolean =>
156
148
  !!getWalletInfo(walletType)?.mobileWallet;
157
149
 
158
- const showSwitchNetwork =
159
- currentStepNetworkStatus ===
160
- PendingSwapNetworkStatus.WaitingForNetworkChange &&
161
- !!currentStepNamespace &&
150
+ const stepIsBlockedForSwitchNetwork =
151
+ !!currentStepNetworkStatus &&
152
+ [
153
+ PendingSwapNetworkStatus.WaitingForNetworkChange,
154
+ PendingSwapNetworkStatus.NetworkChangeFailed,
155
+ ].includes(currentStepNetworkStatus);
156
+ const isMobileWallet =
162
157
  !!currentStepWallet?.walletType &&
163
- (isMobileWallet(currentStepWallet.walletType) ||
164
- canSwitchNetworkTo(
165
- currentStepWallet.walletType,
166
- currentStepNamespace.network,
167
- currentStepNamespace
168
- ));
169
-
170
- const switchNetwork = showSwitchNetwork
171
- ? connect.bind(null, currentStepWallet.walletType, [
158
+ checkIsMobileWallet(currentStepWallet.walletType);
159
+ const canSwitchNetworkToRequiredNetwork =
160
+ !!currentStepWallet &&
161
+ !!currentStepNamespace &&
162
+ canSwitchNetworkTo(
163
+ currentStepWallet.walletType,
164
+ currentStepNamespace.network,
165
+ currentStepNamespace
166
+ );
167
+
168
+ const switchNetworkIsAvailable =
169
+ !!currentStepNamespace &&
170
+ stepIsBlockedForSwitchNetwork &&
171
+ (isMobileWallet || canSwitchNetworkToRequiredNetwork);
172
+
173
+ const handleSwitchNetwork = () => {
174
+ if (switchNetworkIsAvailable) {
175
+ handleShowSwitchNetworkLoading();
176
+ connect(currentStepWallet.walletType, [
172
177
  {
173
178
  namespace: currentStepNamespace.namespace,
174
179
  network: currentStepNamespace.network,
175
180
  },
176
181
  ])
177
- : undefined;
182
+ .then(() => {
183
+ handleShowSwitchNetworkSucceeded();
184
+ })
185
+ .catch((error: unknown) => {
186
+ handleShowSwitchNetworkFailed(error as Error);
187
+ });
188
+ }
189
+ };
190
+
191
+ const handleSwitchNetworkClick = () => {
192
+ handleChangeModalState('switchNetwork');
193
+ handleSwitchNetwork();
194
+ };
178
195
 
179
196
  const stepMessage = getSwapMessages(swap, currentStep, getWalletInfo);
180
197
  const steps = getSteps({
181
198
  swap,
182
- switchNetwork,
199
+ switchNetworkIsAvailable,
200
+ handleSwitchNetworkClick,
183
201
  showNetworkModal: currentStepNetworkStatus,
184
202
  setNetworkModal: handleChangeModalState,
185
203
  message: stepMessage,
@@ -276,6 +294,83 @@ export function SwapDetails(props: SwapDetailsProps) {
276
294
  </ErrorMessages>
277
295
  );
278
296
 
297
+ useEffect(() => {
298
+ const existNotification = notifications.find(
299
+ (n) => n.requestId === swap.requestId
300
+ );
301
+ if (existNotification) {
302
+ if (swap.status === 'success' || swap.status === 'failed') {
303
+ setShowCompletedModal(swap.status);
304
+ removeNotification(swap.requestId);
305
+ handleCloseModal();
306
+ } else if (showCompletedModal) {
307
+ setShowCompletedModal(null);
308
+ }
309
+ }
310
+ }, [swap.status, swap.requestId]);
311
+
312
+ useEffect(() => {
313
+ if (switchNetworkIsAvailable) {
314
+ handleChangeModalState('switchNetwork');
315
+ if (
316
+ currentStepNetworkStatus ===
317
+ PendingSwapNetworkStatus.WaitingForNetworkChange
318
+ ) {
319
+ handleShowSwitchNetworkLoading();
320
+ return;
321
+ }
322
+ if (
323
+ currentStepNetworkStatus ===
324
+ PendingSwapNetworkStatus.NetworkChangeFailed
325
+ ) {
326
+ handleShowSwitchNetworkFailed();
327
+ return;
328
+ }
329
+ return;
330
+ }
331
+
332
+ if (
333
+ currentStepNetworkStatus ===
334
+ PendingSwapNetworkStatus.WaitingForConnectingWallet
335
+ ) {
336
+ handleChangeModalState('connectWallet');
337
+ return;
338
+ }
339
+
340
+ if (currentStepNetworkStatus === PendingSwapNetworkStatus.NetworkChanged) {
341
+ handleChangeModalState('switchNetwork');
342
+ handleShowSwitchNetworkSucceeded();
343
+ return;
344
+ }
345
+
346
+ if (modalState && ['connectWallet', 'switchNetwork'].includes(modalState)) {
347
+ handleCloseModal();
348
+ }
349
+ }, [currentStepNetworkStatus]);
350
+
351
+ useEffect(() => {
352
+ modalStateRef.current = modalState;
353
+ switchNetworkModalStateRef.current = switchNetworkModalState;
354
+
355
+ // Close switch network success modal with a delay
356
+ if (
357
+ modalState === 'switchNetwork' &&
358
+ switchNetworkModalState?.type === 'success'
359
+ ) {
360
+ const timeout = setTimeout(() => {
361
+ if (
362
+ modalStateRef.current === 'switchNetwork' &&
363
+ switchNetworkModalStateRef.current?.type === 'success'
364
+ ) {
365
+ handleCloseModal();
366
+ }
367
+ }, SUCCESS_SWITCH_NETWORK_MODAL_CLOSE_DELAY);
368
+
369
+ return () => clearTimeout(timeout);
370
+ }
371
+ return;
372
+ }, [modalState, switchNetworkModalState]);
373
+
279
374
  return (
280
375
  <Layout
281
376
  header={{
@@ -419,11 +514,13 @@ export function SwapDetails(props: SwapDetailsProps) {
419
514
  <SwapDetailsModal
420
515
  isOpen={isModalOpen}
421
516
  state={modalState}
517
+ switchNetworkModalState={switchNetworkModalState}
422
518
  onClose={handleCloseModal}
423
519
  onCancel={onCancel}
424
520
  onDelete={onDelete}
425
521
  message={stepMessage.detailedMessage.content}
426
522
  swap={swap}
523
+ handleSwitchNetwork={handleSwitchNetworkClick}
427
524
  />
428
525
  <SwapDetailsCompleteModal
429
526
  open={!!showCompletedModal}
@@ -6,8 +6,14 @@ import { PendingSwapNetworkStatus } from 'rango-types';
6
6
  import React from 'react';
7
7
 
8
8
  export function WarningAlert(props: WaningAlertsProps) {
9
- const { switchNetwork, setNetworkModal, message, showNetworkModal } = props;
10
- if (!!switchNetwork) {
9
+ const {
10
+ switchNetworkIsAvailable,
11
+ handleSwitchNetworkClick,
12
+ setNetworkModal,
13
+ message,
14
+ showNetworkModal,
15
+ } = props;
16
+ if (!!switchNetworkIsAvailable) {
11
17
  return (
12
18
  <Alert
13
19
  type="warning"
@@ -19,10 +25,8 @@ export function WarningAlert(props: WaningAlertsProps) {
19
25
  size="xxsmall"
20
26
  type="warning"
21
27
  onClick={() => {
22
- setNetworkModal(PendingSwapNetworkStatus.WaitingForNetworkChange);
23
- switchNetwork().catch((e) => {
24
- console.log(e);
25
- });
28
+ setNetworkModal('switchNetwork');
29
+ handleSwitchNetworkClick();
26
30
  }}>
27
31
  {i18n.t('Change')}
28
32
  </Button>
@@ -44,9 +48,7 @@ export function WarningAlert(props: WaningAlertsProps) {
44
48
  size="xxsmall"
45
49
  type="warning"
46
50
  onClick={() => {
47
- setNetworkModal(
48
- PendingSwapNetworkStatus.WaitingForConnectingWallet
49
- );
51
+ setNetworkModal('connectWallet');
50
52
  }}>
51
53
  {i18n.t('Connect')}
52
54
  </Button>
@@ -12,7 +12,8 @@ import { WarningAlert } from './SwapDetailsAlerts.Warning';
12
12
 
13
13
  export function SwapDetailsAlerts(props: SwapAlertsProps) {
14
14
  const {
15
- switchNetwork,
15
+ switchNetworkIsAvailable,
16
+ handleSwitchNetworkClick,
16
17
  showNetworkModal,
17
18
  setNetworkModal,
18
19
  message,
@@ -75,7 +76,8 @@ export function SwapDetailsAlerts(props: SwapAlertsProps) {
75
76
  )}
76
77
  {step.status !== 'failed' && hasWarning && (
77
78
  <WarningAlert
78
- switchNetwork={switchNetwork}
79
+ switchNetworkIsAvailable={switchNetworkIsAvailable}
80
+ handleSwitchNetworkClick={handleSwitchNetworkClick}
79
81
  showNetworkModal={showNetworkModal}
80
82
  setNetworkModal={setNetworkModal}
81
83
  message={message}
@@ -1,6 +1,5 @@
1
1
  import type { getSwapMessages } from '../../utils/swap';
2
2
  import type { ModalState } from '../SwapDetailsModal';
3
- import type { ConnectResult } from '@rango-dev/wallets-react';
4
3
  import type { SwapperMeta } from 'rango-sdk';
5
4
  import type {
6
5
  BlockchainMeta,
@@ -15,7 +14,8 @@ export interface SwapAlertsProps extends WaningAlertsProps {
15
14
  }
16
15
 
17
16
  export interface WaningAlertsProps extends FailedAlertsProps {
18
- switchNetwork: (() => Promise<ConnectResult[]>) | undefined;
17
+ switchNetworkIsAvailable: boolean;
18
+ handleSwitchNetworkClick: () => void;
19
19
  showNetworkModal: PendingSwapNetworkStatus | null | undefined;
20
20
  setNetworkModal: (network: ModalState) => void;
21
21
  }
@@ -1,17 +1,31 @@
1
1
  import type { NetworkStateContentProps } from './SwapDetailsModal.types';
2
2
 
3
3
  import { i18n } from '@lingui/core';
4
- import { MessageBox } from '@rango-dev/ui';
4
+ import { Button, Divider, MessageBox } from '@rango-dev/ui';
5
5
  import React from 'react';
6
6
 
7
7
  export const NetworkStateContent = (props: NetworkStateContentProps) => {
8
- const { status, message } = props;
8
+ const { switchNetworkModalState, handleSwitchNetwork } = props;
9
9
 
10
- const type = status === 'waitingForNetworkChange' ? 'loading' : 'success';
11
- const title =
12
- status === 'waitingForNetworkChange'
13
- ? i18n.t('Change Network')
14
- : i18n.t('Network Changed');
15
-
16
- return <MessageBox type={type} title={title} description={message} />;
10
+ return (
11
+ <>
12
+ <MessageBox
13
+ type={switchNetworkModalState.type}
14
+ title={switchNetworkModalState.title}
15
+ description={switchNetworkModalState.description}
16
+ />
17
+ {switchNetworkModalState.type === 'error' && (
18
+ <>
19
+ <Divider size="30" />
20
+ <Button
21
+ id="widget-switch-network-try-again"
22
+ type="primary"
23
+ size="large"
24
+ onClick={handleSwitchNetwork}>
25
+ {i18n.t('Try Again')}
26
+ </Button>
27
+ </>
28
+ )}
29
+ </>
30
+ );
17
31
  };
@@ -11,18 +11,32 @@ import { NetworkStateContent } from './SwapDetailsModal.NetworkState';
11
11
  import { WalletStateContent } from './SwapDetailsModal.WalletState';
12
12
 
13
13
  export function SwapDetailsModal(props: ModalPropTypes) {
14
- const { isOpen, state, onClose, onDelete, onCancel, swap, message } = props;
14
+ const {
15
+ isOpen,
16
+ state,
17
+ switchNetworkModalState,
18
+ onClose,
19
+ onDelete,
20
+ onCancel,
21
+ swap,
22
+ message,
23
+ handleSwitchNetwork,
24
+ } = props;
15
25
 
16
26
  return (
17
27
  <WatermarkedModal
18
28
  open={isOpen}
19
29
  onClose={onClose}
20
30
  container={getContainer()}>
21
- {state === 'waitingForConnectingWallet' && (
31
+ {state === 'connectWallet' && (
22
32
  <WalletStateContent swap={swap} message={message} onClose={onClose} />
23
33
  )}
24
- {(state === 'waitingForNetworkChange' || state === 'networkChanged') && (
25
- <NetworkStateContent message={message} status={state} />
34
+ {state === 'switchNetwork' && switchNetworkModalState && (
35
+ <NetworkStateContent
36
+ message={message}
37
+ switchNetworkModalState={switchNetworkModalState}
38
+ handleSwitchNetwork={handleSwitchNetwork}
39
+ />
26
40
  )}
27
41
  {state === 'delete' && (
28
42
  <DeleteContent
@@ -1,20 +1,29 @@
1
1
  import type { TargetNamespace } from '@rango-dev/queue-manager-rango-preset';
2
2
  import type { LegacyWalletType } from '@rango-dev/wallets-core/legacy';
3
- import type { PendingSwap, PendingSwapNetworkStatus } from 'rango-types';
3
+ import type { PendingSwap } from 'rango-types';
4
4
 
5
5
  export type ModalState =
6
- | Exclude<PendingSwapNetworkStatus, PendingSwapNetworkStatus.WaitingForQueue>
6
+ | 'connectWallet'
7
+ | 'switchNetwork'
7
8
  | 'delete'
8
9
  | 'cancel'
9
10
  | null;
11
+
12
+ export type SwitchNetworkModalState = {
13
+ type: 'success' | 'loading' | 'error';
14
+ title: string;
15
+ description: string;
16
+ };
10
17
  export interface ModalPropTypes {
11
18
  isOpen: boolean;
12
19
  onClose: () => void;
13
20
  onCancel: () => void;
14
21
  onDelete: () => void;
15
22
  state: ModalState;
23
+ switchNetworkModalState: SwitchNetworkModalState | null;
16
24
  swap: PendingSwap;
17
25
  message: string;
26
+ handleSwitchNetwork: () => void;
18
27
  }
19
28
 
20
29
  export interface CompleteModalPropTypes {
@@ -46,7 +55,8 @@ export interface WalletStateContentProps {
46
55
 
47
56
  export interface NetworkStateContentProps {
48
57
  message: string;
49
- status: 'networkChanged' | 'waitingForNetworkChange';
58
+ switchNetworkModalState: SwitchNetworkModalState;
59
+ handleSwitchNetwork: () => void;
50
60
  }
51
61
 
52
62
  export interface InstallWalletContentProps {
package/src/utils/swap.ts CHANGED
@@ -716,6 +716,13 @@ export function getSwapMessages(
716
716
  case PendingSwapNetworkStatus.WaitingForNetworkChange:
717
717
  message = message || i18n.t('Waiting for changing wallet network');
718
718
  break;
719
+ case PendingSwapNetworkStatus.NetworkChangeFailed:
720
+ message =
721
+ message ||
722
+ i18n.t(
723
+ 'The network switch could not be completed. Please try again, or switch the network manually in your wallet.'
724
+ );
725
+ break;
719
726
  default:
720
727
  message = message || '';
721
728
  break;