@lifi/widget 1.29.6 → 1.30.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 (62) hide show
  1. package/cjs/components/Card/CardTitle.d.ts +3 -1
  2. package/cjs/components/Card/CardTitle.js +7 -1
  3. package/cjs/components/ChainSelect/ChainSelect.d.ts +1 -0
  4. package/cjs/components/Header/WalletHeader.js +2 -2
  5. package/cjs/components/SendToWallet/SendToWallet.js +18 -10
  6. package/cjs/components/SendToWallet/SendToWalletButton.js +3 -2
  7. package/cjs/components/Step/CircularProgress.d.ts +1 -0
  8. package/cjs/components/Step/StepList.d.ts +1 -0
  9. package/cjs/components/SwapInput/SwapInputEndAdornment.d.ts +1 -0
  10. package/cjs/components/SwapRoutes/SwapRoutesExpanded.d.ts +1 -0
  11. package/cjs/config/version.d.ts +1 -1
  12. package/cjs/config/version.js +1 -1
  13. package/cjs/i18n/en.json +1 -0
  14. package/cjs/pages/ActiveSwapsPage/ActiveSwapsPage.d.ts +1 -0
  15. package/cjs/pages/MainPage/MainSwapButton.js +1 -1
  16. package/cjs/pages/SelectTokenPage/SearchTokenInput.d.ts +1 -0
  17. package/cjs/pages/SelectWalletPage/SelectWalletPage.d.ts +1 -0
  18. package/cjs/pages/SettingsPage/AdvancedPreferences.d.ts +1 -0
  19. package/cjs/pages/SettingsPage/GasPriceSelect.d.ts +1 -0
  20. package/cjs/pages/SettingsPage/SettingsPage.d.ts +1 -0
  21. package/cjs/pages/SettingsPage/ShowDestinationWallet.d.ts +1 -0
  22. package/cjs/pages/SettingsPage/SlippageInput.d.ts +1 -0
  23. package/cjs/pages/SwapPage/ExchangeRateBottomSheet.js +2 -2
  24. package/cjs/providers/SwapFormProvider/FormUpdater.js +2 -0
  25. package/cjs/providers/SwapFormProvider/SwapFormProvider.d.ts +5 -0
  26. package/cjs/providers/SwapFormProvider/SwapFormProvider.js +6 -3
  27. package/cjs/types/widget.d.ts +5 -0
  28. package/cjs/types/widget.js +5 -1
  29. package/cjs/utils/format.d.ts +1 -1
  30. package/cjs/utils/format.js +1 -2
  31. package/components/Card/CardTitle.d.ts +3 -1
  32. package/components/Card/CardTitle.js +7 -1
  33. package/components/ChainSelect/ChainSelect.d.ts +1 -0
  34. package/components/Header/WalletHeader.js +2 -2
  35. package/components/SendToWallet/SendToWallet.js +18 -10
  36. package/components/SendToWallet/SendToWalletButton.js +3 -2
  37. package/components/Step/CircularProgress.d.ts +1 -0
  38. package/components/Step/StepList.d.ts +1 -0
  39. package/components/SwapInput/SwapInputEndAdornment.d.ts +1 -0
  40. package/components/SwapRoutes/SwapRoutesExpanded.d.ts +1 -0
  41. package/config/version.d.ts +1 -1
  42. package/config/version.js +1 -1
  43. package/i18n/en.json +1 -0
  44. package/package.json +11 -11
  45. package/pages/ActiveSwapsPage/ActiveSwapsPage.d.ts +1 -0
  46. package/pages/MainPage/MainSwapButton.js +1 -1
  47. package/pages/SelectTokenPage/SearchTokenInput.d.ts +1 -0
  48. package/pages/SelectWalletPage/SelectWalletPage.d.ts +1 -0
  49. package/pages/SettingsPage/AdvancedPreferences.d.ts +1 -0
  50. package/pages/SettingsPage/GasPriceSelect.d.ts +1 -0
  51. package/pages/SettingsPage/SettingsPage.d.ts +1 -0
  52. package/pages/SettingsPage/ShowDestinationWallet.d.ts +1 -0
  53. package/pages/SettingsPage/SlippageInput.d.ts +1 -0
  54. package/pages/SwapPage/ExchangeRateBottomSheet.js +2 -2
  55. package/providers/SwapFormProvider/FormUpdater.js +2 -0
  56. package/providers/SwapFormProvider/SwapFormProvider.d.ts +5 -0
  57. package/providers/SwapFormProvider/SwapFormProvider.js +6 -3
  58. package/tsconfig.cjs.tsbuildinfo +1 -1
  59. package/types/widget.d.ts +5 -0
  60. package/types/widget.js +4 -0
  61. package/utils/format.d.ts +1 -1
  62. package/utils/format.js +1 -2
@@ -11,4 +11,6 @@ export declare const CardTitle: import("@emotion/styled").StyledComponent<import
11
11
  variantMapping?: Partial<Record<"button" | "caption" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "inherit" | "subtitle1" | "subtitle2" | "body1" | "body2" | "overline" | "@supports (font-variation-settings: normal)", string>> | undefined;
