@getpara/react-sdk-lite 2.10.0 → 2.12.0

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.
Files changed (55) hide show
  1. package/dist/modal/ParaModal.js +14 -1
  2. package/dist/modal/components/Account/Account.js +114 -22
  3. package/dist/modal/components/Account/AccountMonitorTx.d.ts +1 -0
  4. package/dist/modal/components/Account/AccountMonitorTx.js +256 -0
  5. package/dist/modal/components/Account/AccountSend/AccountSendAsset.js +2 -2
  6. package/dist/modal/components/Account/AccountSend/AccountSendForm.js +68 -10
  7. package/dist/modal/components/Account/AccountSend/context.d.ts +2 -0
  8. package/dist/modal/components/Account/AccountSend/context.js +50 -110
  9. package/dist/modal/components/Account/AccountWallet.js +1 -6
  10. package/dist/modal/components/Account/AccountWalletSelect.js +5 -12
  11. package/dist/modal/components/AddFunds/AddFundsContext.js +70 -25
  12. package/dist/modal/components/AddFunds/AddFundsReceive.js +1 -1
  13. package/dist/modal/components/AddFunds/AddFundsSettings.js +134 -29
  14. package/dist/modal/components/AuthInput/hooks/useDropdownPosition.d.ts +1 -1
  15. package/dist/modal/components/AuthInput/hooks/useDropdownPosition.js +25 -17
  16. package/dist/modal/components/AuthOptions/AuthOptions.js +1 -1
  17. package/dist/modal/components/Body/Body.js +4 -0
  18. package/dist/modal/components/Controls/ChainSelect.js +2 -3
  19. package/dist/modal/components/ErrorBoundary.d.ts +20 -0
  20. package/dist/modal/components/ErrorBoundary.js +27 -0
  21. package/dist/modal/components/ExternalWalletStep/ExternalWalletStep.js +1 -1
  22. package/dist/modal/components/OnRampComponents/OnRampProviderButton.js +3 -8
  23. package/dist/modal/components/WalletSelectOld/WalletSelectOld.js +6 -13
  24. package/dist/modal/components/common.d.ts +10 -1
  25. package/dist/modal/components/common.js +44 -11
  26. package/dist/modal/hooks/index.d.ts +1 -0
  27. package/dist/modal/hooks/index.js +1 -0
  28. package/dist/modal/hooks/useFarcasterLogin.js +1 -1
  29. package/dist/modal/hooks/useSendMutations.d.ts +51 -0
  30. package/dist/modal/hooks/useSendMutations.js +170 -0
  31. package/dist/modal/hooks/useTelegramLogin.js +1 -1
  32. package/dist/modal/hooks/useTransactionMonitoring.d.ts +1 -0
  33. package/dist/modal/hooks/useTransactionMonitoring.js +175 -0
  34. package/dist/modal/index.d.ts +1 -1
  35. package/dist/modal/index.js +1 -1
  36. package/dist/modal/stores/index.d.ts +1 -0
  37. package/dist/modal/stores/index.js +1 -0
  38. package/dist/modal/stores/modal/actions.js +0 -1
  39. package/dist/modal/stores/modal/useModalSessionStore.d.ts +28 -0
  40. package/dist/modal/stores/modal/useModalSessionStore.js +26 -0
  41. package/dist/modal/stores/modal/useModalStore.d.ts +2 -3
  42. package/dist/modal/stores/modal/useModalStore.js +2 -2
  43. package/dist/modal/utils/onramps.d.ts +61 -0
  44. package/dist/modal/utils/onramps.js +112 -0
  45. package/dist/modal/utils/steps.d.ts +4 -2
  46. package/dist/modal/utils/steps.js +6 -2
  47. package/dist/provider/hooks/mutations/utils.js +1 -1
  48. package/dist/provider/hooks/utils/useAutoSessionKeepAlive.js +1 -1
  49. package/dist/provider/hooks/utils/useEventListeners.js +2 -2
  50. package/dist/provider/hooks/utils/useModal.d.ts +2 -1
  51. package/dist/provider/hooks/utils/useModal.js +10 -3
  52. package/dist/provider/providers/ExternalWalletProvider.js +2 -2
  53. package/package.json +9 -8
  54. package/dist/modal/utils/validateOnRampConfig.d.ts +0 -5
  55. package/dist/modal/utils/validateOnRampConfig.js +0 -32
@@ -23,11 +23,13 @@ import { useStore } from "../provider/stores/useStore.js";
23
23
  import parsePhoneNumberFromString from "libphonenumber-js";
24
24
  import { useAuthActions } from "../provider/providers/AuthProvider.js";
25
25
  import { validateInput } from "./utils/authInputHelpers.js";
26
+ import { useTransactionMonitoring } from "./hooks/useTransactionMonitoring.js";
26
27
  defineCustomElements();
27
28
  const ParaModal = forwardRef((props, ref) => {
28
29
  const storedModalConfig = useStore((state) => state.modalConfig);
29
30
  const refs = useStore((state) => state.refs);
30
31
  const modalContentRef = useRef(null);
32
+ const modalRef = useRef(null);
31
33
  const modalRefs = useModalStore((state) => state.refs);
32
34
  const flow = useModalStore((state) => state.flow);
33
35
  const currentStep = useModalStore((state) => state.step);
@@ -110,7 +112,7 @@ const ParaModal = forwardRef((props, ref) => {
110
112
  onClose,
111
113
  defaultAuthIdentifier
112
114
  }), rest),
113
- reactSdkVersion: "2.10.0"
115
+ reactSdkVersion: "2.12.0"
114
116
  });
