@pollar/react 0.10.1 → 0.11.1-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1033,7 +1033,7 @@ var PollarModalFooter = () => {
1033
1033
  /* @__PURE__ */ jsx("span", { className: "pollar-footer-name", children: "Pollar" }),
1034
1034
  /* @__PURE__ */ jsxs("span", { className: "pollar-footer-version", children: [
1035
1035
  "v",
1036
- "0.10.1"
1036
+ "0.11.1-rc.1"
1037
1037
  ] })
1038
1038
  ] })
1039
1039
  ] });
@@ -2052,6 +2052,29 @@ function authStateToStatus(step) {
2052
2052
  if (error.includes(step)) return "ERROR";
2053
2053
  return "NONE";
2054
2054
  }
2055
+ function buildModalCssVars(theme, accentColor) {
2056
+ const isDark = theme === "dark";
2057
+ return {
2058
+ "--pollar-accent": accentColor,
2059
+ "--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
2060
+ "--pollar-border": isDark ? "#374151" : "#e5e7eb",
2061
+ "--pollar-text": isDark ? "#ffffff" : "#111827",
2062
+ "--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
2063
+ "--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
2064
+ "--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
2065
+ "--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
2066
+ "--pollar-error-text": isDark ? "#f87171" : "#dc2626",
2067
+ "--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
2068
+ "--pollar-buttons-border-radius": "6px",
2069
+ "--pollar-buttons-height": "44px",
2070
+ "--pollar-input-height": "44px",
2071
+ "--pollar-input-border-radius": "0.5rem",
2072
+ "--pollar-card-border-radius": "10px",
2073
+ "--pollar-modal-padding": "2rem",
2074
+ "--pollar-modal-heading-size": "1.375rem",
2075
+ "--pollar-modal-subtitle-size": "0.9rem"
2076
+ };
2077
+ }
2055
2078
  function LoginModalTemplate({
2056
2079
  theme,
2057
2080
  accentColor,
@@ -2078,7 +2101,6 @@ function LoginModalTemplate({
2078
2101
  }) {
2079
2102
  const [showPasskeyChooser, setShowPasskeyChooser] = useState(false);
2080
2103
  const [activeGroup, setActiveGroup] = useState(null);
2081
- const isDark = theme === "dark";
2082
2104
  const enabledSocial = Object.entries(providers).filter(([, enabled]) => enabled);
2083
2105
  const rootAdapters = walletAdapters.filter((a) => !a.meta.group);
2084
2106
  const walletGroups = walletAdapters.filter((a) => a.meta.group).reduce((acc, a) => {
@@ -2089,26 +2111,7 @@ function LoginModalTemplate({
2089
2111
  return acc;
2090
2112
  }, []);
2091
2113
  const activeGroupAdapters = walletGroups.find((g) => g.label === activeGroup)?.adapters ?? [];
2092
- const cssVars = {
2093
- "--pollar-accent": accentColor,
2094
- "--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
2095
- "--pollar-border": isDark ? "#374151" : "#e5e7eb",
2096
- "--pollar-text": isDark ? "#ffffff" : "#111827",
2097
- "--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
2098
- "--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
2099
- "--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
2100
- "--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
2101
- "--pollar-error-text": isDark ? "#f87171" : "#dc2626",
2102
- "--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
2103
- "--pollar-buttons-border-radius": "6px",
2104
- "--pollar-buttons-height": "44px",
2105
- "--pollar-input-height": "44px",
2106
- "--pollar-input-border-radius": "0.5rem",
2107
- "--pollar-card-border-radius": "10px",
2108
- "--pollar-modal-padding": "2rem",
2109
- "--pollar-modal-heading-size": "1.375rem",
2110
- "--pollar-modal-subtitle-size": "0.9rem"
2111
- };
2114
+ const cssVars = buildModalCssVars(theme, accentColor);
2112
2115
  const status = authStateToStatus(authState.step);
2113
2116
  const isLoading = status === "LOADING";
2114
2117
  const isEmailCodeError = authState.step === "error" && (authState.errorCode === AUTH_ERROR_CODES.EMAIL_CODE_EXPIRED || authState.errorCode === AUTH_ERROR_CODES.EMAIL_CODE_INVALID);
@@ -2283,6 +2286,46 @@ function LoginModalTemplate({
2283
2286
  /* @__PURE__ */ jsx(PollarModalFooter, {})
2284
2287
  ] });
2285
2288
  }
2289
+ function LoginModalStatus({
2290
+ status,
2291
+ theme,
2292
+ accentColor,
2293
+ logoUrl,
2294
+ appName,
2295
+ onRetry,
2296
+ onCancel
2297
+ }) {
2298
+ const cssVars = buildModalCssVars(theme, accentColor);
2299
+ return /* @__PURE__ */ jsxs("div", { className: "pollar-modal-card pollar-modal", style: cssVars, onClick: (e) => e.stopPropagation(), children: [
2300
+ /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-close-btn", onClick: onCancel, "aria-label": "Close", children: /* @__PURE__ */ jsx(
2301
+ "svg",
2302
+ {
2303
+ width: "18",
2304
+ height: "18",
2305
+ viewBox: "0 0 24 24",
2306
+ fill: "none",
2307
+ stroke: "currentColor",
2308
+ strokeWidth: "2.5",
2309
+ strokeLinecap: "round",
2310
+ strokeLinejoin: "round",
2311
+ children: /* @__PURE__ */ jsx("path", { d: "M18 6L6 18M6 6l12 12" })
2312
+ }
2313
+ ) }),
2314
+ /* @__PURE__ */ jsxs("div", { className: "pollar-header", children: [
2315
+ /* @__PURE__ */ jsx("div", { className: "pollar-logo-wrap", children: /* @__PURE__ */ jsx("img", { src: logoUrl ?? LOGO_POLLAR, alt: "Logo", className: "pollar-logo" }) }),
2316
+ /* @__PURE__ */ jsx("h2", { className: "pollar-title", children: appName }),
2317
+ /* @__PURE__ */ jsx("p", { className: "pollar-subtitle", children: "Log in or sign up" })
2318
+ ] }),
2319
+ status === "loading" ? /* @__PURE__ */ jsxs("div", { className: "pollar-loading-block", children: [
2320
+ /* @__PURE__ */ jsx("div", { className: "pollar-spinner" }),
2321
+ /* @__PURE__ */ jsx("span", { children: "Loading..." })
2322
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "pollar-wallet-section", children: [
2323
+ /* @__PURE__ */ jsx("p", { className: "pollar-modal-error", children: "Could not load sign-in options. Check your connection and try again." }),
2324
+ /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-btn-primary", onClick: onRetry, children: "Try again" })
2325
+ ] }),
2326
+ /* @__PURE__ */ jsx(PollarModalFooter, {})
2327
+ ] });
2328
+ }
2286
2329
  function PrivyLoginSubmodal({
2287
2330
  adapter,
2288
2331
  theme,
@@ -2439,7 +2482,7 @@ function PrivyLoginSubmodal({
2439
2482
  }
2440
2483
  function LoginModal({ onClose }) {
2441
2484
  const [email, setEmail] = useState("");
2442
- const { getClient, styles, appConfig: config } = usePollar();
2485
+ const { getClient, styles, appConfig: config, configStatus, retryConfig } = usePollar();
2443
2486
  const [authState, setAuthState] = useState(() => getClient().getAuthState());
2444
2487
  const walletAdapters = useMemo(() => getClient().listWalletAdapters(), [getClient]);
2445
2488
  const [codeInputKey, setCodeInputKey] = useState(0);
@@ -2525,7 +2568,18 @@ function LoginModal({ onClose }) {
2525
2568
  getClient().login({ provider });
2526
2569
  }
2527
2570
  }
2528
- return /* @__PURE__ */ jsx("div", { className: "pollar-overlay", onClick: handleClose, children: interactiveAdapter ? /* @__PURE__ */ jsx(
2571
+ return /* @__PURE__ */ jsx("div", { className: "pollar-overlay", onClick: handleClose, children: configStatus !== "ready" ? /* @__PURE__ */ jsx(
2572
+ LoginModalStatus,
2573
+ {
2574
+ status: configStatus === "error" ? "error" : "loading",
2575
+ theme,
2576
+ accentColor,
2577
+ logoUrl: logoUrl ?? null,
2578
+ appName: config.application?.name ?? "Pollar",
2579
+ onRetry: retryConfig,
2580
+ onCancel: handleClose
2581
+ }
2582
+ ) : interactiveAdapter ? /* @__PURE__ */ jsx(
2529
2583
  PrivyLoginSubmodal,
2530
2584
  {
2531
2585
  adapter: interactiveAdapter,
@@ -3878,7 +3932,7 @@ function SendModal({ onClose }) {
3878
3932
  []
3879
3933
  );
3880
3934
  const balanceData = walletBalance.step === "loaded" ? walletBalance.data : null;
3881
- const allAssets = balanceData?.balances ?? [];
3935
+ const allAssets = (balanceData?.balances ?? []).filter((b) => b.chain === void 0 || b.chain === "STELLAR");
3882
3936
  const sortedAssets = [
3883
3937
  ...allAssets.filter((b) => b.enabledInApp),
3884
3938
  ...allAssets.filter((b) => !b.enabledInApp && (b.type === "native" || parseFloat(b.balance) > 0))
@@ -4383,7 +4437,9 @@ function SwapModal({ onClose }) {
4383
4437
  const balances = walletBalance.step === "loaded" ? walletBalance.data.balances : [];
4384
4438
  const assetRecords = enabledAssets.step === "loaded" ? enabledAssets.data.assets : [];
4385
4439
  const isLoadingData = walletBalance.step === "loading" || enabledAssets.step === "loading";
4386
- const sellOptions = balances.filter((b) => b.type === "native" || !b.trustlineRemoved).map((b) => ({ ref: toRef(b), code: b.code, issuer: b.issuer, available: b.available, enabledInApp: b.enabledInApp }));
4440
+ const sellOptions = balances.filter(
4441
+ (b) => b.type != null && (b.type === "native" || !b.trustlineRemoved)
4442
+ ).map((b) => ({ ref: toRef(b), code: b.code, issuer: b.issuer, available: b.available, enabledInApp: b.enabledInApp }));
4387
4443
  const buyKeyOfSell = selectedSell ? `${selectedSell.code}:${selectedSell.issuer ?? "native"}` : "";
4388
4444
  const optKey = (o) => `${o.code}:${o.issuer ?? "native"}`;
4389
4445
  const enabledBuy = assetRecords.map((a) => ({
@@ -5629,11 +5685,23 @@ function cropAddress2(address) {
5629
5685
  if (address.length <= 16) return address;
5630
5686
  return `${address.slice(0, 8)}...${address.slice(-8)}`;
5631
5687
  }
5632
- function BalanceItem({ record }) {
5688
+ var CHAIN_TAG = {
5689
+ STELLAR: { label: "Stellar", color: "#7d00ff" },
5690
+ POLYGON: { label: "Polygon", color: "#8247e5" },
5691
+ SOLANA: { label: "Solana", color: "#14f195" }
5692
+ };
5693
+ function ChainTag({ chain }) {
5694
+ const tag = CHAIN_TAG[chain] ?? { label: chain, color: "#6b7280" };
5695
+ return /* @__PURE__ */ jsx("span", { className: "pollar-bal-chain-tag", style: { "--pollar-chain-color": tag.color }, children: tag.label });
5696
+ }
5697
+ function BalanceItem({ record, showChain }) {
5633
5698
  const balanceDiffers = record.balance !== record.available;
5634
5699
  return /* @__PURE__ */ jsxs("div", { className: "pollar-bal-item", children: [
5635
5700
  /* @__PURE__ */ jsxs("div", { className: "pollar-bal-asset-info", children: [
5636
- /* @__PURE__ */ jsx("span", { className: "pollar-bal-asset", children: record.code }),
5701
+ /* @__PURE__ */ jsxs("span", { className: "pollar-bal-asset-code-row", children: [
5702
+ /* @__PURE__ */ jsx("span", { className: "pollar-bal-asset", children: record.code }),
5703
+ showChain && record.chain && /* @__PURE__ */ jsx(ChainTag, { chain: record.chain })
5704
+ ] }),
5637
5705
  record.issuer && /* @__PURE__ */ jsxs("span", { className: "pollar-bal-issuer", children: [
5638
5706
  /* @__PURE__ */ jsx("span", { className: "pollar-bal-issuer-addr", children: cropAddress2(record.issuer) }),
5639
5707
  /* @__PURE__ */ jsx(CopyButton, { value: record.issuer, label: "Copy issuer address", className: "pollar-copy-btn-sm" })
@@ -5730,7 +5798,7 @@ function WalletBalanceModalTemplate({
5730
5798
  "."
5731
5799
  ] }),
5732
5800
  data?.exists && data.balances.length === 0 && /* @__PURE__ */ jsx("div", { className: "pollar-modal-empty", children: "No balances found." }),
5733
- data?.exists && data.balances.length > 0 && /* @__PURE__ */ jsx("div", { className: "pollar-bal-list", children: data.balances.map((b) => /* @__PURE__ */ jsx(BalanceItem, { record: b }, b.code + (b.issuer ?? ""))) }),
5801
+ data?.exists && data.balances.length > 0 && /* @__PURE__ */ jsx("div", { className: "pollar-bal-list", children: data.balances.map((b) => /* @__PURE__ */ jsx(BalanceItem, { record: b, showChain: data.multichain === true }, (b.chain ?? "") + b.code + (b.issuer ?? ""))) }),
5734
5802
  /* @__PURE__ */ jsx(PollarModalFooter, {})
5735
5803
  ] });
5736
5804
  }
@@ -5847,6 +5915,11 @@ function PollarProvider({
5847
5915
  const [walletBalance, setWalletBalance] = useState({ step: "idle" });
5848
5916
  const [enabledAssets, setEnabledAssets] = useState({ step: "idle" });
5849
5917
  const [resolvedConfig, setResolvedConfig] = useState(() => appConfigProp ?? DEFAULT_APP_CONFIG);
5918
+ const [configStatus, setConfigStatus] = useState(
5919
+ appConfigProp !== void 0 ? "ready" : "loading"
5920
+ );
5921
+ const [configRetry, setConfigRetry] = useState(0);
5922
+ const retryConfig = useCallback(() => setConfigRetry((n) => n + 1), []);
5850
5923
  useEffect(() => {
5851
5924
  return pollarClient.onTransactionStateChange(setTransaction);
5852
5925
  }, [pollarClient]);
@@ -5910,18 +5983,29 @@ function PollarProvider({
5910
5983
  setModalErrorLogger(pollarClient.getLogger());
5911
5984
  }, [pollarClient]);
5912
5985
  useEffect(() => {
5913
- if (appConfigProp !== void 0) return;
5986
+ if (appConfigProp !== void 0) {
5987
+ setConfigStatus("ready");
5988
+ return;
5989
+ }
5914
5990
  let cancelled = false;
5991
+ setConfigStatus("loading");
5915
5992
  pollarClient.getAppConfig().then((fetched) => {
5916
- if (cancelled || !fetched) return;
5993
+ if (cancelled) return;
5994
+ if (!fetched) {
5995
+ setConfigStatus("error");
5996
+ return;
5997
+ }
5917
5998
  setResolvedConfig(fetched);
5999
+ setConfigStatus("ready");
5918
6000
  }).catch((err) => {
6001
+ if (cancelled) return;
5919
6002
  pollarClient.getLogger().error("[PollarProvider] getAppConfig failed", err);
6003
+ setConfigStatus("error");
5920
6004
  });
5921
6005
  return () => {
5922
6006
  cancelled = true;
5923
6007
  };
5924
- }, [pollarClient, appConfigProp]);
6008
+ }, [pollarClient, appConfigProp, configRetry]);
5925
6009
  const [loginModalOpen, setLoginModalOpen] = useState(false);
5926
6010
  const [transactionModalOpen, setTransactionModalOpen] = useState(false);
5927
6011
  const [kycModalOpen, setKycModalOpen] = useState(false);
@@ -6023,6 +6107,8 @@ function PollarProvider({
6023
6107
  // config
6024
6108
  appConfig: resolvedConfig,
6025
6109
  styles,
6110
+ configStatus,
6111
+ retryConfig,
6026
6112
  adapters
6027
6113
  };
6028
6114
  }, [
@@ -6039,6 +6125,8 @@ function PollarProvider({
6039
6125
  refreshAssets,
6040
6126
  networkState,
6041
6127
  resolvedConfig,
6128
+ configStatus,
6129
+ retryConfig,
6042
6130
  adapters
6043
6131
  ]);
6044
6132
  return /* @__PURE__ */ jsxs(PollarContext.Provider, { value: contextValue, children: [