12
12
  } & import("@mui/material/OverridableComponent").CommonProps & Omit<Pick<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "key" | keyof import("react").HTMLAttributes<HTMLSpanElement>> & {
13
13
  ref?: ((instance: HTMLSpanElement | null) => void) | import("react").RefObject<HTMLSpanElement> | null | undefined;
14
- }, keyof import("@mui/material/OverridableComponent").CommonProps | "children" | "sx" | "variant" | ("p" | "color" | "border" | "boxShadow" | "fontWeight" | "zIndex" | "alignContent" | "alignItems" | "alignSelf" | "bottom" | "boxSizing" | "columnGap" | "display" | "flexBasis" | "flexDirection" | "flexGrow" | "flexShrink" | "flexWrap" | "fontFamily" | "fontSize" | "fontStyle" | "gridAutoColumns" | "gridAutoFlow" | "gridAutoRows" | "gridTemplateAreas" | "gridTemplateColumns" | "gridTemplateRows" | "height" | "justifyContent" | "justifyItems" | "justifySelf" | "left" | "letterSpacing" | "lineHeight" | "marginBottom" | "marginLeft" | "marginRight" | "marginTop" | "maxHeight" | "maxWidth" | "minHeight" | "minWidth" | "order" | "paddingBottom" | "paddingLeft" | "paddingRight" | "paddingTop" | "position" | "right" | "rowGap" | "textAlign" | "textOverflow" | "textTransform" | "top" | "visibility" | "whiteSpace" | "width" | "borderBottom" | "borderColor" | "borderLeft" | "borderRadius" | "borderRight" | "borderTop" | "flex" | "gap" | "gridArea" | "gridColumn" | "gridRow" | "margin" | "overflow" | "padding" | "bgcolor" | "m" | "mt" | "mr" | "mb" | "ml" | "mx" | "marginX" | "my" | "marginY" | "pt" | "pr" | "pb" | "pl" | "px" | "paddingX" | "py" | "paddingY" | "typography" | "displayPrint") | "align" | "gutterBottom" | "noWrap" | "paragraph" | "variantMapping"> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
14
+ }, keyof import("@mui/material/OverridableComponent").CommonProps | "children" | "sx" | "variant" | ("p" | "color" | "border" | "boxShadow" | "fontWeight" | "zIndex" | "alignContent" | "alignItems" | "alignSelf" | "bottom" | "boxSizing" | "columnGap" | "display" | "flexBasis" | "flexDirection" | "flexGrow" | "flexShrink" | "flexWrap" | "fontFamily" | "fontSize" | "fontStyle" | "gridAutoColumns" | "gridAutoFlow" | "gridAutoRows" | "gridTemplateAreas" | "gridTemplateColumns" | "gridTemplateRows" | "height" | "justifyContent" | "justifyItems" | "justifySelf" | "left" | "letterSpacing" | "lineHeight" | "marginBottom" | "marginLeft" | "marginRight" | "marginTop" | "maxHeight" | "maxWidth" | "minHeight" | "minWidth" | "order" | "paddingBottom" | "paddingLeft" | "paddingRight" | "paddingTop" | "position" | "right" | "rowGap" | "textAlign" | "textOverflow" | "textTransform" | "top" | "visibility" | "whiteSpace" | "width" | "borderBottom" | "borderColor" | "borderLeft" | "borderRadius" | "borderRight" | "borderTop" | "flex" | "gap" | "gridArea" | "gridColumn" | "gridRow" | "margin" | "overflow" | "padding" | "bgcolor" | "m" | "mt" | "mr" | "mb" | "ml" | "mx" | "marginX" | "my" | "marginY" | "pt" | "pr" | "pb" | "pl" | "px" | "paddingX" | "py" | "paddingY" | "typography" | "displayPrint") | "align" | "gutterBottom" | "noWrap" | "paragraph" | "variantMapping"> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme> & {
15
+ required?: boolean | undefined;
16
+ }, {}, {}>;
@@ -3,10 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CardTitle = void 0;
4
4
  const material_1 = require("@mui/material");
5
5
  const styles_1 = require("@mui/material/styles");
