@pollar/react 0.9.0-rc.0 → 0.9.0-rc.2

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
@@ -1004,6 +1004,10 @@ var require_QRCode = __commonJS({
1004
1004
  var LOGO_POLLAR = "https://pollar.xyz/assets/logo_pollar.png";
1005
1005
  var LOGO_FREIGHTER = "https://pollar.xyz/assets/logo_freighter.png";
1006
1006
  var LOGO_ALBEDO = "https://pollar.xyz/assets/logo_albedo.svg";
1007
+ var _modalLog = console;
1008
+ function setModalErrorLogger(logger) {
1009
+ _modalLog = logger;
1010
+ }
1007
1011
  var ModalErrorBoundary = class extends react.Component {
1008
1012
  constructor() {
1009
1013
  super(...arguments);
@@ -1013,7 +1017,7 @@ var ModalErrorBoundary = class extends react.Component {
1013
1017
  return { crashed: true };
1014
1018
  }
1015
1019
  componentDidCatch(error) {
1016
- console.error("[PollarProvider] Modal crashed:", error);
1020
+ _modalLog.error("[PollarProvider] Modal crashed:", error);
1017
1021
  }
1018
1022
  render() {
1019
1023
  if (this.state.crashed) {
@@ -1031,7 +1035,7 @@ var PollarModalFooter = () => {
1031
1035
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-footer-name", children: "Pollar" }),
1032
1036
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-footer-version", children: [
1033
1037
  "v",
1034
- "0.9.0-rc.0"
1038
+ "0.9.0-rc.2"
1035
1039
  ] })
1036
1040
  ] })
1037
1041
  ] });
@@ -1262,6 +1266,104 @@ function DistributionRulesModal({ onClose }) {
1262
1266
  }
1263
1267
  ) });
1264
1268
  }
