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