6
- exports.CardTitle = (0, styles_1.styled)(material_1.Typography)(({ theme }) => ({
6
+ exports.CardTitle = (0, styles_1.styled)(material_1.Typography, {
7
+ shouldForwardProp: (prop) => !['required'].includes(prop),
8
+ })(({ theme, required }) => ({
7
9
  fontSize: '0.875rem',
8
10
  lineHeight: '1.286',
9
11
  letterSpacing: '0.01071em',
10
12
  fontWeight: 700,
11
13
  padding: theme.spacing(1.75, 2, 0, 2),
14
+ '&:after': {
15
+ content: required ? '" *"' : 'none',
16
+ color: theme.palette.error.main,
17
+ },
12
18
  }));
@@ -1,2 +1,3 @@
1
+ /// <reference types="react" />
1
2
  import type { SwapFormTypeProps } from '../../providers';
2
3
  export declare const ChainSelect: ({ formType }: SwapFormTypeProps) => JSX.Element;
@@ -30,11 +30,11 @@ const ConnectButton = () => {
30
30
  const { t } = (0, react_i18next_1.useTranslation)();
31
31
  const { pathname } = (0, react_router_dom_1.useLocation)();
32
32
  const config = (0, providers_1.useWidgetConfig)();
33
- const { connect: walletConnect } = (0, providers_1.useWallet)();
33
+ const { connect: connectWallet } = (0, providers_1.useWallet)();
34
34
  const navigate = (0, react_router_dom_1.useNavigate)();
35
35
  const connect = () => __awaiter(void 0, void 0, void 0, function* () {
36
36
  if (config.walletManagement) {
37
- yield walletConnect();
37
+ yield connectWallet();
38
38
  return;
39
39
  }
40
40
  navigate(utils_1.navigationRoutes.selectWallet);
@@ -23,31 +23,39 @@ const Card_1 = require("../Card");
23
23
  const SendToWallet_style_1 = require("./SendToWallet.style");
24
24
  exports.SendToWallet = (0, react_1.forwardRef)((props, ref) => {
25
25
  const { t } = (0, react_i18next_1.useTranslation)();
26
- const { register, trigger } = (0, react_hook_form_1.useFormContext)();
26
+ const { register, unregister, trigger, getValues, clearErrors } = (0, react_hook_form_1.useFormContext)();
27
27
  const { account, provider } = (0, providers_1.useWallet)();
28
- const { disabledUI, hiddenUI, toAddress } = (0, providers_1.useWidgetConfig)();
28
+ const { disabledUI, hiddenUI, requiredUI, toAddress } = (0, providers_1.useWidgetConfig)();
29
29
  const { showSendToWallet, showSendToWalletDirty, setSendToWallet } = (0, stores_1.useSendToWalletStore)();
30
30
  const { showDestinationWallet } = (0, stores_1.useSettings)(['showDestinationWallet']);
31
- (0, react_1.useEffect)(() => {
32
- trigger(providers_1.SwapFormKey.ToAddress);
33
- }, [account.chainId, trigger]);
34
31
  const hiddenToAddress = hiddenUI === null || hiddenUI === void 0 ? void 0 : hiddenUI.includes(types_1.HiddenUI.ToAddress);
35
32
  const disabledToAddress = disabledUI === null || disabledUI === void 0 ? void 0 : disabledUI.includes(types_1.DisabledUI.ToAddress);
36
- // We want to show toAddress field if it is set via widget configuration, disabled for changes, but not hidden
33
+ const requiredToAddress = requiredUI === null || requiredUI === void 0 ? void 0 : requiredUI.includes(types_1.DisabledUI.ToAddress);
34
+ // We want to show toAddress field if it is set via widget configuration and not hidden
37
35
  const showInstantly = Boolean(!showSendToWalletDirty &&
38
- toAddress &&
39
- disabledToAddress &&
40
36
  showDestinationWallet &&
41
- !hiddenToAddress);
37
+ toAddress &&
38
+ !hiddenToAddress) || requiredToAddress;
42
39
  (0, react_1.useEffect)(() => {
43
40
  if (showInstantly) {
44
41
  setSendToWallet(true);
45
42
  }
46
43
  }, [showInstantly, setSendToWallet]);
44
+ (0, react_1.useEffect)(() => {
45
+ const value = getValues(providers_1.SwapFormKey.ToAddress);
46
+ if (value) {
47
+ trigger(providers_1.SwapFormKey.ToAddress);
48
+ }
49
+ }, [account.chainId, getValues, trigger]);
50
+ (0, react_1.useEffect)(() => {
51
+ unregister(providers_1.SwapFormKey.ToAddress);
52
+ }, [requiredToAddress, unregister]);
47
53
  if (hiddenToAddress) {
48
54
  return null;
49
55
  }
50
56
  const { onChange, onBlur, name, ref: inputRef, } = register(providers_1.SwapFormKey.ToAddress, {
57
+ required: requiredToAddress &&
58
+ t('swap.error.title.walletAddressRequired'),
51
59
  validate: (value) => __awaiter(void 0, void 0, void 0, function* () {
52
60
  try {
53
61
  if (!value) {
@@ -63,7 +71,7 @@ exports.SendToWallet = (0, react_1.forwardRef)((props, ref) => {
63
71
  }),
64
72
  onBlur: () => trigger(providers_1.SwapFormKey.ToAddress),
65
73
  });
66
- return ((0, jsx_runtime_1.jsx)(material_1.Collapse, Object.assign({ timeout: showInstantly ? 0 : 225, in: showSendToWallet || showInstantly, mountOnEnter: true, unmountOnExit: true }, { children: (0, jsx_runtime_1.jsxs)(Card_1.Card, Object.assign({}, props, { ref: ref }, { children: [(0, jsx_runtime_1.jsx)(Card_1.CardTitle, { children: t('swap.sendToWallet') }), (0, jsx_runtime_1.jsxs)(SendToWallet_style_1.FormControl, Object.assign({ fullWidth: true, sx: { paddingTop: '6px', paddingBottom: '5px' } }, { children: [(0, jsx_runtime_1.jsx)(SendToWallet_style_1.Input, { ref: inputRef, size: "small", autoComplete: "off", autoCorrect: "off", autoCapitalize: "off", spellCheck: "false", onChange: onChange, onBlur: onBlur, name: name, placeholder: t('swap.walletAddressOrEns'), disabled: Boolean(toAddress && disabledToAddress) }), (0, jsx_runtime_1.jsx)(exports.SendToWalletFormHelperText, {})] }))] })) })));
74
+ return ((0, jsx_runtime_1.jsx)(material_1.Collapse, Object.assign({ timeout: showInstantly ? 0 : 225, in: showSendToWallet || showInstantly, mountOnEnter: true, unmountOnExit: true }, { children: (0, jsx_runtime_1.jsxs)(Card_1.Card, Object.assign({}, props, { ref: ref }, { children: [(0, jsx_runtime_1.jsx)(Card_1.CardTitle, Object.assign({ required: requiredToAddress }, { children: t('swap.sendToWallet') })), (0, jsx_runtime_1.jsxs)(SendToWallet_style_1.FormControl, Object.assign({ fullWidth: true, sx: { paddingTop: '6px', paddingBottom: '5px' } }, { children: [(0, jsx_runtime_1.jsx)(SendToWallet_style_1.Input, { ref: inputRef, size: "small", autoComplete: "off", autoCorrect: "off", autoCapitalize: "off", spellCheck: "false", onChange: onChange, onBlur: onBlur, name: name, placeholder: t('swap.walletAddressOrEns'), disabled: Boolean(toAddress && disabledToAddress) }), (0, jsx_runtime_1.jsx)(exports.SendToWalletFormHelperText, {})] }))] })) })));
67
75
  });
68
76
  const SendToWalletFormHelperText = () => {
69
77
  var _a;
@@ -13,12 +13,13 @@ const SendToWalletButton = () => {
13
13
  const { t } = (0, react_i18next_1.useTranslation)();
14
14
  const { setValue } = (0, react_hook_form_1.useFormContext)();
15
15
  const { account } = (0, providers_1.useWallet)();
16
- const { disabledUI, hiddenUI } = (0, providers_1.useWidgetConfig)();
16
+ const { disabledUI, hiddenUI, requiredUI } = (0, providers_1.useWidgetConfig)();
17
17
  const { showSendToWallet, toggleSendToWallet } = (0, stores_1.useSendToWalletStore)();
18
18
  const { showDestinationWallet } = (0, stores_1.useSettings)(['showDestinationWallet']);
19
19
  if (!showDestinationWallet ||
20
20
  !account.isActive ||
21
- (hiddenUI === null || hiddenUI === void 0 ? void 0 : hiddenUI.includes(types_1.HiddenUI.ToAddress))) {
21
+ (hiddenUI === null || hiddenUI === void 0 ? void 0 : hiddenUI.includes(types_1.HiddenUI.ToAddress)) ||
22
+ (requiredUI === null || requiredUI === void 0 ? void 0 : requiredUI.includes(types_1.HiddenUI.ToAddress))) {
22
23
  return null;
23
24
  }
24
25
  const handleClick = () => {
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  import type { Process } from '@lifi/sdk';
2
3
  export declare function CircularProgress({ process }: {
3
4
  process: Process;
@@ -1,2 +1,3 @@
1
+ /// <reference types="react" />
1
2
  import { Route } from '@lifi/sdk';
2
3
  export declare const getStepList: (route?: Route) => JSX.Element[] | undefined;
@@ -1,2 +1,3 @@
1
+ /// <reference types="react" />
1
2
  import type { SwapFormTypeProps } from '../../providers';
2
3
  export declare const SwapInputEndAdornment: ({ formType }: SwapFormTypeProps) => JSX.Element;
@@ -1,2 +1,3 @@
1
+ /// <reference types="react" />
1
2
  export declare const SwapRoutesExpanded: () => JSX.Element;
2
3
  export declare const SwapRoutesExpandedElement: () => JSX.Element;
@@ -1,2 +1,2 @@
1
1
  export declare const name = "@lifi/widget";
2
- export declare const version = "1.29.6";
2
+ export declare const version = "1.30.0";
@@ -2,4 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.version = exports.name = void 0;
4
4
  exports.name = '@lifi/widget';
5
- exports.version = '1.29.6';
5
+ exports.version = '1.30.0';
package/cjs/i18n/en.json CHANGED
@@ -93,6 +93,7 @@
93
93
  "transactionUnprepared": "Unable to prepare transaction",
94
94
  "unknown": "Something went wrong",
95
95
  "walletAddressInvalid": "Wallet address is invalid.",
96
+ "walletAddressRequired": "Wallet address is required.",
96
97
  "walletEnsAddressInvalid": "Wallet address is invalid or network doesn't support ENS."
97
98
  }
98
99
  },
@@ -1 +1,2 @@
1
+ /// <reference types="react" />
1
2
  export declare const ActiveSwapsPage: () => JSX.Element;
@@ -31,6 +31,6 @@ const MainSwapButton = () => {
31
31
  });
32
32
  }
33
33
  });
34
- return ((0, jsx_runtime_1.jsx)(SwapButton_1.SwapButton, { onClick: handleClick, currentRoute: currentRoute, disabled: isLoading || isFetching || isValidating || !isValid }));
34
+ return ((0, jsx_runtime_1.jsx)(SwapButton_1.SwapButton, { onClick: handleClick, currentRoute: currentRoute, disabled: currentRoute && (isLoading || isFetching || isValidating || !isValid) }));
35
35
  };
36
36
  exports.MainSwapButton = MainSwapButton;
@@ -1 +1,2 @@
1
+ /// <reference types="react" />
1
2
  export declare const SearchTokenInput: () => JSX.Element;
@@ -1 +1,2 @@
1
+ /// <reference types="react" />
1
2
  export declare const SelectWalletPage: () => JSX.Element;
@@ -1 +1,2 @@
1
+ /// <reference types="react" />
1
2
  export declare const AdvancedPreferences: () => JSX.Element;
@@ -1 +1,2 @@
1
+ /// <reference types="react" />
1
2
  export declare const GasPriceSelect: () => JSX.Element;
@@ -1 +1,2 @@
1
+ /// <reference types="react" />
1
2
  export declare const SettingsPage: () => JSX.Element;
@@ -1 +1,2 @@
1
+ /// <reference types="react" />
1
2
  export declare const ShowDestinationWallet: () => JSX.Element | null;
@@ -1 +1,2 @@
1
+ /// <reference types="react" />
1
2
  export declare const SlippageInput: () => JSX.Element;
@@ -53,9 +53,9 @@ const ExchangeRateBottomSheetContent = ({ data, onCancel, onContinue }) => {
53
53
  const ref = (0, react_1.useRef)();
54
54
  (0, hooks_1.useSetContentHeight)(ref);
55
55
  return ((0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ p: 3, ref: ref }, { children: [(0, jsx_runtime_1.jsxs)(StatusBottomSheet_style_1.IconContainer, { children: [(0, jsx_runtime_1.jsx)(StatusBottomSheet_style_1.IconCircle, Object.assign({ status: "warning", mb: 1 }, { children: (0, jsx_runtime_1.jsx)(icons_material_1.WarningRounded, { color: "warning" }) })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ py: 1, fontSize: 18, fontWeight: 700 }, { children: t('swap.warning.title.rateChanged') }))] }), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ py: 1 }, { children: t('swap.warning.message.rateChanged') })), (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ display: "flex", justifyContent: "space-between", mt: 1 }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { children: t('swap.quotedAmount') }), (0, jsx_runtime_1.jsxs)(material_1.Typography, Object.assign({ fontWeight: 600 }, { children: [t('format.number', {
56
- value: (0, utils_1.formatTokenAmount)(data === null || data === void 0 ? void 0 : data.oldToAmount, data === null || data === void 0 ? void 0 : data.toToken.decimals),
56
+ value: (0, utils_1.formatTokenAmount)(data === null || data === void 0 ? void 0 : data.oldToAmount, data === null || data === void 0 ? void 0 : data.toToken.decimals, 5),
57
57
  }), ' ', data === null || data === void 0 ? void 0 : data.toToken.symbol] }))] })), (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ display: "flex", justifyContent: "space-between", mt: 0.25 }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { children: t('swap.currentAmount') }), (0, jsx_runtime_1.jsxs)(material_1.Typography, Object.assign({ fontWeight: 600 }, { children: [t('format.number', {
58
- value: (0, utils_1.formatTokenAmount)(data === null || data === void 0 ? void 0 : data.newToAmount, data === null || data === void 0 ? void 0 : data.toToken.decimals),
58
+ value: (0, utils_1.formatTokenAmount)(data === null || data === void 0 ? void 0 : data.newToAmount, data === null || data === void 0 ? void 0 : data.toToken.decimals, 5),
59
59
  }), ' ', data === null || data === void 0 ? void 0 : data.toToken.symbol] }))] })), (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ display: "flex", justifyContent: "space-between", mt: 0.25 }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { children: t('swap.rateChange') }), (0, jsx_runtime_1.jsxs)(material_1.Typography, Object.assign({ fontWeight: 600 }, { children: [(0, big_js_1.default)((data === null || data === void 0 ? void 0 : data.newToAmount) || 0)
60
60
  .div((0, big_js_1.default)((data === null || data === void 0 ? void 0 : data.oldToAmount) || 0))
61
61
  .minus(1)
@@ -47,6 +47,8 @@ const FormUpdater = ({ defaultValues }) => {
47
47
  setValue,
48
48
  toChain,
49
49
  ]);
50
+ // Makes widget config options reactive to changes
51
+ // Acts similar to values property from useForm, but includes additional logic for chains
50
52
  (0, react_1.useEffect)(() => {
51
53
  Object.keys(defaultValues).forEach((key) => {
52
54
  if (previousDefaultValues.current[key] !== defaultValues[key]) {
@@ -3,5 +3,10 @@ export declare const formDefaultValues: {
3
3
  fromAmount: string;
4
4
  toAddress: string;
5
5
  tokenSearchFilter: string;
6
+ contractOutputsToken: string;
7
+ toContractAddress: string;
8
+ toContractCallData: string;
9
+ ToContractGasLimit: string;
10
+ toAmount: string;
6
11
  };
7
12
  export declare const SwapFormProvider: React.FC<React.PropsWithChildren<{}>>;
@@ -12,6 +12,11 @@ exports.formDefaultValues = {
12
12
  [types_1.SwapFormKey.FromAmount]: '',
13
13
  [types_1.SwapFormKey.ToAddress]: '',
14
14
  [types_1.SwapFormKey.TokenSearchFilter]: '',
15
+ [types_1.SwapFormKey.ContractOutputsToken]: '',
16
+ [types_1.SwapFormKey.ToContractAddress]: '',
17
+ [types_1.SwapFormKey.ToContractCallData]: '',
18
+ [types_1.SwapFormKey.ToContractGasLimit]: '',
19
+ [types_1.SwapFormKey.ToAmount]: '',
15
20
  };
16
21
  const SwapFormProvider = ({ children, }) => {
17
22
  const { fromChain, fromToken, fromAmount, toChain, toToken, toAddress, buildSwapUrl, } = (0, WidgetProvider_1.useWidgetConfig)();
@@ -19,10 +24,8 @@ const SwapFormProvider = ({ children, }) => {
19
24
  fromToken, fromAmount: (typeof fromAmount === 'number'
20
25
  ? fromAmount === null || fromAmount === void 0 ? void 0 : fromAmount.toPrecision()
21
26
  : fromAmount) || exports.formDefaultValues.fromAmount, toChain,
22
- toToken,
23
- toAddress })), [fromAmount, fromChain, fromToken, toAddress, toChain, toToken]);
27
+ toToken, toAddress: toAddress || exports.formDefaultValues.toAddress })), [fromAmount, fromChain, fromToken, toAddress, toChain, toToken]);
24
28
  const methods = (0, react_hook_form_1.useForm)({
25
- // TODO: revisit after RHF release values support
26
29
  // values,
27
30
  defaultValues,
28
31
  });
@@ -19,6 +19,10 @@ export declare enum HiddenUI {
19
19
  ToAddress = "toAddress"
20
20
  }
21
21
  export type HiddenUIType = `${HiddenUI}`;
22
+ export declare enum RequiredUI {
23
+ ToAddress = "toAddress"
24
+ }
25
+ export type RequiredUIType = `${RequiredUI}`;
22
26
  export type Appearance = PaletteMode | 'auto';
23
27
  export type ThemeConfig = {
24
28
  palette?: Pick<PaletteOptions, 'background' | 'grey' | 'primary' | 'secondary' | 'text'>;
@@ -73,6 +77,7 @@ export interface WidgetConfig {
73
77
  disableTelemetry?: boolean;
74
78
  disabledUI?: DisabledUIType[];
75
79
  hiddenUI?: HiddenUIType[];
80
+ requiredUI?: RequiredUIType[];
76
81
  useRecommendedRoute?: boolean;
77
82
  walletManagement?: WidgetWalletManagement;
78
83
  sdkConfig?: SDKConfig;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.HiddenUI = exports.DisabledUI = void 0;
3
+ exports.RequiredUI = exports.HiddenUI = exports.DisabledUI = void 0;
4
4
  var DisabledUI;
5
5
  (function (DisabledUI) {
6
6
  DisabledUI["FromAmount"] = "fromAmount";
@@ -17,3 +17,7 @@ var HiddenUI;
17
17
  HiddenUI["ToAddress"] = "toAddress";
18
18
  // ToToken = 'toToken',
19
19
  })(HiddenUI = exports.HiddenUI || (exports.HiddenUI = {}));
20
+ var RequiredUI;
21
+ (function (RequiredUI) {
22
+ RequiredUI["ToAddress"] = "toAddress";
23
+ })(RequiredUI = exports.RequiredUI || (exports.RequiredUI = {}));
@@ -3,7 +3,7 @@
3
3
  * @param amount amount to format.
4
4
  * @returns formatted amount.
5
5
  */
6
- export declare const formatTokenAmount: (amount?: string, decimals?: number) => string;
6
+ export declare const formatTokenAmount: (amount?: string, decimals?: number, decimalPlaces?: number) => string;
7
7
  export declare const formatSlippage: (slippage?: string, defaultValue?: string, returnInitial?: boolean) => string;
8
8
  export declare const formatAmount: (amount?: string, returnInitial?: boolean) => string;
9
9
  export declare const formatTokenPrice: (amount?: string, price?: string) => number;
@@ -11,7 +11,7 @@ big_js_1.default.NE = -42;
11
11
  * @param amount amount to format.
12
12
  * @returns formatted amount.
13
13
  */
14
- const formatTokenAmount = (amount = '0', decimals = 0) => {
14
+ const formatTokenAmount = (amount = '0', decimals = 0, decimalPlaces = 3) => {
15
15
  let shiftedAmount = amount;
16
16
  if (decimals) {
17
17
  shiftedAmount = (Number(amount) / Math.pow(10, decimals)).toString();
@@ -20,7 +20,6 @@ const formatTokenAmount = (amount = '0', decimals = 0) => {
20
20
  if (parsedAmount === 0 || isNaN(Number(shiftedAmount))) {
21
21
  return '0';
22
22
  }
23
- let decimalPlaces = 3;
24
23
  const absAmount = Math.abs(parsedAmount);
25
24
  while (absAmount < 1 / Math.pow(10, decimalPlaces)) {
26
25
  decimalPlaces++;
@@ -11,4 +11,6 @@ export declare const CardTitle: import("@emotion/styled").StyledComponent<import
11
11
  variantMapping?: Partial<Record<"button" | "caption" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "inherit" | "subtitle1" | "subtitle2" | "body1" | "body2" | "overline" | "@supports (font-variation-settings: normal)", string>> | undefined;
12
12
  } & import("@mui/material/OverridableComponent").CommonProps & Omit<Pick<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "key" | keyof import("react").HTMLAttributes<HTMLSpanElement>> & {
13
13
  ref?: ((instance: HTMLSpanElement | null) => void) | import("react").RefObject<HTMLSpanElement> | null | undefined;
14
- }, keyof import("@mui/material/OverridableComponent").CommonProps | "children" | "sx" | "variant" | ("p" | "color" | "border" | "boxShadow" | "fontWeight" | "zIndex" | "alignContent" | "alignItems" | "alignSelf" | "bottom" | "boxSizing" | "columnGap" | "display" | "flexBasis" | "flexDirection" | "flexGrow" | "flexShrink" | "flexWrap" | "fontFamily" | "fontSize" | "fontStyle" | "gridAutoColumns" | "gridAutoFlow" | "gridAutoRows" | "gridTemplateAreas" | "gridTemplateColumns" | "gridTemplateRows" | "height" | "justifyContent" | "justifyItems" | "justifySelf" | "left" | "letterSpacing" | "lineHeight" | "marginBottom" | "marginLeft" | "marginRight" | "marginTop" | "maxHeight" | "maxWidth" | "minHeight" | "minWidth" | "order" | "paddingBottom" | "paddingLeft" | "paddingRight" | "paddingTop" | "position" | "right" | "rowGap" | "textAlign" | "textOverflow" | "textTransform" | "top" | "visibility" | "whiteSpace" | "width" | "borderBottom" | "borderColor" | "borderLeft" | "borderRadius" | "borderRight" | "borderTop" | "flex" | "gap" | "gridArea" | "gridColumn" | "gridRow" | "margin" | "overflow" | "padding" | "bgcolor" | "m" | "mt" | "mr" | "mb" | "ml" | "mx" | "marginX" | "my" | "marginY" | "pt" | "pr" | "pb" | "pl" | "px" | "paddingX" | "py" | "paddingY" | "typography" | "displayPrint") | "align" | "gutterBottom" | "noWrap" | "paragraph" | "variantMapping"> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
14
+ }, keyof import("@mui/material/OverridableComponent").CommonProps | "children" | "sx" | "variant" | ("p" | "color" | "border" | "boxShadow" | "fontWeight" | "zIndex" | "alignContent" | "alignItems" | "alignSelf" | "bottom" | "boxSizing" | "columnGap" | "display" | "flexBasis" | "flexDirection" | "flexGrow" | "flexShrink" | "flexWrap" | "fontFamily" | "fontSize" | "fontStyle" | "gridAutoColumns" | "gridAutoFlow" | "gridAutoRows" | "gridTemplateAreas" | "gridTemplateColumns" | "gridTemplateRows" | "height" | "justifyContent" | "justifyItems" | "justifySelf" | "left" | "letterSpacing" | "lineHeight" | "marginBottom" | "marginLeft" | "marginRight" | "marginTop" | "maxHeight" | "maxWidth" | "minHeight" | "minWidth" | "order" | "paddingBottom" | "paddingLeft" | "paddingRight" | "paddingTop" | "position" | "right" | "rowGap" | "textAlign" | "textOverflow" | "textTransform" | "top" | "visibility" | "whiteSpace" | "width" | "borderBottom" | "borderColor" | "borderLeft" | "borderRadius" | "borderRight" | "borderTop" | "flex" | "gap" | "gridArea" | "gridColumn" | "gridRow" | "margin" | "overflow" | "padding" | "bgcolor" | "m" | "mt" | "mr" | "mb" | "ml" | "mx" | "marginX" | "my" | "marginY" | "pt" | "pr" | "pb" | "pl" | "px" | "paddingX" | "py" | "paddingY" | "typography" | "displayPrint") | "align" | "gutterBottom" | "noWrap" | "paragraph" | "variantMapping"> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme> & {
15
+ required?: boolean | undefined;
16
+ }, {}, {}>;
@@ -1,9 +1,15 @@
1
1
  import { Typography } from '@mui/material';
2
2
  import { styled } from '@mui/material/styles';
3
- export const CardTitle = styled(Typography)(({ theme }) => ({
3
+ export const CardTitle = styled(Typography, {
4
+ shouldForwardProp: (prop) => !['required'].includes(prop),
5
+ })(({ theme, required }) => ({
4
6
  fontSize: '0.875rem',
5
7
  lineHeight: '1.286',
6
8
  letterSpacing: '0.01071em',
7
9
  fontWeight: 700,
8
10
  padding: theme.spacing(1.75, 2, 0, 2),
11
+ '&:after': {
12
+ content: required ? '" *"' : 'none',
13
+ color: theme.palette.error.main,
14
+ },
9
15
  }));
@@ -1,2 +1,3 @@
1
+ /// <reference types="react" />
1
2
  import type { SwapFormTypeProps } from '../../providers';
2
3
  export declare const ChainSelect: ({ formType }: SwapFormTypeProps) => JSX.Element;
@@ -26,11 +26,11 @@ const ConnectButton = () => {
26
26
  const { t } = useTranslation();
27
27
  const { pathname } = useLocation();
28
28
  const config = useWidgetConfig();
29
- const { connect: walletConnect } = useWallet();
29
+ const { connect: connectWallet } = useWallet();
30
30
  const navigate = useNavigate();
31
31
  const connect = () => __awaiter(void 0, void 0, void 0, function* () {
32
32
  if (config.walletManagement) {
33
- yield walletConnect();
33
+ yield connectWallet();
34
34
  return;
35
35
  }
36
36
  navigate(navigationRoutes.selectWallet);
@@ -20,31 +20,39 @@ import { Card, CardTitle } from '../Card';
20
20
  import { FormControl, Input } from './SendToWallet.style';
21
21
  export const SendToWallet = forwardRef((props, ref) => {
22
22
  const { t } = useTranslation();
23
- const { register, trigger } = useFormContext();
23
+ const { register, unregister, trigger, getValues, clearErrors } = useFormContext();
24
24
  const { account, provider } = useWallet();
25
- const { disabledUI, hiddenUI, toAddress } = useWidgetConfig();
25
+ const { disabledUI, hiddenUI, requiredUI, toAddress } = useWidgetConfig();
26
26
  const { showSendToWallet, showSendToWalletDirty, setSendToWallet } = useSendToWalletStore();
27
27
  const { showDestinationWallet } = useSettings(['showDestinationWallet']);
28
- useEffect(() => {
29
- trigger(SwapFormKey.ToAddress);
30
- }, [account.chainId, trigger]);
31
28
  const hiddenToAddress = hiddenUI === null || hiddenUI === void 0 ? void 0 : hiddenUI.includes(HiddenUI.ToAddress);
32
29
  const disabledToAddress = disabledUI === null || disabledUI === void 0 ? void 0 : disabledUI.includes(DisabledUI.ToAddress);
33
- // We want to show toAddress field if it is set via widget configuration, disabled for changes, but not hidden
30
+ const requiredToAddress = requiredUI === null || requiredUI === void 0 ? void 0 : requiredUI.includes(DisabledUI.ToAddress);
31
+ // We want to show toAddress field if it is set via widget configuration and not hidden
34
32
  const showInstantly = Boolean(!showSendToWalletDirty &&
35
- toAddress &&
36
- disabledToAddress &&
37
33
  showDestinationWallet &&
38
- !hiddenToAddress);
34
+ toAddress &&
35
+ !hiddenToAddress) || requiredToAddress;
39
36
  useEffect(() => {
40
37
  if (showInstantly) {
41
38
  setSendToWallet(true);
42
39
  }
43
40
  }, [showInstantly, setSendToWallet]);
41
+ useEffect(() => {
42
+ const value = getValues(SwapFormKey.ToAddress);
43
+ if (value) {
44
+ trigger(SwapFormKey.ToAddress);
45
+ }
46
+ }, [account.chainId, getValues, trigger]);
47
+ useEffect(() => {
48
+ unregister(SwapFormKey.ToAddress);
49
+ }, [requiredToAddress, unregister]);
44
50
  if (hiddenToAddress) {
45
51
  return null;
46
52
  }
47
53
  const { onChange, onBlur, name, ref: inputRef, } = register(SwapFormKey.ToAddress, {
54
+ required: requiredToAddress &&
55
+ t('swap.error.title.walletAddressRequired'),
48
56
  validate: (value) => __awaiter(void 0, void 0, void 0, function* () {
49
57
  try {
50
58
  if (!value) {
@@ -60,7 +68,7 @@ export const SendToWallet = forwardRef((props, ref) => {
60
68
  }),
61
69
  onBlur: () => trigger(SwapFormKey.ToAddress),
62
70
  });
63
- return (_jsx(Collapse, Object.assign({ timeout: showInstantly ? 0 : 225, in: showSendToWallet || showInstantly, mountOnEnter: true, unmountOnExit: true }, { children: _jsxs(Card, Object.assign({}, props, { ref: ref }, { children: [_jsx(CardTitle, { children: t('swap.sendToWallet') }), _jsxs(FormControl, Object.assign({ fullWidth: true, sx: { paddingTop: '6px', paddingBottom: '5px' } }, { children: [_jsx(Input, { ref: inputRef, size: "small", autoComplete: "off", autoCorrect: "off", autoCapitalize: "off", spellCheck: "false", onChange: onChange, onBlur: onBlur, name: name, placeholder: t('swap.walletAddressOrEns'), disabled: Boolean(toAddress && disabledToAddress) }), _jsx(SendToWalletFormHelperText, {})] }))] })) })));
71
+ return (_jsx(Collapse, Object.assign({ timeout: showInstantly ? 0 : 225, in: showSendToWallet || showInstantly, mountOnEnter: true, unmountOnExit: true }, { children: _jsxs(Card, Object.assign({}, props, { ref: ref }, { children: [_jsx(CardTitle, Object.assign({ required: requiredToAddress }, { children: t('swap.sendToWallet') })), _jsxs(FormControl, Object.assign({ fullWidth: true, sx: { paddingTop: '6px', paddingBottom: '5px' } }, { children: [_jsx(Input, { ref: inputRef, size: "small", autoComplete: "off", autoCorrect: "off", autoCapitalize: "off", spellCheck: "false", onChange: onChange, onBlur: onBlur, name: name, placeholder: t('swap.walletAddressOrEns'), disabled: Boolean(toAddress && disabledToAddress) }), _jsx(SendToWalletFormHelperText, {})] }))] })) })));
64
72
  });
65
73
  export const SendToWalletFormHelperText = () => {
66
74
  var _a;
@@ -10,12 +10,13 @@ export const SendToWalletButton = () => {
10
10
  const { t } = useTranslation();
11
11
  const { setValue } = useFormContext();
12
12
  const { account } = useWallet();
13
- const { disabledUI, hiddenUI } = useWidgetConfig();
13
+ const { disabledUI, hiddenUI, requiredUI } = useWidgetConfig();
14
14
  const { showSendToWallet, toggleSendToWallet } = useSendToWalletStore();
15
15
  const { showDestinationWallet } = useSettings(['showDestinationWallet']);
16
16
  if (!showDestinationWallet ||
17
17
  !account.isActive ||
18
- (hiddenUI === null || hiddenUI === void 0 ? void 0 : hiddenUI.includes(HiddenUI.ToAddress))) {
18
+ (hiddenUI === null || hiddenUI === void 0 ? void 0 : hiddenUI.includes(HiddenUI.ToAddress)) ||
19
+ (requiredUI === null || requiredUI === void 0 ? void 0 : requiredUI.includes(HiddenUI.ToAddress))) {
19
20
  return null;
20
21
  }
21
22
  const handleClick = () => {
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  import type { Process } from '@lifi/sdk';
2
3
  export declare function CircularProgress({ process }: {
3
4
  process: Process;
@@ -1,2 +1,3 @@
1
+ /// <reference types="react" />
1
2
  import { Route } from '@lifi/sdk';
2
3
  export declare const getStepList: (route?: Route) => JSX.Element[] | undefined;
@@ -1,2 +1,3 @@
1
+ /// <reference types="react" />
1
2
  import type { SwapFormTypeProps } from '../../providers';
2
3
  export declare const SwapInputEndAdornment: ({ formType }: SwapFormTypeProps) => JSX.Element;
@@ -1,2 +1,3 @@
1
+ /// <reference types="react" />
1
2
  export declare const SwapRoutesExpanded: () => JSX.Element;
2
3
  export declare const SwapRoutesExpandedElement: () => JSX.Element;
@@ -1,2 +1,2 @@
1
1
  export declare const name = "@lifi/widget";
2
- export declare const version = "1.29.6";
2
+ export declare const version = "1.30.0";
package/config/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  export const name = '@lifi/widget';
2
- export const version = '1.29.6';
2
+ export const version = '1.30.0';
package/i18n/en.json CHANGED
@@ -93,6 +93,7 @@
93
93
  "transactionUnprepared": "Unable to prepare transaction",
94
94
  "unknown": "Something went wrong",
95
95
  "walletAddressInvalid": "Wallet address is invalid.",
96
+ "walletAddressRequired": "Wallet address is required.",
96
97
  "walletEnsAddressInvalid": "Wallet address is invalid or network doesn't support ENS."
97
98
  }
98
99
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifi/widget",
3
- "version": "1.29.6",
3
+ "version": "1.30.0",
4
4
  "description": "LI.FI Widget for cross-chain bridging and swapping. It will drive your multi-chain strategy and attract new users from everywhere.",
5
5
  "main": "./cjs/index.js",
6
6
  "module": "./index.js",
@@ -44,15 +44,15 @@
44
44
  "@ethersproject/experimental": "^5.7.0",
45
45
  "@ethersproject/providers": "^5.7.2",
46
46
  "@lifi/sdk": "^1.7.2",
47
- "@lifi/wallet-management": "^1.2.5",
47
+ "@lifi/wallet-management": "^1.2.6",
48
48
  "@mui/icons-material": "^5.11.0",
49
- "@mui/lab": "^5.0.0-alpha.117",
50
- "@mui/material": "^5.11.6",
51
- "@sentry/integrations": "^7.33.0",
52
- "@sentry/react": "^7.33.0",
53
- "@sentry/tracing": "^7.33.0",
54
- "@tanstack/react-query": "^4.23.0",
55
- "@tanstack/react-virtual": "^3.0.0-beta.39",
49
+ "@mui/lab": "^5.0.0-alpha.118",
50
+ "@mui/material": "^5.11.7",
51
+ "@sentry/integrations": "^7.35.0",
52
+ "@sentry/react": "^7.35.0",
53
+ "@sentry/tracing": "^7.35.0",
54
+ "@tanstack/react-query": "^4.24.4",
55
+ "@tanstack/react-virtual": "^3.0.0-beta.41",
56
56
  "big.js": "^6.2.1",
57
57
  "i18next": "^22.4.9",
58
58
  "i18next-browser-languagedetector": "^7.0.1",
@@ -60,9 +60,9 @@
60
60
  "mitt": "^3.0.0",
61
61
  "react": "^18.2.0",
62
62
  "react-dom": "^18.2.0",
63
- "react-hook-form": "^7.42.1",
63
+ "react-hook-form": "^7.43.0",
64
64
  "react-i18next": "^12.1.4",
65
- "react-router-dom": "^6.7.0",
65
+ "react-router-dom": "^6.8.0",
66
66
  "react-timer-hook": "^3.0.5",
67
67
  "uuid": "^9.0.0",
68
68
  "zustand": "^4.3.2"
@@ -1 +1,2 @@
1
+ /// <reference types="react" />
1
2
  export declare const ActiveSwapsPage: () => JSX.Element;
@@ -28,5 +28,5 @@ export const MainSwapButton = () => {
28
28
  });
29
29
  }
30
30
  });
31
- return (_jsx(SwapButton, { onClick: handleClick, currentRoute: currentRoute, disabled: isLoading || isFetching || isValidating || !isValid }));
31
+ return (_jsx(SwapButton, { onClick: handleClick, currentRoute: currentRoute, disabled: currentRoute && (isLoading || isFetching || isValidating || !isValid) }));
32
32
  };
@@ -1 +1,2 @@
1
+ /// <reference types="react" />
1
2
  export declare const SearchTokenInput: () => JSX.Element;
@@ -1 +1,2 @@
1
+ /// <reference types="react" />
1
2
  export declare const SelectWalletPage: () => JSX.Element;
@@ -1 +1,2 @@
1
+ /// <reference types="react" />
1
2
  export declare const AdvancedPreferences: () => JSX.Element;
@@ -1 +1,2 @@
1
+ /// <reference types="react" />
1
2
  export declare const GasPriceSelect: () => JSX.Element;
@@ -1 +1,2 @@
1
+ /// <reference types="react" />
1
2
  export declare const SettingsPage: () => JSX.Element;