115
117
  } catch (e) {
116
118
  }
@@ -187,6 +189,7 @@ const ParaModal = forwardRef((props, ref) => {
187
189
  break;
188
190
  }
189
191
  });
192
+ useTransactionMonitoring();
190
193
  useEffect(() => {
191
194
  if (isReady && isOpen && !isAccountLoading && !isInitialized.current) {
192
195
  initModal(isOpen);
@@ -271,6 +274,15 @@ const ParaModal = forwardRef((props, ref) => {
271
274
  setStep(ModalStep.LOGIN_DONE);
272
275
  }
273
276
  });
277
+ useEffect(() => {
278
+ var _a2;
279
+ if ((_a2 = modalRef.current) == null ? void 0 : _a2.shadowRoot) {
280
+ const container = modalRef.current.shadowRoot.getElementById("modal-container");
281
+ if (container && modalRefs.modalContainer) {
282
+ modalRefs.modalContainer.current = container;
283
+ }
284
+ }
285
+ }, [isModalMounted]);
274
286
  if (!para) {
275
287
  console.error("A Para instance is required.");
276
288
  return null;
@@ -295,6 +307,7 @@ const ParaModal = forwardRef((props, ref) => {
295
307
  return /* @__PURE__ */ jsx(
296
308
  StyledAuthModal,
297
309
  {
310
+ ref: modalRef,
298
311
  enterTransitionDuration: DEFAULTS.ANIMATION_DURATION,
299
312
  exitTransitionDuration: DEFAULTS.ANIMATION_DURATION,
300
313
  open: isOpen,
@@ -2,10 +2,10 @@
2
2
  import "../../../chunk-MMUBH76A.js";
3
3
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
4
  import { safeStyled } from "@getpara/react-common";
5
- import { InnerStepContainer, StepContainer } from "../common.js";
5
+ import { ExplorerLink, InnerStepContainer, StepContainer } from "../common.js";
6
6
  import { CpslButton, CpslIcon, CpslSpinner, CpslText, CpslTileButton } from "@getpara/react-components";
7
- import { OnRampStep, useModalStore } from "../../stores/index.js";
8
- import { useEffect } from "react";
7
+ import { OnRampStep, useModalStore, useModalSessionStore } from "../../stores/index.js";
8
+ import { useEffect, useMemo } from "react";
9
9
  import { ModalStep } from "../../utils/steps.js";
10
10
  import { useInternalClient } from "../../../provider/hooks/utils/useInternalClient.js";
11
11
  import { useAccount, useWalletState } from "../../../provider/index.js";
@@ -13,17 +13,101 @@ import { EnabledFlow } from "@getpara/web-sdk";
13
13
  import { useAccountLinking } from "../../../provider/providers/AccountLinkProvider.js";
14
14
  import { useAssets } from "../../../provider/providers/AssetsProvider.js";
15
15
  import { AccountHeader } from "./AccountHeader.js";
16
+ import { AnimatePresence, motion } from "framer-motion";
16
17
  const Account = () => {
17
18
  const onRampConfig = useModalStore((state) => state.onRampConfig);
18
19
  const setStep = useModalStore((state) => state.setStep);
19
20
  const setGuestAddFundsTab = useModalStore((state) => state.setGuestAddFundsTab);
20
21
  const setOnRampStep = useModalStore((state) => state.setOnRampStep);
21
- const sendTx = useModalStore((state) => state.sendTx);
22
+ const sendTx = useModalSessionStore((state) => state.sendTx);
23
+ const sendTxStatus = useModalSessionStore((state) => {
24
+ var _a, _b, _c;
25
+ return (_c = (_b = (_a = state.sendTx) == null ? void 0 : _a.result) == null ? void 0 : _b.status) == null ? void 0 : _c.status;
26
+ });
27
+ const sendTxResult = useModalSessionStore((state) => {
28
+ var _a;
29
+ return (_a = state.sendTx) == null ? void 0 : _a.result;
30
+ });
22
31
  const para = useInternalClient();
23
32
  const { embedded } = useAccount();
24
33
  const { selectedWallet, setSelectedWallet } = useWalletState();
25
34
  const { isEnabled } = useAccountLinking();
26
35
  const { profileBalance } = useAssets();
36
+ const transactionMonitorContent = useMemo(() => {
37
+ var _a, _b, _c, _d;
38
+ if (!sendTx) return null;
39
+ if ((_b = (_a = sendTx == null ? void 0 : sendTx.result) == null ? void 0 : _a.status) == null ? void 0 : _b.status) {
40
+ const status = sendTx.result.status.status;
41
+ const confirmations = (_c = sendTx.result.status.confirmations) != null ? _c : 0;
42
+ const isPending = status === "PENDING" || status === "CONFIRMED" && confirmations < 1;
43
+ const isConfirmed = status === "CONFIRMED" && confirmations >= 1;
44
+ const isFailed = status === "FAILED";
45
+ let color, text, icon, key;
46
+ switch (true) {
47
+ case isConfirmed:
48
+ color = "var(--cpsl-color-utility-green)";
49
+ text = "Transaction confirmed";
50
+ icon = /* @__PURE__ */ jsx(CpslIcon, { icon: "check", size: "16px", color });
51
+ key = "confirmed";
52
+ break;
53
+ case isFailed:
54
+ color = "var(--cpsl-color-utility-red)";
55
+ text = "Transaction failed";
56
+ icon = /* @__PURE__ */ jsx(CpslIcon, { icon: "alertTriangle", size: "16px", color });
57
+ key = "failed";
58
+ break;
59
+ case isPending:
60
+ default:
61
+ color = "var(--cpsl-color-text-secondary)";
62
+ text = "Transaction in progress";
63
+ icon = /* @__PURE__ */ jsx(CpslSpinner, { size: "16px", barColor: color });
64
+ key = "pending";
65
+ break;
66
+ }
67
+ return /* @__PURE__ */ jsx(
68
+ AnimatedMonitorContainer,
69
+ {
70
+ variants: fadeVariants,
71
+ initial: "enter",
72
+ animate: "center",
73
+ exit: "exit",
74
+ transition: fadeTransition,
75
+ children: /* @__PURE__ */ jsxs(
76
+ AnimatedMonitorButton,
77
+ {
78
+ onClick: () => {
79
+ setStep(ModalStep.ACCOUNT_MONITOR_TX);
80
+ },
81
+ children: [
82
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "4px", color }, children: [
83
+ icon,
84
+ /* @__PURE__ */ jsx("span", { children: text })
85
+ ] }),
86
+ /* @__PURE__ */ jsx(CpslIcon, { icon: "chevronRight", size: "16px" })
87
+ ]
88
+ }
89
+ )
90
+ },
91
+ key
92
+ );
93
+ }
94
+ if ((_d = sendTx == null ? void 0 : sendTx.result) == null ? void 0 : _d.explorerUrl) {
95
+ return /* @__PURE__ */ jsx(
96
+ AnimatedMonitorContainer,
97
+ {
98
+ variants: fadeVariants,
99
+ initial: "enter",
100
+ animate: "center",
101
+ exit: "exit",
102
+ transition: fadeTransition,
103
+ children: /* @__PURE__ */ jsx(ExplorerLink, { href: sendTx.result.explorerUrl, text: "Monitor Transaction" })
104
+ },
105
+ "explorer"
106
+ );
107
+ }
108
+ return null;
109
+ }, [sendTx, sendTxStatus, sendTxResult, setStep]);
110
+ const transactionMonitor = /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: transactionMonitorContent });
27
111
  const isGuestMode = embedded.isConnected && embedded.isGuestMode;
28
112
  const cantBuyAndWithdraw = (para.externalWalletConnectionType === "CONNECTION_ONLY" || para.externalWalletConnectionType === "VERIFICATION") && !para.userId;
29
113
  const isOnRampLoaded = !!onRampConfig;
@@ -90,10 +174,7 @@ const Account = () => {
90
174
  }
91
175
  )
92
176
  ] }),
