@getpara/react-sdk-lite 2.9.0 → 2.10.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.
@@ -110,7 +110,7 @@ const ParaModal = forwardRef((props, ref) => {
110
110
  onClose,
111
111
  defaultAuthIdentifier
112
112
  }), rest),
113
- reactSdkVersion: "2.9.0"
113
+ reactSdkVersion: "2.10.0"
114
114
  });
115
115
  } catch (e) {
116
116
  }
@@ -24,6 +24,8 @@ type Value = {
24
24
  tab: Tab;
25
25
  activeWallet: ReturnType<typeof useWallet>['data'];
26
26
  onRampConfig: OnRampConfig;
27
+ /** On-ramp test mode: only respects config in PROD; non-PROD always behaves as test mode. */
28
+ isTestMode: boolean;
27
29
  settingsStep: SettingsStep | null;
28
30
  TestModeAlert: ReactNode;
29
31
  };
@@ -18,7 +18,8 @@ import {
18
18
  EnabledFlow,
19
19
  getOnRampAssets,
20
20
  getOnRampNetworks,
21
- OnRampPurchaseType
21
+ OnRampPurchaseType,
22
+ Environment
22
23
  } from "@getpara/web-sdk";
23
24
  import { getNetworkFromChainId, getNetworkOrMainNetEquivalent, safeStyled } from "@getpara/react-common";
24
25
  import { CpslAlert, CpslIcon } from "@getpara/react-components";
@@ -45,6 +46,7 @@ const DEFAULT = {
45
46
  },
46
47
  onRampConfig: {},
47
48
  activeWallet: {},
49
+ isTestMode: true,
48
50
  settingsStep: "FORM",
49
51
  TestModeAlert: null
50
52
  };
@@ -54,29 +56,31 @@ function isValid(onRampConfig, walletType, network, asset) {
54
56
  }
55
57
  const AddFundsContext = createContext(DEFAULT);