1269
+ function cropAddress(address) {
1270
+ if (address.length <= 16) return address;
1271
+ return `${address.slice(0, 8)}...${address.slice(-8)}`;
1272
+ }
1273
+ function AssetItem({ record }) {
1274
+ const established = record.trustlineEstablished;
1275
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-asset-item", children: [
1276
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-asset-info", children: [
1277
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-asset-code", children: record.code }),
1278
+ record.name && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-asset-name", children: record.name })
1279
+ ] }),
1280
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `pollar-asset-trustline${established ? " established" : ""}`, children: established ? "Trustline active" : "Needs trustline" })
1281
+ ] });
1282
+ }
1283
+ function EnabledAssetsModalTemplate({
1284
+ theme,
1285
+ accentColor,
1286
+ enabledAssets,
1287
+ walletAddress,
1288
+ onRefresh,
1289
+ onClose
1290
+ }) {
1291
+ const isDark = theme === "dark";
1292
+ const cssVars = {
1293
+ "--pollar-accent": accentColor,
1294
+ "--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
1295
+ "--pollar-border": isDark ? "#374151" : "#e5e7eb",
1296
+ "--pollar-text": isDark ? "#ffffff" : "#111827",
1297
+ "--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
1298
+ "--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
1299
+ "--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
1300
+ "--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
1301
+ "--pollar-error-text": isDark ? "#f87171" : "#dc2626",
1302
+ "--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
1303
+ "--pollar-buttons-border-radius": "6px",
1304
+ "--pollar-buttons-height": "44px",
1305
+ "--pollar-input-height": "44px",
1306
+ "--pollar-input-border-radius": "0.5rem",
1307
+ "--pollar-card-border-radius": "10px"
1308
+ };
1309
+ const isLoading = enabledAssets.step === "loading";
1310
+ const data = enabledAssets.step === "loaded" ? enabledAssets.data : null;
1311
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-card pollar-asset-modal", "data-theme": theme, style: cssVars, onClick: (e) => e.stopPropagation(), children: [
1312
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
1313
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Enabled Assets" }),
1314
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
1315
+ /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-modal-refresh-btn", onClick: onRefresh, disabled: isLoading, children: [
1316
+ /* @__PURE__ */ jsxRuntime.jsxs(
1317
+ "svg",
1318
+ {
1319
+ className: `pollar-modal-refresh-icon${isLoading ? " spinning" : ""}`,
1320
+ width: "13",
1321
+ height: "13",
1322
+ viewBox: "0 0 13 13",
1323
+ fill: "none",
1324
+ "aria-hidden": true,
1325
+ children: [
1326
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M11.5 6.5a5 5 0 11-1.5-3.536", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }),
1327
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 1v3h-3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
1328
+ ]
1329
+ }
1330
+ ),
1331
+ "Refresh"
1332
+ ] }),
1333
+ /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-modal-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2 2l12 12M14 2L2 14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) })
1334
+ ] })
1335
+ ] }),
1336
+ walletAddress && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-asset-address", children: cropAddress(walletAddress) }),
1337
+ isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "Loading\u2026" }),
1338
+ enabledAssets.step === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: enabledAssets.message }),
1339
+ data && !data.exists && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-empty", children: [
1340
+ "Account not found on ",
1341
+ data.network,
1342
+ "."
1343
+ ] }),
1344
+ data && data.assets.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No assets enabled for this application." }),
1345
+ data && data.assets.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-asset-list", children: data.assets.map((a) => /* @__PURE__ */ jsxRuntime.jsx(AssetItem, { record: a }, a.code + (a.issuer ?? ""))) }),
1346
+ /* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
1347
+ ] });
1348
+ }
1349
+ function EnabledAssetsModal({ onClose }) {
1350
+ const { enabledAssets, refreshAssets, walletAddress, styles } = usePollar();
1351
+ const { theme = "light", accentColor = "#005DB4" } = styles;
1352
+ react.useEffect(() => {
1353
+ void refreshAssets();
1354
+ }, [refreshAssets]);
1355
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
1356
+ EnabledAssetsModalTemplate,
1357
+ {
1358
+ theme,
1359
+ accentColor,
1360
+ enabledAssets,
1361
+ walletAddress,
1362
+ onRefresh: () => refreshAssets(),
1363
+ onClose
1364
+ }
1365
+ ) });
1366
+ }
1265
1367
  var STATUS_CONFIG = {
1266
1368
  none: { label: "Not started", color: "#6b7280", dot: false },
1267
1369
  pending: { label: "Pending review", color: "#f59e0b", dot: true },
@@ -1812,6 +1914,9 @@ function LoginModal({ onClose }) {
1812
1914
  setCodeInputKey((k) => k + 1);
1813
1915
  }
1814
1916
  if (next.step === "authenticated") {
1917
+ if (autoCloseTimer.current !== null) {
1918
+ clearTimeout(autoCloseTimer.current);
1919
+ }
1815
1920
  autoCloseTimer.current = setTimeout(() => {
1816
1921
  autoCloseTimer.current = null;
1817
1922
  onCloseRef.current();
@@ -3469,7 +3574,7 @@ function formatBalance2(balance) {
3469
3574
  const n = parseFloat(balance);
3470
3575
  return isNaN(n) ? balance : n.toLocaleString(void 0, { maximumFractionDigits: 7 });
3471
3576
  }
3472
- function cropAddress(address) {
3577
+ function cropAddress2(address) {
3473
3578
  if (address.length <= 16) return address;
3474
3579
  return `${address.slice(0, 8)}...${address.slice(-8)}`;
3475
3580
  }
@@ -3539,7 +3644,7 @@ function WalletBalanceModalTemplate({
3539
3644
  /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-modal-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2 2l12 12M14 2L2 14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) })
3540
3645
  ] })
3541
3646
  ] }),
3542
- walletAddress && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-bal-address", children: cropAddress(walletAddress) }),
3647
+ walletAddress && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-bal-address", children: cropAddress2(walletAddress) }),
3543
3648
  isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "Loading\u2026" }),
3544
3649
  walletBalance.step === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: walletBalance.message }),
3545
3650
  data && !data.exists && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-empty", children: [
@@ -3652,6 +3757,7 @@ function PollarProvider({
3652
3757
  const [txHistory, setTxHistory] = react.useState({ step: "idle" });
3653
3758
  const [sessions, setSessions] = react.useState({ step: "idle" });
3654
3759
  const [walletBalance, setWalletBalance] = react.useState({ step: "idle" });
3760
+ const [enabledAssets, setEnabledAssets] = react.useState({ step: "idle" });
3655
3761
  const [resolvedConfig, setResolvedConfig] = react.useState(() => appConfigProp ?? DEFAULT_APP_CONFIG);
3656
3762
  react.useEffect(() => {
3657
3763
  return pollarClient.onTransactionStateChange(setTransaction);
@@ -3665,6 +3771,9 @@ function PollarProvider({
3665
3771
  react.useEffect(() => {
3666
3772
  return pollarClient.onWalletBalanceStateChange(setWalletBalance);
3667
3773
  }, [pollarClient]);
3774
+ react.useEffect(() => {
3775
+ return pollarClient.onEnabledAssetsStateChange(setEnabledAssets);
3776
+ }, [pollarClient]);
3668
3777
  react.useEffect(() => {
3669
3778
  return pollarClient.onNetworkStateChange((state) => {
3670
3779
  setNetworkState(state);
@@ -3685,6 +3794,9 @@ function PollarProvider({
3685
3794
  }
3686
3795
  });
3687
3796
  }, [pollarClient]);
3797
+ react.useEffect(() => {
3798
+ setModalErrorLogger(pollarClient.getLogger());
3799
+ }, [pollarClient]);
3688
3800
  react.useEffect(() => {
3689
3801
  if (appConfigProp !== void 0) return;
3690
3802
  let cancelled = false;
@@ -3692,7 +3804,7 @@ function PollarProvider({
3692
3804
  if (cancelled || !fetched) return;
3693
3805
  setResolvedConfig(fetched);
3694
3806
  }).catch((err) => {
3695
- console.error("[PollarProvider] getAppConfig failed", err);
3807
+ pollarClient.getLogger().error("[PollarProvider] getAppConfig failed", err);
3696
3808
  });
3697
3809
  return () => {
3698
3810
  cancelled = true;
@@ -3705,6 +3817,7 @@ function PollarProvider({
3705
3817
  const [rampModalOpen, setRampModalOpen] = react.useState(false);
3706
3818
  const [txHistoryModalOpen, setTxHistoryModalOpen] = react.useState(false);
3707
3819
  const [walletBalanceModalOpen, setWalletBalanceModalOpen] = react.useState(false);
3820
+ const [enabledAssetsModalOpen, setEnabledAssetsModalOpen] = react.useState(false);
3708
3821
  const [sendModalOpen, setSendModalOpen] = react.useState(false);
3709
3822
  const [receiveModalOpen, setReceiveModalOpen] = react.useState(false);
3710
3823
  const [sessionsModalOpen, setSessionsModalOpen] = react.useState(false);
@@ -3712,6 +3825,7 @@ function PollarProvider({
3712
3825
  const walletAddress = sessionState?.wallet?.address || "";
3713
3826
  const getClient = react.useCallback(() => pollarClient, [pollarClient]);
3714
3827
  const refreshWalletBalance = react.useCallback(() => pollarClient.refreshBalance(), [pollarClient, walletAddress]);
3828
+ const refreshAssets = react.useCallback(() => pollarClient.refreshAssets(), [pollarClient, walletAddress]);
3715
3829
  const renderWallets = ui?.renderWallets;
3716
3830
  const contextValue = react.useMemo(() => {
3717
3831
  const styles = resolvedConfig.styles ?? {};
@@ -3743,6 +3857,10 @@ function PollarProvider({
3743
3857
  walletBalance,
3744
3858
  refreshWalletBalance,
3745
3859
  openWalletBalanceModal: () => setWalletBalanceModalOpen(true),
3860
+ // enabled assets
3861
+ enabledAssets,
3862
+ refreshAssets,
3863
+ openEnabledAssetsModal: () => setEnabledAssetsModalOpen(true),
3746
3864
  // send / receive
3747
3865
  openSendModal: () => setSendModalOpen(true),
3748
3866
  openReceiveModal: () => setReceiveModalOpen(true),
@@ -3777,6 +3895,8 @@ function PollarProvider({
3777
3895
  sessions,
3778
3896
  walletBalance,
3779
3897
  refreshWalletBalance,
3898
+ enabledAssets,
3899
+ refreshAssets,
3780
3900
  networkState,
3781
3901
  resolvedConfig,
3782
3902
  adapters,
@@ -3798,6 +3918,7 @@ function PollarProvider({
3798
3918
  rampModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setRampModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(RampWidget, { onClose: () => setRampModalOpen(false) }) }),
3799
3919
  txHistoryModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setTxHistoryModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(TxHistoryModal, { onClose: () => setTxHistoryModalOpen(false) }) }),
3800
3920
  walletBalanceModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setWalletBalanceModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(WalletBalanceModal, { onClose: () => setWalletBalanceModalOpen(false) }) }),
3921
+ enabledAssetsModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setEnabledAssetsModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(EnabledAssetsModal, { onClose: () => setEnabledAssetsModalOpen(false) }) }),
3801
3922
  sendModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setSendModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(SendModal, { onClose: () => setSendModalOpen(false) }) }),
3802
3923
  receiveModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setReceiveModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(ReceiveModal, { onClose: () => setReceiveModalOpen(false) }) }),
3803
3924
  sessionsModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setSessionsModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(SessionsModal, { onClose: () => setSessionsModalOpen(false) }) }),
@@ -4248,6 +4369,8 @@ function WalletButton() {
4248
4369
 
4249
4370
  exports.DistributionRulesModal = DistributionRulesModal;
4250
4371
  exports.DistributionRulesModalTemplate = DistributionRulesModalTemplate;
4372
+ exports.EnabledAssetsModal = EnabledAssetsModal;
4373
+ exports.EnabledAssetsModalTemplate = EnabledAssetsModalTemplate;
4251
4374
  exports.KycModal = KycModal;
4252
4375
  exports.KycModalTemplate = KycModalTemplate;
4253
4376
  exports.KycStatus = KycStatus;