93
- !!(sendTx == null ? void 0 : sendTx.explorerUrl) && /* @__PURE__ */ jsxs(MonitorLink, { target: "_blank", href: sendTx.explorerUrl, rel: "noopener noreferrer", "data-testid": "para-monitor-tx", children: [
94
- /* @__PURE__ */ jsx("span", { children: "Monitor Transaction" }),
95
- /* @__PURE__ */ jsx(CpslIcon, { icon: "externalLink", size: "16px", style: { marginLeft: "6px" } })
96
- ] }),
177
+ transactionMonitor,
97
178
  /* @__PURE__ */ jsx(ButtonContainer, { children: isOnRampLoaded ? /* @__PURE__ */ jsxs(Fragment, { children: [
98
179
  (onRampConfig.isBuyEnabled || onRampConfig.isReceiveEnabled) && !cantBuyAndWithdraw && /* @__PURE__ */ jsx(OptionButton, { icon: "plusCircle", onClick: handleBuyClick, "data-testid": "para-add-funds-tile", children: /* @__PURE__ */ jsx(CpslText, { variant: "bodyXS", color: "secondary", weight: "medium", children: "Add Funds" }) }),
99
180
  embedded.authType !== "externalWallet" && /* @__PURE__ */ jsx(
@@ -154,24 +235,35 @@ const LowerContainer = safeStyled.div`
154
235
  gap: 16px;
155
236
  width: 100%;
156
237
  `;
157
- const MonitorLink = safeStyled.a`
158
- font-family: var(--cpsl-font-family);
159
- font-size: 14px;
160
- position: relative;
161
- display: flex;
162
- align-items: center;
163
- justify-content: center;
238
+ const fadeVariants = {
239
+ enter: {
240
+ opacity: 0
241
+ },
242
+ center: {
243
+ opacity: 1
244
+ },
245
+ exit: {
246
+ opacity: 0
247
+ }
248
+ };
249
+ const fadeTransition = {
250
+ duration: 0.2
251
+ };
252
+ const AnimatedMonitorContainer = safeStyled(motion.div)`
253
+ width: 100%;
254
+ `;
255
+ const AnimatedMonitorButton = safeStyled.button`
164
256
  width: 100%;
165
257
  background: transparent;
166
258
  border: none;
167
259
  cursor: pointer;
168
- color: var(--cpsl-color-text-primary);
169
- --icon-color: var(--cpsl-color-text-primary);
170
-
171
- &:hover {
172
- color: var(--cpsl-color-text-contrast);
173
- --icon-color: var(--cpsl-color-text-contrast);
174
- }
260
+ display: flex;
261
+ align-items: center;
262
+ justify-content: center;
263
+ gap: 8px;
264
+ color: var(--cpsl-color-text-secondary);
265
+ font-family: var(--cpsl-font-family);
266
+ font-size: 14px;
175
267
  `;
176
268
  export {
177
269
  Account
@@ -0,0 +1 @@
1
+ export declare const AccountMonitorTx: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,256 @@
1
+ "use client";
2
+ import {
3
+ __async
4
+ } from "../../../chunk-MMUBH76A.js";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { useEffect, useMemo, useState } from "react";
7
+ import { useModalStore, useModalSessionStore } from "../../stores/index.js";
8
+ import { ModalStep } from "../../utils/steps.js";
9
+ import { StepContainer, InnerStepContainer, Heading, HeroIcon, SpinnerContainer, ExplorerLink } from "../common.js";
10
+ import { CpslButton, CpslSpinner, CpslText } from "@getpara/react-components";
11
+ import { useInternalClient } from "../../../provider/hooks/utils/useInternalClient.js";
12
+ import { useSendMutations } from "../../hooks/index.js";
13
+ import { useWalletState } from "../../../provider/index.js";
14
+ import { formatAssetQuantity } from "@getpara/shared";
15
+ import { truncateAddress } from "@getpara/web-sdk";
16
+ import { AnimatePresence, motion } from "framer-motion";
17
+ import { safeStyled } from "@getpara/react-common";
18
+ import { ErrorBoundary } from "../ErrorBoundary.js";
19
+ const ErrorFallback = () => {
20
+ var _a;
21
+ const setStep = useModalStore((state) => state.setStep);
22
+ const sendTx = useModalSessionStore((state) => state.sendTx);
23
+ return /* @__PURE__ */ jsxs(StepContainer, { children: [
24
+ /* @__PURE__ */ jsx(HeroIcon, { icon: "alertTriangle" }),
25
+ /* @__PURE__ */ jsxs(InnerStepContainer, { children: [
26
+ /* @__PURE__ */ jsx(Heading, { children: "Something went wrong" }),
27
+ /* @__PURE__ */ jsx(CpslText, { variant: "bodyS", color: "secondary", children: "Unable to display transaction status." }),
28
+ ((_a = sendTx == null ? void 0 : sendTx.result) == null ? void 0 : _a.explorerUrl) && /* @__PURE__ */ jsx(ExplorerLink, { href: sendTx.result.explorerUrl, text: "View on Explorer" })
29
+ ] }),
30
+ /* @__PURE__ */ jsx(
31
+ CpslButton,
32
+ {
33
+ fullWidth: true,
34
+ onClick: () => {
35
+ setStep(ModalStep.ACCOUNT_MAIN);
36
+ },
37
+ children: "Go Back"
38
+ }
39
+ )
40
+ ] });
41
+ };
42
+ const AccountMonitorTx = () => {
43
+ return /* @__PURE__ */ jsx(ErrorBoundary, { fallback: /* @__PURE__ */ jsx(ErrorFallback, {}), children: /* @__PURE__ */ jsx(AccountMonitorTxContent, {}) });
44
+ };
45
+ const AccountMonitorTxContent = () => {
46
+ var _a, _b, _c, _d, _e, _f;
47
+ const sendTx = useModalSessionStore((state) => state.sendTx);
48
+ const setSendTx = useModalSessionStore((state) => state.setSendTx);
49
+ const setStep = useModalStore((state) => state.setStep);
50
+ const para = useInternalClient();
51
+ const { selectedWallet, setSelectedWallet } = useWalletState();
52
+ const [isRetrying, setIsRetrying] = useState(false);
53
+ useEffect(() => {
54
+ if ((sendTx == null ? void 0 : sendTx.walletId) && (selectedWallet == null ? void 0 : selectedWallet.id) !== sendTx.walletId) {
55
+ const wallet = para.wallets[sendTx.walletId];
56
+ if (wallet && wallet.type) {
57
+ setSelectedWallet({ id: sendTx.walletId, type: wallet.type });
58
+ }
59
+ }
60
+ }, [sendTx == null ? void 0 : sendTx.walletId, selectedWallet == null ? void 0 : selectedWallet.id, para.wallets, setSelectedWallet]);
61
+ useEffect(() => {
62
+ var _a2;
63
+ if (!((_a2 = sendTx == null ? void 0 : sendTx.result) == null ? void 0 : _a2.status)) {
64
+ setStep(ModalStep.ACCOUNT_MAIN);
65
+ }
66
+ }, [sendTx, setStep]);
67
+ const { estimateMutateAsync, broadcastMutateAsync } = useSendMutations({
68
+ estimateOnSuccess: () => {
69
+ },
70
+ estimateOnError: () => {
71
+ },
72
+ broadcastOnError: () => {
73
+ }
74
+ });
75
+ const handleRetry = () => __async(void 0, null, function* () {
76
+ var _a2;
77
+ if (!(sendTx == null ? void 0 : sendTx.opts) || !(sendTx == null ? void 0 : sendTx.userId) || !(sendTx == null ? void 0 : sendTx.walletId) || !((_a2 = sendTx == null ? void 0 : sendTx.result) == null ? void 0 : _a2.network)) {
78
+ return;
79
+ }
80
+ setIsRetrying(true);
81
+ try {
82
+ const estimateResult = yield estimateMutateAsync({
83
+ userId: sendTx.userId,
84
+ walletId: sendTx.walletId,
85
+ opts: sendTx.opts
86
+ });
87
+ if (!(estimateResult == null ? void 0 : estimateResult.result)) {
88
+ setIsRetrying(false);
89
+ return;
90
+ }
91
+ if (!(selectedWallet == null ? void 0 : selectedWallet.id) || !(selectedWallet == null ? void 0 : selectedWallet.address) || !(selectedWallet == null ? void 0 : selectedWallet.type)) {
92
+ setIsRetrying(false);
93
+ return;
94
+ }
95
+ const walletAddress = selectedWallet.address;
96
+ const walletType = selectedWallet.type;
97
+ const network = sendTx.result.network;
98
+ yield broadcastMutateAsync({
99
+ userId: sendTx.userId,
100
+ walletId: sendTx.walletId,
101
+ walletAddress,
102
+ walletType,
103
+ txSerialized: estimateResult.result.txSerialized,
104
+ message: estimateResult.result.message,
105
+ evmChainId: network.type === "EVM" ? network.evmChainId : void 0,
106
+ isDevnet: network.type === "SOLANA" ? network.isDevnet : void 0
107
+ });
108
+ } catch (error) {
109
+ console.error("Retry failed:", error);
110
+ } finally {
111
+ setIsRetrying(false);
112
+ }
113
+ });
114
+ const explorerLink = useMemo(() => {
115
+ var _a2;
116
+ if ((_a2 = sendTx == null ? void 0 : sendTx.result) == null ? void 0 : _a2.explorerUrl) {
117
+ return /* @__PURE__ */ jsx(ExplorerLink, { href: sendTx.result.explorerUrl, text: "View Transaction" });
118
+ }
119
+ return null;
120
+ }, [(_a = sendTx == null ? void 0 : sendTx.result) == null ? void 0 : _a.explorerUrl]);
121
+ const content = useMemo(() => {
122
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g, _h;
123
+ if (!sendTx) {
124
+ return null;
125
+ }
126
+ const status = (_b2 = (_a2 = sendTx.result) == null ? void 0 : _a2.status) == null ? void 0 : _b2.status;
127
+ const confirmations = (_e2 = (_d2 = (_c2 = sendTx.result) == null ? void 0 : _c2.status) == null ? void 0 : _d2.confirmations) != null ? _e2 : 0;
128
+ const isPending = status === "PENDING" || status === "CONFIRMED" && confirmations < 1;
129
+ const isConfirmed = status === "CONFIRMED" && confirmations >= 1;
130
+ const isFailed = status === "FAILED";
131
+ switch (true) {
132
+ case isConfirmed:
133
+ return /* @__PURE__ */ jsx(
134
+ AnimatedContainer,
135
+ {
136
+ variants: fadeVariants,
137
+ initial: "enter",
138
+ animate: "center",
139
+ exit: "exit",
140
+ transition: fadeTransition,
141
+ children: /* @__PURE__ */ jsxs(StepContainer, { children: [
142
+ /* @__PURE__ */ jsx(HeroIcon, { icon: "checkCircleFilled" }),
143
+ /* @__PURE__ */ jsxs(InnerStepContainer, { children: [
144
+ /* @__PURE__ */ jsx(Heading, { children: "Success!" }),
145
+ /* @__PURE__ */ jsx(CpslText, { variant: "bodyS", color: "secondary", children: "Your funds have been sent." }),
146
+ explorerLink
147
+ ] }),
148
+ /* @__PURE__ */ jsx(
149
+ CpslButton,
150
+ {
151
+ fullWidth: true,
152
+ onClick: () => {
153
+ setSendTx(null);
154
+ },
155
+ children: "Done"
156
+ }
157
+ )
158
+ ] })
159
+ },
160
+ "confirmed"
161
+ );
162
+ case isFailed:
163
+ return /* @__PURE__ */ jsx(
164
+ AnimatedContainer,
165
+ {
166
+ variants: fadeVariants,
167
+ initial: "enter",
168
+ animate: "center",
169
+ exit: "exit",
170
+ transition: fadeTransition,
171
+ children: /* @__PURE__ */ jsxs(StepContainer, { children: [
172
+ /* @__PURE__ */ jsx(HeroIcon, { icon: "alertTriangle" }),
173
+ /* @__PURE__ */ jsxs(InnerStepContainer, { children: [
174
+ /* @__PURE__ */ jsx(Heading, { children: "Transaction failed" }),
175
+ /* @__PURE__ */ jsx(CpslText, { variant: "bodyS", color: "secondary", children: "Your transaction was not completed." })
176
+ ] }),
177
+ /* @__PURE__ */ jsx(CpslButton, { fullWidth: true, onClick: handleRetry, disabled: isRetrying, children: isRetrying ? "Retrying..." : "Retry" })
178
+ ] })
179
+ },
180
+ "failed"
181
+ );
182
+ case isPending:
183
+ default:
184
+ return /* @__PURE__ */ jsx(
185
+ AnimatedContainer,
186
+ {
187
+ variants: fadeVariants,
188
+ initial: "enter",
189
+ animate: "center",
190
+ exit: "exit",
191
+ transition: fadeTransition,
192
+ children: /* @__PURE__ */ jsxs(
193
+ StepContainer,
194
+ {
195
+ style: {
196
+ fontFamily: "var(--cpsl-font-family)",
197
+ color: "var(--cpsl-color-text-primary)"
198
+ },
199
+ children: [
200
+ /* @__PURE__ */ jsx(SpinnerContainer, { children: /* @__PURE__ */ jsx(CpslSpinner, { size: 100 }) }),
201
+ explorerLink,
202
+ ((_f2 = sendTx.opts) == null ? void 0 : _f2.destinationAddress) && /* @__PURE__ */ jsxs("div", { style: { width: "100%", fontSize: "14px", display: "flex", justifyContent: "space-between" }, children: [
203
+ /* @__PURE__ */ jsx("div", { style: { textAlign: "left" }, children: "To" }),
204
+ /* @__PURE__ */ jsx("div", { style: { textAlign: "right" }, children: truncateAddress(sendTx.opts.destinationAddress, sendTx.opts.type) })
205
+ ] }),
206
+ ((_g = sendTx.opts) == null ? void 0 : _g.tokenSymbol) && ((_h = sendTx.opts) == null ? void 0 : _h.transferAmount) && /* @__PURE__ */ jsxs("div", { style: { width: "100%", fontSize: "14px", display: "flex", justifyContent: "space-between" }, children: [
207
+ /* @__PURE__ */ jsx("div", { style: { textAlign: "left" }, children: "Amount" }),
208
+ /* @__PURE__ */ jsx("div", { style: { textAlign: "right" }, children: formatAssetQuantity({
209
+ quantity: sendTx.opts.transferAmount,
210
+ symbol: sendTx.opts.tokenSymbol
211
+ }) })
212
+ ] })
213
+ ]
214
+ }
215
+ )
216
+ },
217
+ "pending"
218
+ );
219
+ }
220
+ }, [
221
+ sendTx,
222
+ (_c = (_b = sendTx == null ? void 0 : sendTx.result) == null ? void 0 : _b.status) == null ? void 0 : _c.status,
223
+ (_e = (_d = sendTx == null ? void 0 : sendTx.result) == null ? void 0 : _d.status) == null ? void 0 : _e.confirmations,
224
+ explorerLink,
225
+ handleRetry,
226
+ isRetrying,
227
+ setSendTx
228
+ ]);
229
+ if (!((_f = sendTx == null ? void 0 : sendTx.result) == null ? void 0 : _f.status)) {
230
+ return null;
231
+ }
232
+ return /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: content });
233
+ };
234
+ const fadeVariants = {
235
+ enter: {
236
+ opacity: 0
237
+ },
238
+ center: {
239
+ opacity: 1
240
+ },
241
+ exit: {
242
+ opacity: 0
243
+ }
244
+ };
245
+ const fadeTransition = {
246
+ duration: 0.2
247
+ };
248
+ const AnimatedContainer = safeStyled(motion.div)`
249
+ position: relative;
250
+ display: flex;
251
+ flex-direction: column;
252
+ width: 100%;
253
+ `;
254
+ export {
255
+ AccountMonitorTx
256
+ };
@@ -44,7 +44,7 @@ function AccountSendAsset() {
44
44
  return (_b = (_a = profileBalance == null ? void 0 : profileBalance.wallets.find((wallet) => wallet.address === (selectedWallet == null ? void 0 : selectedWallet.address))) == null ? void 0 : _a.assets) != null ? _b : [];
45
45
  }, [profileBalance, selectedWallet == null ? void 0 : selectedWallet.address]);
46
46
  const transformItem = useCallback((item) => {
47
- var _a, _b;
47
+ var _a, _b, _c;
48
48
  const isValued = ((_a = item.value) == null ? void 0 : _a.value) && ((_b = item.value) == null ? void 0 : _b.value) >= 0.01;
49
49
  const quantity = formatAssetQuantity({ quantity: item.quantity, symbol: item.metadata.symbol });
50
50
  return {
@@ -53,7 +53,7 @@ function AccountSendAsset() {
53
53
  AssetNetwork,
54
54
  {
55
55
  assetSrc: item.metadata.logoUrl,
56
- networkSrc: item.networks.length === 1 ? item.networks[0].metadata.logoUrl : void 0,
56
+ networkSrc: item.networks.length === 1 ? (_c = item.networks[0].metadata) == null ? void 0 : _c.logoUrl : void 0,
57
57
  size: 48
58
58
  }
59
59
  ),
@@ -9,14 +9,19 @@ import { useSend } from "./context.js";
9
9
  import { useModalStore } from "../../../stores/index.js";
10
10
  import { ModalStep } from "../../../utils/steps.js";
11
11
  import { useEffect, useMemo, useRef, useState } from "react";
12
+ import { createPortal } from "react-dom";
12
13
  import { useDebounce } from "../../../hooks/useDebounce.js";
13
14
  import { AssetNetwork } from "./AssetNetwork.js";
14
15
  import { useWalletState } from "../../../../provider/index.js";
16
+ import { useInternalClient } from "../../../../provider/hooks/utils/useInternalClient.js";
17
+ import { Environment } from "@getpara/web-sdk";
18
+ import { safeStyled } from "@getpara/react-common";
15
19
  function AccountSendForm() {
16
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
20
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
17
21
  const { selectedWallet } = useWalletState();
18
22
  const setStep = useModalStore((state) => state.setStep);
19
23
  const onRampConfig = useModalStore((state) => state.onRampConfig);
24
+ const currentStep = useModalStore((state) => state.step);
20
25
  const {
21
26
  estimate,
22
27
  broadcast,
@@ -35,11 +40,16 @@ function AccountSendForm() {
35
40
  setIsMax,
36
41
  estimateIsPending,
37
42
  broadcastIsPending,
38
- optionsType
43
+ optionsType,
44
+ simulateFailure,
45
+ setSimulateFailure
39
46
  } = useSend();
47
+ const para = useInternalClient();
48
+ const isDevOrSandbox = ((_a = para.ctx) == null ? void 0 : _a.env) === Environment.DEV || ((_b = para.ctx) == null ? void 0 : _b.env) === Environment.SANDBOX;
49
+ const isSendFormStep = currentStep === ModalStep.ACCOUNT_SEND;
40
50
  const [inputDestinationAddress, setInputDestinationAddress] = useState(destinationAddress);
41
51
  const dbInputDestinationAddress = useDebounce(inputDestinationAddress, 500);
42
- const isTestnet = (_b = (_a = sendMetadata == null ? void 0 : sendMetadata.network) == null ? void 0 : _a.metadata) == null ? void 0 : _b.isTestnet;
52
+ const isTestnet = (_d = (_c = sendMetadata == null ? void 0 : sendMetadata.network) == null ? void 0 : _c.metadata) == null ? void 0 : _d.isTestnet;
43
53
  const shouldUseAmountMode = !assetPrice || !!assetPrice && isTestnet;
44
54
  const [inputMode, setInputMode] = useState(shouldUseAmountMode ? "AMOUNT" : "VALUE");
45
55
  const [inputValue, setInputValue] = useState(
@@ -101,7 +111,7 @@ function AccountSendForm() {
101
111
  estimateIsPending,
102
112
  broadcastIsPending,
103
113
  onRampConfig == null ? void 0 : onRampConfig.isBuyEnabled,
104
- (_d = (_c = sendMetadata == null ? void 0 : sendMetadata.network) == null ? void 0 : _c.metadata) == null ? void 0 : _d.nativeTokenSymbol,
114
+ (_f = (_e = sendMetadata == null ? void 0 : sendMetadata.network) == null ? void 0 : _e.metadata) == null ? void 0 : _f.nativeTokenSymbol,
105
115
  estimate == null ? void 0 : estimate.transferAmount
106
116
  ]);
107
117
  useEffect(() => {
@@ -109,7 +119,7 @@ function AccountSendForm() {
109
119
  const isTestnet2 = (_b2 = (_a2 = sendMetadata == null ? void 0 : sendMetadata.network) == null ? void 0 : _a2.metadata) == null ? void 0 : _b2.isTestnet;
110
120
  const shouldUseAmountMode2 = !assetPrice || !!assetPrice && isTestnet2;
111
121
  setInputMode(shouldUseAmountMode2 ? "AMOUNT" : "VALUE");
112
- }, [assetPrice, (_f = (_e = sendMetadata == null ? void 0 : sendMetadata.network) == null ? void 0 : _e.metadata) == null ? void 0 : _f.isTestnet]);
122
+ }, [assetPrice, (_h = (_g = sendMetadata == null ? void 0 : sendMetadata.network) == null ? void 0 : _g.metadata) == null ? void 0 : _h.isTestnet]);
113
123
  useEffect(() => {
114
124
  if (inputMode === "AMOUNT") {
115
125
  setTransferAmount(Number(dbInputValue));
@@ -195,7 +205,7 @@ function AccountSendForm() {
195
205
  children: [
196
206
  /* @__PURE__ */ jsx(CpslText, { variant: "bodyM", color: "secondary", children: inputMode === "VALUE" ? formatAssetQuantity({
197
207
  quantity: isMax && assetAmountOnNetwork ? assetAmountOnNetwork : transferAmount,
198
- symbol: (_g = sendMetadata.asset.metadata) == null ? void 0 : _g.symbol
208
+ symbol: (_i = sendMetadata.asset.metadata) == null ? void 0 : _i.symbol
199
209
  }) : formatCurrency({
200
210
  value: isMax && assetValueOnNetwork ? assetValueOnNetwork.value : Number(transferValue),
201
211
  currency: "USD"
@@ -238,7 +248,7 @@ function AccountSendForm() {
238
248
  AssetNetwork,
239
249
  {
240
250
  assetSrc: sendMetadata.asset.metadata.logoUrl,
241
- networkSrc: sendMetadata.network.metadata.logoUrl,
251
+ networkSrc: (_k = (_j = sendMetadata.network) == null ? void 0 : _j.metadata) == null ? void 0 : _k.logoUrl,
242
252
  size: 32
243
253
  }
244
254
  ),
@@ -318,7 +328,7 @@ function AccountSendForm() {
318
328
  }
319
329
  ),
320
330
  /* @__PURE__ */ jsx(
321
- CpslInput,
331
+ RecipientInput,
322
332
  {
323
333
  placeholder: "Enter recipient address",
324
334
  value: inputDestinationAddress,
@@ -330,7 +340,7 @@ function AccountSendForm() {
330
340
  ),
331
341
  ((estimate == null ? void 0 : estimate.feeValue) || (estimate == null ? void 0 : estimate.feeAmount) || estimateIsPending) && /* @__PURE__ */ jsxs("div", { style: { display: "flex", width: "100%", gap: "4px", alignItems: "center", justifyContent: "space-between" }, children: [
332
342
  /* @__PURE__ */ jsx(CpslText, { variant: "bodyXS", color: "secondary", children: "Network Fee" }),
333
- /* @__PURE__ */ jsx(CpslText, { variant: "bodyXS", color: "contrast", children: estimateIsPending ? "Estimating..." : (_k = (_j = ((_i = (_h = sendMetadata == null ? void 0 : sendMetadata.network) == null ? void 0 : _h.metadata) == null ? void 0 : _i.isTestnet) ? estimate == null ? void 0 : estimate.feeAmount : estimate == null ? void 0 : estimate.feeValue) != null ? _j : estimate == null ? void 0 : estimate.feeAmount) != null ? _k : "0" })
343
+ /* @__PURE__ */ jsx(CpslText, { variant: "bodyXS", color: "contrast", children: estimateIsPending ? "Estimating..." : (_o = (_n = ((_m = (_l = sendMetadata == null ? void 0 : sendMetadata.network) == null ? void 0 : _l.metadata) == null ? void 0 : _m.isTestnet) ? estimate == null ? void 0 : estimate.feeAmount : estimate == null ? void 0 : estimate.feeValue) != null ? _n : estimate == null ? void 0 : estimate.feeAmount) != null ? _o : "0" })
334
344
  ] }),
335
345
  error && /* @__PURE__ */ jsx("div", { style: { display: "flex", width: "100%", gap: "4px", alignItems: "center", justifyContent: "space-between" }, children: error }),
336
346
  /* @__PURE__ */ jsx(
@@ -339,14 +349,62 @@ function AccountSendForm() {
339
349
  variant: "primary",
340
350
  fullWidth: true,
341
351
  pending: estimateIsPending || broadcastIsPending,
342
- disabled: estimateIsPending || broadcastIsPending || !((_l = estimate == null ? void 0 : estimate.result) == null ? void 0 : _l.txSerialized) || !!(estimate == null ? void 0 : estimate.error),
352
+ disabled: estimateIsPending || broadcastIsPending || !((_p = estimate == null ? void 0 : estimate.result) == null ? void 0 : _p.txSerialized) || !!(estimate == null ? void 0 : estimate.error),
343
353
  onClick: onSubmit,
344
354
  "data-testid": "para-send-confirm",
345
355
  children: "Confirm Send"
346
356
  }
357
+ ),
358
+ isDevOrSandbox && isSendFormStep && typeof window !== "undefined" && createPortal(
359
+ /* @__PURE__ */ jsx(SimulateFailureContainer, { children: /* @__PURE__ */ jsxs(
360
+ "label",
361
+ {
362
+ style: {
363
+ display: "flex",
364
+ alignItems: "center",
365
+ gap: "8px",
366
+ cursor: "pointer",
367
+ width: "100%",
368
+ justifyContent: "center"
369
+ },
370
+ children: [
371
+ /* @__PURE__ */ jsx(
372
+ "input",
373
+ {
374
+ type: "checkbox",
375
+ checked: simulateFailure,
376
+ onChange: (e) => setSimulateFailure(e.target.checked),
377
+ style: { cursor: "pointer" }
378
+ }
379
+ ),
380
+ /* @__PURE__ */ jsx(CpslText, { variant: "bodyXS", color: "secondary", children: "Simulate failure" })
381
+ ]
382
+ }
383
+ ) }),
384
+ document.body
347
385
  )
348
386
  ] });
349
387
  }
388
+ const RecipientInput = safeStyled(CpslInput)`
389
+ --cpsl-color-input-surface-hover: var(--cpsl-color-input-surface-default);
390
+ `;
391
+ const SimulateFailureContainer = safeStyled.div`
392
+ position: fixed !important;
393
+ bottom: 0 !important;
394
+ left: 0 !important;
395
+ right: 0 !important;
396
+ width: 100% !important;
397
+ z-index: 100001 !important;
398
+ background: var(--cpsl-color-background-0) !important;
399
+ border-top: 1px solid var(--cpsl-color-background-16) !important;
400
+ padding: 16px !important;
401
+ display: flex !important;
402
+ justify-content: center !important;
403
+ align-items: center !important;
404
+ box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1) !important;
405
+ pointer-events: auto !important;
406
+ isolation: isolate;
407
+ `;
350
408
  export {
351
409
  AccountSendForm
352
410
  };