56
58
  function AddFundsContextProvider({ tab, children }) {
57
- var _a, _b;
59
+ var _a, _b, _c, _d, _e;
58
60
  const appName = useStore((state) => state.appName);
61
+ const client = useStore((state) => state.client);
59
62
  const onRampConfig = useModalStore((state) => state.onRampConfig);
60
63
  const onRampStep = useModalStore((state) => state.onRampStep);
61
64
  const setOnRampStep = useModalStore((state) => state.setOnRampStep);
62
65
  const isTestModeAlertDismissed = useModalStore((state) => state.isTestModeAlertDismissed);
63
66
  const setIsTestModeAlertDismissed = useModalStore((state) => state.setIsTestModeAlertDismissed);
64
67
  const { chainId } = useExternalWallets();
68
+ const isTestMode = ((_a = client == null ? void 0 : client.ctx) == null ? void 0 : _a.env) === Environment.PROD ? (_b = onRampConfig == null ? void 0 : onRampConfig.testMode) != null ? _b : false : true;
65
69
  const { data: activeWallet } = useWallet();
66
- const [fiatQuantity, setFiatQuantity] = useState((_b = (_a = onRampConfig == null ? void 0 : onRampConfig.defaultBuyAmount) == null ? void 0 : _a[0]) != null ? _b : "25.00");
70
+ const [fiatQuantity, setFiatQuantity] = useState((_d = (_c = onRampConfig == null ? void 0 : onRampConfig.defaultBuyAmount) == null ? void 0 : _c[0]) != null ? _d : "25.00");
67
71
  const networks = useMemo(() => {
68
72
  if (!onRampConfig) {
69
73
  return [];
70
74
  }
71
75
  const detectedNetwork = getNetworkFromChainId(chainId);
72
76
  const isExternal = (activeWallet == null ? void 0 : activeWallet.isExternal) && !!detectedNetwork;
73
- return isExternal ? [getNetworkOrMainNetEquivalent(detectedNetwork, onRampConfig.testMode)] : getOnRampNetworks(onRampConfig.assetInfo, {
77
+ return isExternal ? [getNetworkOrMainNetEquivalent(detectedNetwork, isTestMode)] : getOnRampNetworks(onRampConfig.assetInfo, {
74
78
  walletType: activeWallet == null ? void 0 : activeWallet.type,
75
79
  allowed: onRampConfig.allowedAssets ? Object.keys(onRampConfig.allowedAssets) : void 0,
76
80
  providers: onRampConfig.providers,
77
81
  action: OnRampPurchaseType[tab === EnabledFlow.BUY ? "BUY" : "SELL"]
78
82
  });
79
- }, [chainId, activeWallet, onRampConfig, tab]);
83
+ }, [chainId, activeWallet, onRampConfig, tab, isTestMode]);
80
84
  const assets = useMemo(() => {
81
85
  if (!onRampConfig) {
82
86
  return [];
@@ -116,9 +120,9 @@ function AddFundsContextProvider({ tab, children }) {
116
120
  const isProviderAllowed = useMemo(
117
121
  () => onRampConfig && !!(activeWallet == null ? void 0 : activeWallet.type) ? onRampConfig.providers.reduce(
118
122
  (acc, id) => {
119
- var _a2, _b2, _c, _d, _e;
123
+ var _a2, _b2, _c2, _d2, _e2;
120
124
  return __spreadProps(__spreadValues({}, acc), {
121
- [id]: !!network && !!asset && !!((_e = (_d = (_c = (_b2 = (_a2 = onRampConfig.assetInfo[activeWallet.type]) == null ? void 0 : _a2[network]) == null ? void 0 : _b2[asset]) == null ? void 0 : _c[id]) == null ? void 0 : _d[1]) == null ? void 0 : _e[tab === EnabledFlow.BUY ? "BUY" : "SELL"])
125
+ [id]: !!network && !!asset && !!((_e2 = (_d2 = (_c2 = (_b2 = (_a2 = onRampConfig.assetInfo[activeWallet.type]) == null ? void 0 : _a2[network]) == null ? void 0 : _b2[asset]) == null ? void 0 : _c2[id]) == null ? void 0 : _d2[1]) == null ? void 0 : _e2[tab === EnabledFlow.BUY ? "BUY" : "SELL"])
122
126
  });
123
127
  },
124
128
  {}
@@ -140,17 +144,23 @@ function AddFundsContextProvider({ tab, children }) {
140
144
  }
141
145
  }, [asset, network, assets.length, networks.length]);
142
146
  const TestModeAlert = useMemo(() => {
143
- return (onRampConfig == null ? void 0 : onRampConfig.testMode) && !isTestModeAlertDismissed ? /* @__PURE__ */ jsx(CpslAlert, { variant: "error", filled: true, children: /* @__PURE__ */ jsxs(Fragment, { children: [
144
- /* @__PURE__ */ jsxs("span", { children: [
147
+ var _a2;
148
+ const isProd = ((_a2 = client == null ? void 0 : client.ctx) == null ? void 0 : _a2.env) === Environment.PROD;
149
+ return isTestMode && !isTestModeAlertDismissed ? /* @__PURE__ */ jsx(CpslAlert, { variant: "error", filled: true, children: /* @__PURE__ */ jsxs(Fragment, { children: [
150
+ /* @__PURE__ */ jsx("span", { children: isProd ? /* @__PURE__ */ jsxs(Fragment, { children: [
145
151
  "This Para Modal is configured to run on-ramp services in ",
146
152
  /* @__PURE__ */ jsx("b", { children: "test mode" }),
147
153
  " only, for development purposes. If you are a user of ",
148
154
  appName,
149
155
  ", please contact support."
150
- ] }),
156
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
157
+ "On-ramp services are configured to run in ",
158
+ /* @__PURE__ */ jsx("b", { children: "test mode" }),
159
+ " only outside of the PROD environment."
160
+ ] }) }),
151
161
  /* @__PURE__ */ jsx(CloseButton, { onClick: () => setIsTestModeAlertDismissed(true), children: /* @__PURE__ */ jsx(CloseX, { icon: "x" }) })
152
162
  ] }) }) : null;
153
- }, [isTestModeAlertDismissed, appName, onRampConfig == null ? void 0 : onRampConfig.testMode, setIsTestModeAlertDismissed]);
163
+ }, [isTestModeAlertDismissed, appName, isTestMode, setIsTestModeAlertDismissed, (_e = client == null ? void 0 : client.ctx) == null ? void 0 : _e.env]);
154
164
  useEffect(() => {
155
165
  if (!!asset && !network && narrowedNetworks.length === 1) {
156
166
  setNetwork(narrowedNetworks[0]);
@@ -174,6 +184,7 @@ function AddFundsContextProvider({ tab, children }) {
174
184
  setFiatQuantity,
175
185
  activeWallet,
176
186
  onRampConfig,
187
+ isTestMode,
177
188
  settingsStep,
178
189
  TestModeAlert
179
190
  };
@@ -189,6 +200,7 @@ function AddFundsContextProvider({ tab, children }) {
189
200
  setFiatQuantity,
190
201
  activeWallet,
191
202
  onRampConfig,
203
+ isTestMode,
192
204
  settingsStep,
193
205
  TestModeAlert
194
206
  ]);
@@ -20,7 +20,7 @@ function AddFundsProvider() {
20
20
  const setOnRampStep = useModalStore((state) => state.setOnRampStep);
21
21
  const onRampConfig = useModalStore((state) => state.onRampConfig);
22
22
  const setOnRampPurchase = useModalStore((state) => state.setOnRampPurchase);
23
- const { asset, network, fiatQuantity, isProviderAllowed, tab, TestModeAlert } = useAddFunds();
23
+ const { asset, network, fiatQuantity, isProviderAllowed, tab, TestModeAlert, isTestMode } = useAddFunds();
24
24
  const { data: activeWallet } = useWallet();
25
25
  useEffect(() => {
26
26
  if (Object.values(isProviderAllowed).every((v) => !v)) {
@@ -57,7 +57,7 @@ function AddFundsProvider() {
57
57
  network,
58
58
  asset: asset || void 0,
59
59
  fiatQuantity,
60
- testMode: onRampConfig == null ? void 0 : onRampConfig.testMode
60
+ testMode: isTestMode
61
61
  }
62
62
  });
63
63
  setOnRampPurchase(__spreadProps(__spreadValues({}, newOnRampPurchase), { fiat: "USD" }));
@@ -74,7 +74,9 @@ export interface ParaModalProps {
74
74
  */
75
75
  logo?: string;
76
76
  /**
77
- * Whether or not to run configured on-ramp providers in test mode.
77
+ * Whether to run configured on-ramp providers in test mode in the PROD environment.
78
+ *
79
+ * On-ramp and off-ramp widgets will always run in test mode outside of PROD.
78
80
  */
79
81
  onRampTestMode?: boolean;
80
82
  /**
@@ -1,13 +1,15 @@
1
1
  "use client";
2
2
  import {
3
- __async
3
+ __async,
4
+ __spreadProps,
5
+ __spreadValues
4
6
  } from "../../../chunk-MMUBH76A.js";
5
7
  import { useQuery } from "@tanstack/react-query";
6
- import { useRef, useEffect } from "react";
8
+ import { useRef, useEffect, useMemo } from "react";
7
9
  import { useStore } from "../../stores/useStore.js";
8
10
  import { useInternalClient } from "../utils/useInternalClient.js";
9
11
  import { useIsFullyLoggedIn } from "./useIsFullyLoggedIn.js";
10
- import { filterProfileBalance } from "@getpara/shared";
12
+ import { filterProfileBalance, formatCurrency } from "@getpara/shared";
11
13
  const useProfileBalance = (options) => {
12
14
  var _a, _b, _c;
13
15
  const client = useInternalClient();
@@ -17,6 +19,7 @@ const useProfileBalance = (options) => {
17
19
  return (_a2 = state.modalConfig) == null ? void 0 : _a2.balances;
18
20
  });
19
21
  const refs = useStore((state) => state.refs);
22
+ const balanceOverrides = useStore((state) => state.balanceOverrides);
20
23
  const isComprehensive = (_a = options == null ? void 0 : options.isComprehensive) != null ? _a : false;
21
24
  const previousTriggerRef = useRef(options == null ? void 0 : options.refetchTrigger);
22
25
  const shouldRefetchRef = useRef(false);
@@ -28,8 +31,10 @@ const useProfileBalance = (options) => {
28
31
  previousTriggerRef.current = options == null ? void 0 : options.refetchTrigger;
29
32
  }
30
33
  }, [options == null ? void 0 : options.refetchTrigger]);
31
- return useQuery({
32
- enabled: isSuccess && !!client,
34
+ const requiresOverrides = (config == null ? void 0 : config.useBalanceOverrides) && (config == null ? void 0 : config.displayType) === "AGGREGATED";
35
+ const shouldUseOverrides = requiresOverrides && !!balanceOverrides;
36
+ const query = useQuery({
37
+ enabled: isSuccess && !!client && (!requiresOverrides || !!balanceOverrides),
33
38
  queryKey: [
34
39
  "useProfileBalance",
35
40
  isFullyLoggedIn != null ? isFullyLoggedIn : null,
@@ -56,9 +61,31 @@ const useProfileBalance = (options) => {
56
61
  isInitialLoadRef.current = false;
57
62
  return isComprehensive ? profileBalance : filterProfileBalance(profileBalance, config || { displayType: "AGGREGATED" });
58
63
  }),
59
- // We handle refetch manually
60
64
  refetchOnWindowFocus: false
61
65
  });
66
+ const data = useMemo(() => {
67
+ var _a2;
68
+ const raw = query.data;
69
+ if (!raw || !shouldUseOverrides) return raw;
70
+ const overrides = balanceOverrides.value;
71
+ const result = structuredClone(raw);
72
+ for (const [walletAddress, override] of Object.entries(overrides)) {
73
+ const wallet = result.wallets.find((w) => w.address === walletAddress);
74
+ if (((_a2 = wallet == null ? void 0 : wallet.value) == null ? void 0 : _a2.value) === void 0) continue;
75
+ if (typeof override !== "number" || !Number.isFinite(override)) continue;
76
+ wallet.value.value = override;
77
+ wallet.formattedValue = formatCurrency(wallet.value);
78
+ }
79
+ if (result.value) {
80
+ result.value.value = result.wallets.reduce((sum, wallet) => {
81
+ var _a3, _b2;
82
+ return sum + ((_b2 = (_a3 = wallet.value) == null ? void 0 : _a3.value) != null ? _b2 : 0);
83
+ }, 0);
84
+ result.formattedValue = formatCurrency(result.value);
85
+ }
86
+ return result;
87
+ }, [query.data, shouldUseOverrides, balanceOverrides == null ? void 0 : balanceOverrides.version]);
88
+ return __spreadProps(__spreadValues({}, query), { data: data != null ? data : void 0 });
62
89
  };
63
90
  export {
64
91
  useProfileBalance
@@ -1,3 +1,4 @@
1
1
  export { useClient } from './useClient.js';
2
2
  export { useModal } from './useModal.js';
3
3
  export { useWalletState } from './useWalletState.js';
4
+ export { useSetBalanceOverrides } from './useSetBalanceOverrides.js';
@@ -3,8 +3,10 @@ import "../../../chunk-MMUBH76A.js";
3
3
  import { useClient } from "./useClient.js";
4
4
  import { useModal } from "./useModal.js";
5
5
  import { useWalletState } from "./useWalletState.js";
6
+ import { useSetBalanceOverrides } from "./useSetBalanceOverrides.js";
6
7
  export {
7
8
  useClient,
8
9
  useModal,
10
+ useSetBalanceOverrides,
9
11
  useWalletState
10
12
  };
@@ -0,0 +1,34 @@
1
+ import { BalanceOverrides } from '@getpara/shared';
2
+ /**
3
+ * Returns a function to set the balance overrides, similar to React `setState`. Use this once your balance overrides are available to modify or replace the displayed wallet balances in the Para Modal. Both the individual wallet and the cumulative total balance will be modified.
4
+ *
5
+ * If you have set `useBalanceOverrides` to `true` in your configuration, you must call this function at least once with a non-null value for balances to be displayed.
6
+ *
7
+ * **Behavior notes:**
8
+ * - Both numeric `value.value` and `formattedValue` strings are recalculated after overrides.
9
+ * - Wallets not present in the override map retain their original values.
10
+ * - Overrides are re-applied whenever the underlying balance data refetches; they do not need to be re-set.
11
+ * - Non-finite values (`NaN`, `Infinity`) are silently skipped.
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * import { useAccount, useSetBalanceOverrides } from '@getpara/react-sdk';
16
+ *
17
+ * const ComponentWithinParaProvider = () => {
18
+ * const setBalanceOverrides = useSetBalanceOverrides();
19
+ * const { embedded: embeddedWallets } = useAccount();
20
+ *
21
+ * useEffect(() => {
22
+ * const interval = setInterval(async () => {
23
+ * const balances = await getBalancesFromYourApi({ addresses: embeddedWallets.map(w => w.address!) });
24
+ *
25
+ * // Pass a Record<string, number> mapping wallet addresses to their new balance values:
26
+ * setBalanceOverrides(balances);
27
+ * }, 10000);
28
+ * return () => clearInterval(interval);
29
+ * }, [embeddedWallets, setBalanceOverrides]);
30
+ *
31
+ * // ...
32
+ * ```
33
+ */
34
+ export declare const useSetBalanceOverrides: () => (balanceOverrides: BalanceOverrides) => void;
@@ -0,0 +1,12 @@
1
+ "use client";
2
+ import "../../../chunk-MMUBH76A.js";
3
+ import { useStore } from "../../stores/useStore.js";
4
+ const useSetBalanceOverrides = () => {
5
+ const setBalanceOverrides = useStore((state) => state.setBalanceOverrides);
6
+ return (balanceOverrides) => {
7
+ setBalanceOverrides(balanceOverrides);
8
+ };
9
+ };
10
+ export {
11
+ useSetBalanceOverrides
12
+ };
@@ -18,7 +18,17 @@ const createModalSlice = (set) => ({
18
18
  refs: {
19
19
  openedToStep: createRef(),
20
20
  balancesInvalidationTime: createRef()
21
- }
21
+ },
22
+ balanceOverrides: null,
23
+ setBalanceOverrides: (balanceOverrides) => set((state) => {
24
+ var _a, _b;
25
+ return {
26
+ balanceOverrides: balanceOverrides ? {
27
+ version: ((_b = (_a = state.balanceOverrides) == null ? void 0 : _a.version) != null ? _b : 0) + 1,
28
+ value: balanceOverrides
29
+ } : null
30
+ };
31
+ })
22
32
  });
23
33
  export {
24
34
  createModalSlice
@@ -7,6 +7,12 @@ import { ParaSolanaProvider, SolanaExternalWalletContextType, WalletList as Sola
7
7
  import { ModalStep, ParaModalProps } from '../../modal/index.js';
8
8
  import { OAuthLogoVariantType } from '../../modal/types/modalProps.js';
9
9
  import { type TExternalWallet } from '@getpara/react-common';
10
+ import { BalanceOverrides } from '@getpara/shared';
11
+ /** Balance overrides with a version field for React Query cache invalidation (version must be serializable). */
12
+ export type BalanceOverridesWithVersion = {
13
+ version: number;
14
+ value: BalanceOverrides;
15
+ };
10
16
  export type FarcasterMiniAppConfig = {
11
17
  /**
12
18
  * Whether to disable automatic sign-in via the Farcaster user's existing miniapp wallet(s).
@@ -40,6 +46,8 @@ export interface ModalSlice {
40
46
  openedToStep: MutableRefObject<ModalStep | null>;
41
47
  balancesInvalidationTime: MutableRefObject<number | null>;
42
48
  };
49
+ balanceOverrides: BalanceOverridesWithVersion | null;
50
+ setBalanceOverrides: (_: BalanceOverrides | null) => void;
43
51
  }
44
52
  export interface WalletSlice {
45
53
  rpcUrl?: string;
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@getpara/react-sdk-lite",
3
- "version": "2.9.0",
3
+ "version": "2.10.0",
4
4
  "bin": {
5
5
  "setup-para": "dist/cli/cli.mjs"
6
6
  },
7
7
  "dependencies": {
8
- "@getpara/react-common": "2.9.0",
9
- "@getpara/react-components": "2.9.0",
10
- "@getpara/web-sdk": "2.9.0",
8
+ "@getpara/react-common": "2.10.0",
9
+ "@getpara/react-components": "2.10.0",
10
+ "@getpara/web-sdk": "2.10.0",
11
11
  "date-fns": "^3.6.0",
12
12
  "framer-motion": "^11.3.31",
13
13
  "libphonenumber-js": "^1.11.7",
@@ -16,9 +16,9 @@
16
16
  "zustand-sync-tabs": "^0.2.2"
17
17
  },
18
18
  "devDependencies": {
19
- "@getpara/cosmos-wallet-connectors": "2.9.0",
20
- "@getpara/evm-wallet-connectors": "2.9.0",
21
- "@getpara/solana-wallet-connectors": "2.9.0",
19
+ "@getpara/cosmos-wallet-connectors": "2.10.0",
20
+ "@getpara/evm-wallet-connectors": "2.10.0",
21
+ "@getpara/solana-wallet-connectors": "2.10.0",
22
22
  "@tanstack/react-query": "^5.74.0",
23
23
  "@testing-library/dom": "^10.4.0",
24
24
  "@testing-library/react": "^16.3.0",
@@ -38,7 +38,7 @@
38
38
  "package.json",
39
39
  "styles.css"
40
40
  ],
41
- "gitHead": "672cc943bc57cbeced8e79127c52a4fab0af4aed",
41
+ "gitHead": "8da2c51cc91f021acbc2ec7373b9ca0638fc840a",
42
42
  "main": "dist/index.js",
43
43
  "peerDependencies": {
44
44
  "@tanstack/react-query": ">=5.0.0",