@pollar/react 0.10.1-rc.3 → 0.10.1-rc.5

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,11 +1033,53 @@ 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-rc.3"
1036
+ "0.10.1-rc.5"
1037
1037
  ] })
1038
1038
  ] })
1039
1039
  ] });
1040
1040
  };
1041
+ function CopyButton({ value, label = "Copy", className }) {
1042
+ const [copied, setCopied] = useState(false);
1043
+ const timerRef = useRef(null);
1044
+ useEffect(() => {
1045
+ return () => {
1046
+ if (timerRef.current !== null) clearTimeout(timerRef.current);
1047
+ };
1048
+ }, []);
1049
+ function handleCopy(e) {
1050
+ e.stopPropagation();
1051
+ if (!value || !navigator.clipboard) return;
1052
+ void navigator.clipboard.writeText(value).then(() => {
1053
+ setCopied(true);
1054
+ if (timerRef.current !== null) clearTimeout(timerRef.current);
1055
+ timerRef.current = setTimeout(() => {
1056
+ setCopied(false);
1057
+ timerRef.current = null;
1058
+ }, 1500);
1059
+ });
1060
+ }
1061
+ return /* @__PURE__ */ jsx(
1062
+ "button",
1063
+ {
1064
+ type: "button",
1065
+ className: `pollar-copy-btn${className ? ` ${className}` : ""}`,
1066
+ onClick: handleCopy,
1067
+ "aria-label": copied ? "Copied" : label,
1068
+ children: copied ? /* @__PURE__ */ jsx("svg", { width: "13", height: "13", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M3.5 7l2.5 2.5 4.5-5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) : /* @__PURE__ */ jsxs("svg", { width: "13", height: "13", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
1069
+ /* @__PURE__ */ jsx("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1.5", stroke: "currentColor", strokeWidth: "1.5" }),
1070
+ /* @__PURE__ */ jsx(
1071
+ "path",
1072
+ {
1073
+ d: "M3 9H2a1 1 0 01-1-1V2a1 1 0 011-1h6a1 1 0 011 1v1",
1074
+ stroke: "currentColor",
1075
+ strokeWidth: "1.5",
1076
+ strokeLinecap: "round"
1077
+ }
1078
+ )
1079
+ ] })
1080
+ }
1081
+ );
1082
+ }
1041
1083
  function ModalStatusBanner({ message, status, onCancel, onRetry }) {
1042
1084
  if (!message && status === "NONE") {
1043
1085
  return /* @__PURE__ */ jsx("div", { className: "pollar-status" });
@@ -2230,12 +2272,38 @@ function PrivyLoginSubmodal({
2230
2272
  fail(error);
2231
2273
  }
2232
2274
  }
2233
- const BackButton = ({ onClick }) => /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-back-btn", onClick, "aria-label": "Back", children: /* @__PURE__ */ jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M15 19l-7-7 7-7" }) }) });
2275
+ const BackButton = ({ onClick }) => /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-back-btn", onClick, "aria-label": "Back", children: /* @__PURE__ */ jsx(
2276
+ "svg",
2277
+ {
2278
+ width: "20",
2279
+ height: "20",
2280
+ viewBox: "0 0 24 24",
2281
+ fill: "none",
2282
+ stroke: "currentColor",
2283
+ strokeWidth: "2.5",
2284
+ strokeLinecap: "round",
2285
+ strokeLinejoin: "round",
2286
+ children: /* @__PURE__ */ jsx("path", { d: "M15 19l-7-7 7-7" })
2287
+ }
2288
+ ) });
2234
2289
  const showEmail = options.includes("email");
2235
2290
  const showGoogle = options.includes("google");
2236
2291
  const showGithub = options.includes("github");
2237
2292
  return /* @__PURE__ */ jsxs("div", { className: "pollar-modal-card pollar-modal", style: cssVars, onClick: (e) => e.stopPropagation(), children: [
2238
- /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-close-btn", onClick: onCancel, "aria-label": "Close", children: /* @__PURE__ */ jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M18 6L6 18M6 6l12 12" }) }) }),
2293
+ /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-close-btn", onClick: onCancel, "aria-label": "Close", children: /* @__PURE__ */ jsx(
2294
+ "svg",
2295
+ {
2296
+ width: "18",
2297
+ height: "18",
2298
+ viewBox: "0 0 24 24",
2299
+ fill: "none",
2300
+ stroke: "currentColor",
2301
+ strokeWidth: "2.5",
2302
+ strokeLinecap: "round",
2303
+ strokeLinejoin: "round",
2304
+ children: /* @__PURE__ */ jsx("path", { d: "M18 6L6 18M6 6l12 12" })
2305
+ }
2306
+ ) }),
2239
2307
  /* @__PURE__ */ jsxs("div", { className: "pollar-header", children: [
2240
2308
  /* @__PURE__ */ jsx("div", { className: "pollar-logo-wrap", children: /* @__PURE__ */ jsx("img", { src: logoUrl ?? LOGO_POLLAR, alt: "Logo", className: "pollar-logo" }) }),
2241
2309
  /* @__PURE__ */ jsx("h2", { className: "pollar-title", children: appName }),
@@ -2488,8 +2556,7 @@ function flattenInstructions(instr) {
2488
2556
  for (const [k, v] of Object.entries(instr)) {
2489
2557
  let value = "";
2490
2558
  if (typeof v === "string" || typeof v === "number") value = String(v);
2491
- else if (Array.isArray(v))
2492
- value = v.filter((x) => typeof x === "string" || typeof x === "number").join(", ");
2559
+ else if (Array.isArray(v)) value = v.filter((x) => typeof x === "string" || typeof x === "number").join(", ");
2493
2560
  else continue;
2494
2561
  if (!value) continue;
2495
2562
  out.push({ key: k, label: INSTRUCTION_LABELS[k] ?? k, value });
@@ -2514,6 +2581,7 @@ function RampWidgetTemplate({
2514
2581
  provider,
2515
2582
  txStatus,
2516
2583
  kycUrl,
2584
+ tosUrl,
2517
2585
  stellarTxHash,
2518
2586
  depositInstructions,
2519
2587
  canComplete,
@@ -2527,6 +2595,7 @@ function RampWidgetTemplate({
2527
2595
  onSelectQuote,
2528
2596
  onContactContinue,
2529
2597
  onOpenKyc,
2598
+ onOpenTos,
2530
2599
  onCompleteWithdraw,
2531
2600
  onRetry,
2532
2601
  onRefresh,
@@ -2720,7 +2789,11 @@ function RampWidgetTemplate({
2720
2789
  /* @__PURE__ */ jsx("span", { className: "pollar-ramp-payment-label", children: label }),
2721
2790
  /* @__PURE__ */ jsx("div", { className: "pollar-ramp-payment-value", children: /* @__PURE__ */ jsx("code", { style: { wordBreak: "break-all" }, children: value }) })
2722
2791
  ] }, key)),
2723
- kycUrl && txStatus !== "completed" && /* @__PURE__ */ jsxs("button", { type: "button", className: "pollar-btn-primary", onClick: onOpenKyc, children: [
2792
+ tosUrl && !depositInstructions && txStatus !== "completed" && /* @__PURE__ */ jsxs("button", { type: "button", className: "pollar-btn-primary", onClick: onOpenTos, children: [
2793
+ "Accept terms at ",
2794
+ provider
2795
+ ] }),
2796
+ kycUrl && !depositInstructions && txStatus !== "completed" && /* @__PURE__ */ jsxs("button", { type: "button", className: "pollar-btn-primary", onClick: onOpenKyc, children: [
2724
2797
  "Continue at ",
2725
2798
  provider
2726
2799
  ] }),
@@ -2762,6 +2835,7 @@ function RampWidget({ onClose }) {
2762
2835
  const [txId, setTxId] = useState(null);
2763
2836
  const [provider, setProvider] = useState("");
2764
2837
  const [kycUrl, setKycUrl] = useState(null);
2838
+ const [tosUrl, setTosUrl] = useState(null);
2765
2839
  const [txStatus, setTxStatus] = useState(null);
2766
2840
  const [stellarTxHash, setStellarTxHash] = useState(null);
2767
2841
  const [depositInstructions, setDepositInstructions] = useState(null);
@@ -2780,8 +2854,7 @@ function RampWidget({ onClose }) {
2780
2854
  setTxStatus(tx.status);
2781
2855
  if (tx.stellarTxHash) setStellarTxHash(tx.stellarTxHash);
2782
2856
  if (tx.kycUrl) setKycUrl(tx.kycUrl);
2783
- const di = tx.depositInstructions;
2784
- if (di) setDepositInstructions(di);
2857
+ if (tx.depositInstructions) setDepositInstructions(tx.depositInstructions);
2785
2858
  if (TERMINAL.includes(tx.status)) clearInterval(id);
2786
2859
  } catch {
2787
2860
  }
@@ -2829,8 +2902,7 @@ function RampWidget({ onClose }) {
2829
2902
  setTxStatus(tx.status);
2830
2903
  if (tx.stellarTxHash) setStellarTxHash(tx.stellarTxHash);
2831
2904
  if (tx.kycUrl) setKycUrl(tx.kycUrl);
2832
- const di = tx.depositInstructions;
2833
- if (di) setDepositInstructions(di);
2905
+ if (tx.depositInstructions) setDepositInstructions(tx.depositInstructions);
2834
2906
  }
2835
2907
  } catch {
2836
2908
  } finally {
@@ -2844,6 +2916,7 @@ function RampWidget({ onClose }) {
2844
2916
  setTxId(null);
2845
2917
  setProvider("");
2846
2918
  setKycUrl(null);
2919
+ setTosUrl(null);
2847
2920
  setTxStatus(null);
2848
2921
  setStellarTxHash(null);
2849
2922
  setDepositInstructions(null);
@@ -2870,6 +2943,7 @@ function RampWidget({ onClose }) {
2870
2943
  return;
2871
2944
  }
2872
2945
  setKycUrl(result.kycUrl ?? null);
2946
+ setTosUrl(result.tosUrl ?? null);
2873
2947
  setTxStatus(result.status);
2874
2948
  setStellarTxHash(result.stellarTxHash ?? null);
2875
2949
  setDepositInstructions(result.depositInstructions ?? null);
@@ -2934,6 +3008,9 @@ function RampWidget({ onClose }) {
2934
3008
  function handleOpenKyc() {
2935
3009
  if (kycUrl) window.open(kycUrl, "_blank", "noopener,noreferrer");
2936
3010
  }
3011
+ function handleOpenTos() {
3012
+ if (tosUrl) window.open(tosUrl, "_blank", "noopener,noreferrer");
3013
+ }
2937
3014
  async function handleCompleteWithdraw() {
2938
3015
  if (!txId) return;
2939
3016
  setCompleting(true);
@@ -2976,6 +3053,7 @@ function RampWidget({ onClose }) {
2976
3053
  provider,
2977
3054
  txStatus,
2978
3055
  kycUrl,
3056
+ tosUrl,
2979
3057
  stellarTxHash,
2980
3058
  depositInstructions,
2981
3059
  canComplete,
@@ -2989,6 +3067,7 @@ function RampWidget({ onClose }) {
2989
3067
  onSelectQuote: handleSelectQuote,
2990
3068
  onContactContinue: handleContactContinue,
2991
3069
  onOpenKyc: handleOpenKyc,
3070
+ onOpenTos: handleOpenTos,
2992
3071
  onCompleteWithdraw: handleCompleteWithdraw,
2993
3072
  onRetry: resetToInput,
2994
3073
  onRefresh: handleRefresh,
@@ -3154,6 +3233,43 @@ function ReceiveModal({ onClose }) {
3154
3233
  }
3155
3234
  ) });
3156
3235
  }
3236
+ function formatAmount2(value) {
3237
+ const n = parseFloat(value);
3238
+ return isNaN(n) ? value : n.toLocaleString(void 0, { maximumFractionDigits: 7 });
3239
+ }
3240
+ var optionLabel = (o) => o.available !== void 0 ? `${o.code} \u2014 ${formatAmount2(o.available)} available` : o.code;
3241
+ function AssetSelect({
3242
+ label,
3243
+ value,
3244
+ options,
3245
+ onChange,
3246
+ loading = false,
3247
+ disabled = false,
3248
+ appGroupLabel = "App assets",
3249
+ otherGroupLabel = "Other assets",
3250
+ children
3251
+ }) {
3252
+ const appAssets = options.filter((o) => o.enabledInApp);
3253
+ const otherAssets = options.filter((o) => !o.enabledInApp);
3254
+ return /* @__PURE__ */ jsxs("div", { className: "pollar-send-field", children: [
3255
+ /* @__PURE__ */ jsx("label", { className: "pollar-send-label", children: label }),
3256
+ loading ? /* @__PURE__ */ jsx("div", { className: "pollar-send-skeleton" }) : /* @__PURE__ */ jsxs(
3257
+ "select",
3258
+ {
3259
+ className: "pollar-input pollar-send-select",
3260
+ value,
3261
+ disabled,
3262
+ onChange: (e) => onChange(e.target.value),
3263
+ children: [
3264
+ value === "" && /* @__PURE__ */ jsx("option", { value: "", disabled: true, hidden: true }),
3265
+ appAssets.length > 0 && /* @__PURE__ */ jsx("optgroup", { label: appGroupLabel, children: appAssets.map((o) => /* @__PURE__ */ jsx("option", { value: o.key, children: optionLabel(o) }, o.key)) }),
3266
+ otherAssets.length > 0 && /* @__PURE__ */ jsx("optgroup", { label: otherGroupLabel, children: otherAssets.map((o) => /* @__PURE__ */ jsx("option", { value: o.key, children: optionLabel(o) }, o.key)) })
3267
+ ]
3268
+ }
3269
+ ),
3270
+ !loading && children
3271
+ ] });
3272
+ }
3157
3273
  var STATUS_MESSAGES = {
3158
3274
  idle: "",
3159
3275
  building: "Building transaction\u2026",
@@ -3406,8 +3522,6 @@ function SendModalTemplate({
3406
3522
  "--pollar-input-border-radius": "0.5rem",
3407
3523
  "--pollar-card-border-radius": "10px"
3408
3524
  };
3409
- const enabledAssets = assets.filter((a) => a.enabledInApp);
3410
- const otherAssets = assets.filter((a) => !a.enabledInApp);
3411
3525
  const selectedKey = selectedAsset ? assetKey3(selectedAsset) : "";
3412
3526
  const canSubmit = !!selectedAsset && !!amount && !!destination.trim() && !isLoadingBalance;
3413
3527
  const title = step === "form" ? "Send" : txTitle;
@@ -3427,36 +3541,24 @@ function SendModalTemplate({
3427
3541
  !isInProgress && /* @__PURE__ */ jsx("div", { className: "pollar-modal-header-actions", children: /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-modal-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M2 2l12 12M14 2L2 14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) }) })
3428
3542
  ] }),
3429
3543
  step === "form" && /* @__PURE__ */ jsxs(Fragment, { children: [
3430
- /* @__PURE__ */ jsxs("div", { className: "pollar-send-field", children: [
3431
- /* @__PURE__ */ jsx("label", { className: "pollar-send-label", children: "Asset" }),
3432
- isLoadingBalance ? /* @__PURE__ */ jsx("div", { className: "pollar-send-skeleton" }) : /* @__PURE__ */ jsxs(
3433
- "select",
3434
- {
3435
- className: "pollar-input pollar-send-select",
3436
- value: selectedKey,
3437
- onChange: (e) => {
3438
- const all = [...enabledAssets, ...otherAssets];
3439
- const found = all.find((a) => assetKey3(a) === e.target.value);
3440
- if (found) onSelectAsset(found);
3441
- },
3442
- children: [
3443
- /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: "Select asset" }),
3444
- enabledAssets.length > 0 && /* @__PURE__ */ jsx("optgroup", { label: "App assets", children: enabledAssets.map((a) => /* @__PURE__ */ jsxs("option", { value: assetKey3(a), children: [
3445
- a.code,
3446
- " \u2014 ",
3447
- formatBalance(a.available),
3448
- " available"
3449
- ] }, assetKey3(a))) }),
3450
- otherAssets.length > 0 && /* @__PURE__ */ jsx("optgroup", { label: "Other assets", children: otherAssets.map((a) => /* @__PURE__ */ jsxs("option", { value: assetKey3(a), children: [
3451
- a.code,
3452
- " \u2014 ",
3453
- formatBalance(a.available),
3454
- " available"
3455
- ] }, assetKey3(a))) })
3456
- ]
3544
+ /* @__PURE__ */ jsx(
3545
+ AssetSelect,
3546
+ {
3547
+ label: "Asset",
3548
+ value: selectedKey,
3549
+ loading: isLoadingBalance,
3550
+ options: assets.map((a) => ({
3551
+ key: assetKey3(a),
3552
+ code: a.code,
3553
+ available: a.available,
3554
+ enabledInApp: a.enabledInApp
3555
+ })),
3556
+ onChange: (key) => {
3557
+ const found = assets.find((a) => assetKey3(a) === key);
3558
+ if (found) onSelectAsset(found);
3457
3559
  }
3458
- )
3459
- ] }),
3560
+ }
3561
+ ),
3460
3562
  /* @__PURE__ */ jsxs("div", { className: "pollar-send-field", children: [
3461
3563
  /* @__PURE__ */ jsxs("div", { className: "pollar-send-label-row", children: [
3462
3564
  /* @__PURE__ */ jsx("label", { className: "pollar-send-label", children: "Amount" }),
@@ -3556,8 +3658,11 @@ function SendModal({ onClose }) {
3556
3658
  const allAssets = balanceData?.balances ?? [];
3557
3659
  const sortedAssets = [
3558
3660
  ...allAssets.filter((b) => b.enabledInApp),
3559
- ...allAssets.filter((b) => !b.enabledInApp && parseFloat(b.balance) > 0)
3661
+ ...allAssets.filter((b) => !b.enabledInApp && (b.type === "native" || parseFloat(b.balance) > 0))
3560
3662
  ];
3663
+ useEffect(() => {
3664
+ if (!selectedAsset && sortedAssets.length > 0) setSelectedAsset(sortedAssets[0]);
3665
+ }, [sortedAssets, selectedAsset]);
3561
3666
  const hash = transaction.step === "success" ? transaction.hash : null;
3562
3667
  const buildData = "buildData" in transaction ? transaction.buildData : null;
3563
3668
  const explorerNetwork = buildData?.summary.network?.toLowerCase().includes("testnet") ? "testnet" : buildData ? "public" : network === "testnet" ? "testnet" : "public";
@@ -3664,7 +3769,7 @@ var PROVIDER_LABELS = {
3664
3769
  soroswap: "Soroswap",
3665
3770
  sdex: "Stellar DEX"
3666
3771
  };
3667
- function formatAmount2(value) {
3772
+ function formatAmount3(value) {
3668
3773
  const n = parseFloat(value);
3669
3774
  return isNaN(n) ? value : n.toLocaleString(void 0, { maximumFractionDigits: 7 });
3670
3775
  }
@@ -3747,214 +3852,229 @@ function SwapModalTemplate({
3747
3852
  const buyKey = selectedBuy ? assetOptionKey(selectedBuy) : "";
3748
3853
  const canSwap = !smartUnsupported && !!selectedSell && !!selectedBuy && !!amount && !!quote && !quoteLoading && !isLoadingData;
3749
3854
  const title = step === "form" ? "Swap" : txTitle;
3750
- return /* @__PURE__ */ jsxs("div", { className: "pollar-modal-card pollar-send-modal", "data-theme": theme, style: cssVars, onClick: (e) => e.stopPropagation(), children: [
3751
- /* @__PURE__ */ jsxs("div", { className: "pollar-modal-header", children: [
3752
- /* @__PURE__ */ jsxs("div", { className: "pollar-send-header-left", children: [
3753
- showBack && /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-modal-close", onClick: onBack, "aria-label": "Back", children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M10 3L5 8l5 5", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }),
3754
- /* @__PURE__ */ jsx("h2", { className: "pollar-modal-title", children: title })
3755
- ] }),
3756
- !isInProgress && /* @__PURE__ */ jsxs("div", { className: "pollar-modal-header-actions", children: [
3757
- step === "form" && /* @__PURE__ */ jsx(
3758
- "button",
3759
- {
3760
- type: "button",
3761
- className: "pollar-modal-close",
3762
- onClick: onRefresh,
3763
- disabled: configLoading || isLoadingData,
3764
- "aria-label": "Refresh",
3765
- title: "Refresh balances and options",
3766
- children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsx(
3767
- "path",
3855
+ return /* @__PURE__ */ jsxs(
3856
+ "div",
3857
+ {
3858
+ className: "pollar-modal-card pollar-send-modal",
3859
+ "data-theme": theme,
3860
+ style: cssVars,
3861
+ onClick: (e) => e.stopPropagation(),
3862
+ children: [
3863
+ /* @__PURE__ */ jsxs("div", { className: "pollar-modal-header", children: [
3864
+ /* @__PURE__ */ jsxs("div", { className: "pollar-send-header-left", children: [
3865
+ showBack && /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-modal-close", onClick: onBack, "aria-label": "Back", children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M10 3L5 8l5 5", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }),
3866
+ /* @__PURE__ */ jsx("h2", { className: "pollar-modal-title", children: title })
3867
+ ] }),
3868
+ !isInProgress && /* @__PURE__ */ jsxs("div", { className: "pollar-modal-header-actions", children: [
3869
+ step === "form" && /* @__PURE__ */ jsx(
3870
+ "button",
3768
3871
  {
3769
- d: "M13.5 8a5.5 5.5 0 1 1-1.6-3.9M13.5 2.5v3h-3",
3770
- stroke: "currentColor",
3771
- strokeWidth: "1.6",
3772
- strokeLinecap: "round",
3773
- strokeLinejoin: "round"
3872
+ type: "button",
3873
+ className: "pollar-modal-close",
3874
+ onClick: onRefresh,
3875
+ disabled: configLoading || isLoadingData,
3876
+ "aria-label": "Refresh",
3877
+ title: "Refresh balances and options",
3878
+ children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsx(
3879
+ "path",
3880
+ {
3881
+ d: "M13.5 8a5.5 5.5 0 1 1-1.6-3.9M13.5 2.5v3h-3",
3882
+ stroke: "currentColor",
3883
+ strokeWidth: "1.6",
3884
+ strokeLinecap: "round",
3885
+ strokeLinejoin: "round"
3886
+ }
3887
+ ) })
3774
3888
  }
3775
- ) })
3776
- }
3777
- ),
3778
- /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-modal-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M2 2l12 12M14 2L2 14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) })
3779
- ] })
3780
- ] }),
3781
- step === "form" && configLoading && /* @__PURE__ */ jsx("div", { className: "pollar-send-hint", children: "Loading swap options\u2026" }),
3782
- step === "form" && !configLoading && swapUnavailable && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: "Swap is not available for this app." }),
3783
- step === "form" && !configLoading && !swapUnavailable && /* @__PURE__ */ jsxs(Fragment, { children: [
3784
- smartUnsupported && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: "Swaps are not yet available for smart (passkey) wallets." }),
3785
- /* @__PURE__ */ jsxs("div", { className: "pollar-send-field", children: [
3786
- /* @__PURE__ */ jsx("label", { className: "pollar-send-label", children: "You pay" }),
3787
- isLoadingData ? /* @__PURE__ */ jsx("div", { className: "pollar-send-skeleton" }) : /* @__PURE__ */ jsxs(
3788
- "select",
3789
- {
3790
- className: "pollar-input pollar-send-select",
3791
- value: sellKey,
3792
- onChange: (e) => {
3793
- const found = sellOptions.find((o) => assetOptionKey(o) === e.target.value);
3794
- if (found) onSelectSell(found);
3795
- },
3796
- children: [
3797
- /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: "Select asset to sell" }),
3798
- sellOptions.map((o) => /* @__PURE__ */ jsxs("option", { value: assetOptionKey(o), children: [
3799
- o.code,
3800
- o.available !== void 0 ? ` \u2014 ${formatAmount2(o.available)} available` : ""
3801
- ] }, assetOptionKey(o)))
3802
- ]
3803
- }
3804
- )
3805
- ] }),
3806
- /* @__PURE__ */ jsxs("div", { className: "pollar-send-field", children: [
3807
- /* @__PURE__ */ jsxs("div", { className: "pollar-send-label-row", children: [
3808
- /* @__PURE__ */ jsx("label", { className: "pollar-send-label", children: "Amount" }),
3809
- selectedSell?.available !== void 0 && /* @__PURE__ */ jsxs("span", { className: "pollar-send-hint", children: [
3810
- "Available: ",
3811
- formatAmount2(selectedSell.available),
3812
- " ",
3813
- selectedSell.code
3889
+ ),
3890
+ /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-modal-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M2 2l12 12M14 2L2 14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) })
3814
3891
  ] })
3815
3892
  ] }),
3816
- /* @__PURE__ */ jsx(
3817
- "input",
3818
- {
3819
- className: "pollar-input",
3820
- type: "text",
3821
- inputMode: "decimal",
3822
- placeholder: "0.00",
3823
- value: amount,
3824
- onChange: (e) => onAmountChange(e.target.value)
3825
- }
3826
- )
3827
- ] }),
3828
- /* @__PURE__ */ jsxs("div", { className: "pollar-send-field", children: [
3829
- /* @__PURE__ */ jsx("label", { className: "pollar-send-label", children: "You receive" }),
3830
- isLoadingData ? /* @__PURE__ */ jsx("div", { className: "pollar-send-skeleton" }) : /* @__PURE__ */ jsxs(
3831
- "select",
3832
- {
3833
- className: "pollar-input pollar-send-select",
3834
- value: buyKey,
3835
- onChange: (e) => {
3836
- const found = buyOptions.find((o) => assetOptionKey(o) === e.target.value);
3837
- if (found) onSelectBuy(found);
3838
- },
3839
- children: [
3840
- /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: "Select asset to buy" }),
3841
- buyOptions.map((o) => /* @__PURE__ */ jsxs("option", { value: assetOptionKey(o), children: [
3842
- o.code,
3843
- o.enabledInApp ? "" : " (external)"
3844
- ] }, assetOptionKey(o)))
3845
- ]
3846
- }
3847
- ),
3848
- !isLoadingData && (customOpen ? /* @__PURE__ */ jsxs("div", { className: "pollar-swap-custom", children: [
3893
+ step === "form" && configLoading && /* @__PURE__ */ jsx("div", { className: "pollar-send-hint", children: "Loading swap options\u2026" }),
3894
+ step === "form" && !configLoading && swapUnavailable && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: "Swap is not available for this app." }),
3895
+ step === "form" && !swapUnavailable && /* @__PURE__ */ jsxs(Fragment, { children: [
3896
+ smartUnsupported && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: "Swaps are not yet available for smart (passkey) wallets." }),
3849
3897
  /* @__PURE__ */ jsx(
3850
- "input",
3898
+ AssetSelect,
3851
3899
  {
3852
- className: "pollar-input",
3853
- type: "text",
3854
- placeholder: "Code (e.g. USDC)",
3855
- value: customCode,
3856
- onChange: (e) => setCustomCode(e.target.value)
3900
+ label: "You pay",
3901
+ value: sellKey,
3902
+ loading: isLoadingData,
3903
+ disabled: configLoading,
3904
+ options: sellOptions.map((o) => ({
3905
+ key: assetOptionKey(o),
3906
+ code: o.code,
3907
+ available: o.available,
3908
+ enabledInApp: o.enabledInApp
3909
+ })),
3910
+ onChange: (key) => {
3911
+ const found = sellOptions.find((o) => assetOptionKey(o) === key);
3912
+ if (found) onSelectSell(found);
3913
+ }
3857
3914
  }
3858
3915
  ),
3916
+ /* @__PURE__ */ jsxs("div", { className: "pollar-send-field", children: [
3917
+ /* @__PURE__ */ jsxs("div", { className: "pollar-send-label-row", children: [
3918
+ /* @__PURE__ */ jsx("label", { className: "pollar-send-label", children: "Amount" }),
3919
+ selectedSell?.available !== void 0 && /* @__PURE__ */ jsxs("span", { className: "pollar-send-hint", children: [
3920
+ "Available: ",
3921
+ formatAmount3(selectedSell.available),
3922
+ " ",
3923
+ selectedSell.code
3924
+ ] })
3925
+ ] }),
3926
+ /* @__PURE__ */ jsx(
3927
+ "input",
3928
+ {
3929
+ className: "pollar-input",
3930
+ type: "text",
3931
+ inputMode: "decimal",
3932
+ placeholder: "0.00",
3933
+ value: amount,
3934
+ disabled: configLoading,
3935
+ onChange: (e) => onAmountChange(e.target.value)
3936
+ }
3937
+ )
3938
+ ] }),
3859
3939
  /* @__PURE__ */ jsx(
3860
- "input",
3940
+ AssetSelect,
3861
3941
  {
3862
- className: "pollar-input",
3863
- type: "text",
3864
- placeholder: "Issuer (G...)",
3865
- value: customIssuer,
3866
- onChange: (e) => setCustomIssuer(e.target.value)
3942
+ label: "You receive",
3943
+ value: buyKey,
3944
+ loading: isLoadingData,
3945
+ disabled: configLoading,
3946
+ options: buyOptions.map((o) => ({
3947
+ key: assetOptionKey(o),
3948
+ code: o.code,
3949
+ enabledInApp: o.enabledInApp
3950
+ })),
3951
+ onChange: (key) => {
3952
+ const found = buyOptions.find((o) => assetOptionKey(o) === key);
3953
+ if (found) onSelectBuy(found);
3954
+ },
3955
+ children: customOpen ? /* @__PURE__ */ jsxs("div", { className: "pollar-swap-custom", children: [
3956
+ /* @__PURE__ */ jsx(
3957
+ "input",
3958
+ {
3959
+ className: "pollar-input",
3960
+ type: "text",
3961
+ placeholder: "Code (e.g. USDC)",
3962
+ value: customCode,
3963
+ onChange: (e) => setCustomCode(e.target.value)
3964
+ }
3965
+ ),
3966
+ /* @__PURE__ */ jsx(
3967
+ "input",
3968
+ {
3969
+ className: "pollar-input",
3970
+ type: "text",
3971
+ placeholder: "Issuer (G...)",
3972
+ value: customIssuer,
3973
+ onChange: (e) => setCustomIssuer(e.target.value)
3974
+ }
3975
+ ),
3976
+ customError && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: customError }),
3977
+ /* @__PURE__ */ jsxs("div", { className: "pollar-swap-custom-actions", children: [
3978
+ /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-btn-primary", onClick: submitCustomToken, children: "Add token" }),
3979
+ /* @__PURE__ */ jsx(
3980
+ "button",
3981
+ {
3982
+ type: "button",
3983
+ className: "pollar-swap-custom-cancel",
3984
+ onClick: () => {
3985
+ setCustomOpen(false);
3986
+ setCustomError("");
3987
+ },
3988
+ children: "Cancel"
3989
+ }
3990
+ )
3991
+ ] })
3992
+ ] }) : /* @__PURE__ */ jsx(
3993
+ "button",
3994
+ {
3995
+ type: "button",
3996
+ className: "pollar-swap-custom-toggle",
3997
+ disabled: configLoading,
3998
+ onClick: () => setCustomOpen(true),
3999
+ children: "+ Add a token by code / issuer"
4000
+ }
4001
+ )
3867
4002
  }
3868
4003
  ),
3869
- customError && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: customError }),
3870
- /* @__PURE__ */ jsxs("div", { className: "pollar-swap-custom-actions", children: [
3871
- /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-btn-primary", onClick: submitCustomToken, children: "Add token" }),
4004
+ /* @__PURE__ */ jsxs("div", { className: "pollar-send-field", children: [
4005
+ /* @__PURE__ */ jsx("label", { className: "pollar-send-label", children: "Route" }),
3872
4006
  /* @__PURE__ */ jsx(
3873
- "button",
4007
+ "select",
3874
4008
  {
3875
- type: "button",
3876
- className: "pollar-swap-custom-cancel",
3877
- onClick: () => {
3878
- setCustomOpen(false);
3879
- setCustomError("");
3880
- },
3881
- children: "Cancel"
4009
+ className: "pollar-input pollar-send-select",
4010
+ value: provider,
4011
+ disabled: configLoading || providers.length === 0,
4012
+ onChange: (e) => onProviderChange(e.target.value),
4013
+ children: providers.length === 0 ? /* @__PURE__ */ jsx("option", { value: provider, children: configLoading ? "Loading\u2026" : PROVIDER_LABELS[provider] }) : providers.map((p) => /* @__PURE__ */ jsx("option", { value: p, children: PROVIDER_LABELS[p] }, p))
3882
4014
  }
3883
4015
  )
3884
- ] })
3885
- ] }) : /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-swap-custom-toggle", onClick: () => setCustomOpen(true), children: "+ Add a token by code / issuer" }))
3886
- ] }),
3887
- /* @__PURE__ */ jsxs("div", { className: "pollar-send-field", children: [
3888
- /* @__PURE__ */ jsx("label", { className: "pollar-send-label", children: "Route" }),
3889
- /* @__PURE__ */ jsx(
3890
- "select",
4016
+ ] }),
4017
+ quoteLoading && /* @__PURE__ */ jsx("div", { className: "pollar-send-hint", children: "Fetching best price\u2026" }),
4018
+ !quoteLoading && quoteError && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: quoteError }),
4019
+ !quoteLoading && !quoteError && quote && selectedBuy && /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote", children: [
4020
+ /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote-row", children: [
4021
+ /* @__PURE__ */ jsx("span", { className: "pollar-send-hint", children: "You receive" }),
4022
+ /* @__PURE__ */ jsxs("span", { children: [
4023
+ "~ ",
4024
+ formatAmount3(quote.amountOut),
4025
+ " ",
4026
+ selectedBuy.code
4027
+ ] })
4028
+ ] }),
4029
+ /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote-row", children: [
4030
+ /* @__PURE__ */ jsx("span", { className: "pollar-send-hint", children: "Minimum received" }),
4031
+ /* @__PURE__ */ jsxs("span", { children: [
4032
+ formatAmount3(quote.minReceived),
4033
+ " ",
4034
+ selectedBuy.code
4035
+ ] })
4036
+ ] }),
4037
+ /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote-row", children: [
4038
+ /* @__PURE__ */ jsx("span", { className: "pollar-send-hint", children: "Price impact" }),
4039
+ /* @__PURE__ */ jsxs("span", { children: [
4040
+ quote.priceImpactPct,
4041
+ "%"
4042
+ ] })
4043
+ ] }),
4044
+ /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote-row", children: [
4045
+ /* @__PURE__ */ jsx("span", { className: "pollar-send-hint", children: "Route" }),
4046
+ /* @__PURE__ */ jsx("span", { children: PROVIDER_LABELS[quote.provider] })
4047
+ ] })
4048
+ ] }),
4049
+ !quoteLoading && !quoteError && !quote && selectedSell && selectedBuy && !!amount && /* @__PURE__ */ jsx("div", { className: "pollar-send-hint", children: "No route found for this pair." }),
4050
+ buyNeedsTrustline && selectedBuy && /* @__PURE__ */ jsxs("div", { className: "pollar-swap-trustline-notice", children: [
4051
+ "To receive ",
4052
+ selectedBuy.code,
4053
+ " your wallet needs a trustline. Swapping will create it first (~0.5 XLM reserve, refundable if you later remove it)."
4054
+ ] }),
4055
+ formError && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: formError }),
4056
+ /* @__PURE__ */ jsx("div", { className: "pollar-modal-actions", children: /* @__PURE__ */ jsx("button", { className: "pollar-btn-primary", onClick: onSwap, disabled: !canSwap, children: buyNeedsTrustline ? "Create trustline & swap" : "Swap" }) })
4057
+ ] }),
4058
+ step === "tx" && /* @__PURE__ */ jsx(
4059
+ TxStatusView,
3891
4060
  {
3892
- className: "pollar-input pollar-send-select",
3893
- value: provider,
3894
- onChange: (e) => onProviderChange(e.target.value),
3895
- children: providers.map((p) => /* @__PURE__ */ jsx("option", { value: p, children: PROVIDER_LABELS[p] }, p))
4061
+ transaction,
4062
+ showXdr,
4063
+ copied,
4064
+ explorerUrl,
4065
+ walletType,
4066
+ onSignAndSend: () => {
4067
+ },
4068
+ onToggleXdr,
4069
+ onCopyHash,
4070
+ onRetry,
4071
+ onDone
3896
4072
  }
3897
- )
3898
- ] }),
3899
- quoteLoading && /* @__PURE__ */ jsx("div", { className: "pollar-send-hint", children: "Fetching best price\u2026" }),
3900
- !quoteLoading && quoteError && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: quoteError }),
3901
- !quoteLoading && !quoteError && quote && selectedBuy && /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote", children: [
3902
- /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote-row", children: [
3903
- /* @__PURE__ */ jsx("span", { className: "pollar-send-hint", children: "You receive" }),
3904
- /* @__PURE__ */ jsxs("span", { children: [
3905
- "~ ",
3906
- formatAmount2(quote.amountOut),
3907
- " ",
3908
- selectedBuy.code
3909
- ] })
3910
- ] }),
3911
- /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote-row", children: [
3912
- /* @__PURE__ */ jsx("span", { className: "pollar-send-hint", children: "Minimum received" }),
3913
- /* @__PURE__ */ jsxs("span", { children: [
3914
- formatAmount2(quote.minReceived),
3915
- " ",
3916
- selectedBuy.code
3917
- ] })
3918
- ] }),
3919
- /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote-row", children: [
3920
- /* @__PURE__ */ jsx("span", { className: "pollar-send-hint", children: "Price impact" }),
3921
- /* @__PURE__ */ jsxs("span", { children: [
3922
- quote.priceImpactPct,
3923
- "%"
3924
- ] })
3925
- ] }),
3926
- /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote-row", children: [
3927
- /* @__PURE__ */ jsx("span", { className: "pollar-send-hint", children: "Route" }),
3928
- /* @__PURE__ */ jsx("span", { children: PROVIDER_LABELS[quote.provider] })
3929
- ] })
3930
- ] }),
3931
- !quoteLoading && !quoteError && !quote && selectedSell && selectedBuy && !!amount && /* @__PURE__ */ jsx("div", { className: "pollar-send-hint", children: "No route found for this pair." }),
3932
- buyNeedsTrustline && selectedBuy && /* @__PURE__ */ jsxs("div", { className: "pollar-swap-trustline-notice", children: [
3933
- "To receive ",
3934
- selectedBuy.code,
3935
- " your wallet needs a trustline. Swapping will create it first (~0.5 XLM reserve, refundable if you later remove it)."
3936
- ] }),
3937
- formError && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: formError }),
3938
- /* @__PURE__ */ jsx("div", { className: "pollar-modal-actions", children: /* @__PURE__ */ jsx("button", { className: "pollar-btn-primary", onClick: onSwap, disabled: !canSwap, children: buyNeedsTrustline ? "Create trustline & swap" : "Swap" }) })
3939
- ] }),
3940
- step === "tx" && /* @__PURE__ */ jsx(
3941
- TxStatusView,
3942
- {
3943
- transaction,
3944
- showXdr,
3945
- copied,
3946
- explorerUrl,
3947
- walletType,
3948
- onSignAndSend: () => {
3949
- },
3950
- onToggleXdr,
3951
- onCopyHash,
3952
- onRetry,
3953
- onDone
3954
- }
3955
- ),
3956
- /* @__PURE__ */ jsx(PollarModalFooter, {})
3957
- ] });
4073
+ ),
4074
+ /* @__PURE__ */ jsx(PollarModalFooter, {})
4075
+ ]
4076
+ }
4077
+ );
3958
4078
  }
3959
4079
  var QUOTE_DEBOUNCE_MS = 400;
3960
4080
  function toRef(a) {
@@ -4032,7 +4152,7 @@ function SwapModal({ onClose }) {
4032
4152
  const balances = walletBalance.step === "loaded" ? walletBalance.data.balances : [];
4033
4153
  const assetRecords = enabledAssets.step === "loaded" ? enabledAssets.data.assets : [];
4034
4154
  const isLoadingData = walletBalance.step === "loading" || enabledAssets.step === "loading";
4035
- const sellOptions = balances.filter((b) => parseFloat(b.available) > 0).map((b) => ({ ref: toRef(b), code: b.code, issuer: b.issuer, available: b.available, enabledInApp: b.enabledInApp }));
4155
+ 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 }));
4036
4156
  const buyKeyOfSell = selectedSell ? `${selectedSell.code}:${selectedSell.issuer ?? "native"}` : "";
4037
4157
  const optKey = (o) => `${o.code}:${o.issuer ?? "native"}`;
4038
4158
  const enabledBuy = assetRecords.map((a) => ({
@@ -4050,9 +4170,19 @@ function SwapModal({ onClose }) {
4050
4170
  })).filter((o) => !enabledKeys.has(optKey(o)));
4051
4171
  const knownKeys = /* @__PURE__ */ new Set([...enabledKeys, ...catalogBuy.map(optKey)]);
4052
4172
  const customBuy = customTokens.filter((o) => !knownKeys.has(optKey(o)));
4053
- const buyOptions = [...enabledBuy, ...catalogBuy, ...customBuy].filter(
4054
- (o) => optKey(o) !== buyKeyOfSell
4055
- );
4173
+ const buyOptions = [...enabledBuy, ...catalogBuy, ...customBuy].filter((o) => optKey(o) !== buyKeyOfSell);
4174
+ useEffect(() => {
4175
+ if (sellOptions.length === 0) return;
4176
+ if (!selectedSell || !sellOptions.some((o) => optKey(o) === optKey(selectedSell))) {
4177
+ setSelectedSell(sellOptions[0]);
4178
+ }
4179
+ }, [sellOptions, selectedSell]);
4180
+ useEffect(() => {
4181
+ if (buyOptions.length === 0) return;
4182
+ if (!selectedBuy || !buyOptions.some((o) => optKey(o) === optKey(selectedBuy))) {
4183
+ setSelectedBuy(buyOptions[0]);
4184
+ }
4185
+ }, [buyOptions, selectedBuy]);
4056
4186
  function addCustomToken(code, issuer) {
4057
4187
  const c = code.trim().toUpperCase();
4058
4188
  const i = issuer.trim();
@@ -4562,6 +4692,9 @@ function StatusBadge({ status }) {
4562
4692
  function formatDate(iso) {
4563
4693
  return new Date(iso).toLocaleDateString(void 0, { month: "short", day: "numeric", year: "numeric" });
4564
4694
  }
4695
+ function truncateMiddle(value, head = 4, tail = 4) {
4696
+ return value.length <= head + tail + 1 ? value : `${value.slice(0, head)}\u2026${value.slice(-tail)}`;
4697
+ }
4565
4698
  function TxHistoryModalTemplate({
4566
4699
  theme,
4567
4700
  accentColor,
@@ -4634,10 +4767,31 @@ function TxHistoryModalTemplate({
4634
4767
  txHistory.step === "error" && /* @__PURE__ */ jsx("div", { className: "pollar-modal-empty", children: txHistory.message }),
4635
4768
  txHistory.step === "loaded" && records.length === 0 && /* @__PURE__ */ jsx("div", { className: "pollar-modal-empty", children: "No transactions yet." }),
4636
4769
  records.map((record) => {
4637
- const explorerUrl = `https://stellar.expert/explorer/${record.network === "testnet" ? "testnet" : "public"}/tx/${record.hash}`;
4770
+ const hash = typeof record.hash === "string" && record.hash.length > 0 ? record.hash : void 0;
4771
+ const explorerUrl = hash ? `https://stellar.expert/explorer/${record.network === "testnet" ? "testnet" : "public"}/tx/${hash}` : void 0;
4772
+ const destination = typeof record.details?.destination === "string" ? record.details.destination : void 0;
4773
+ const asset = typeof record.details?.asset === "string" ? record.details.asset : void 0;
4774
+ const colon = asset ? asset.indexOf(":") : -1;
4775
+ const trustline = record.operation === "change_trust" && asset && colon > 0 ? {
4776
+ prefix: record.summary.split(":")[0],
4777
+ code: asset.slice(0, colon),
4778
+ issuer: asset.slice(colon + 1)
4779
+ } : void 0;
4638
4780
  return /* @__PURE__ */ jsxs("div", { className: "pollar-hist-item", children: [
4639
- /* @__PURE__ */ jsx("span", { className: "pollar-hist-item-summary", children: record.summary }),
4640
- /* @__PURE__ */ jsx(StatusBadge, { status: record.status }),
4781
+ /* @__PURE__ */ jsxs("div", { className: "pollar-hist-item-top", children: [
4782
+ /* @__PURE__ */ jsx("span", { className: "pollar-hist-item-summary", children: trustline ? /* @__PURE__ */ jsxs(Fragment, { children: [
4783
+ /* @__PURE__ */ jsxs("span", { className: "pollar-hist-item-title", children: [
4784
+ trustline.prefix,
4785
+ ": ",
4786
+ trustline.code
4787
+ ] }),
4788
+ /* @__PURE__ */ jsxs("span", { className: "pollar-hist-item-issuer", children: [
4789
+ truncateMiddle(trustline.issuer),
4790
+ /* @__PURE__ */ jsx(CopyButton, { value: trustline.issuer, label: "Copy issuer", className: "pollar-copy-btn-sm" })
4791
+ ] })
4792
+ ] }) : /* @__PURE__ */ jsx("span", { className: "pollar-hist-item-title", children: record.summary }) }),
4793
+ /* @__PURE__ */ jsx(StatusBadge, { status: record.status })
4794
+ ] }),
4641
4795
  /* @__PURE__ */ jsxs("span", { className: "pollar-hist-item-meta", children: [
4642
4796
  /* @__PURE__ */ jsx("span", { children: record.operation }),
4643
4797
  typeof record.details?.sponsored === "boolean" && /* @__PURE__ */ jsxs("span", { children: [
@@ -4649,21 +4803,29 @@ function TxHistoryModalTemplate({
4649
4803
  record.feeXlm,
4650
4804
  " XLM"
4651
4805
  ] }),
4652
- /* @__PURE__ */ jsxs("span", { children: [
4653
- "\xB7 ",
4654
- formatDate(record.createdAt)
4655
- ] }),
4656
- /* @__PURE__ */ jsx("span", { children: "\xB7" }),
4657
- /* @__PURE__ */ jsxs(
4658
- "a",
4659
- {
4660
- className: "pollar-hist-item-explorer",
4661
- href: explorerUrl,
4662
- target: "_blank",
4663
- rel: "noopener noreferrer",
4664
- "aria-label": "View on Stellar Explorer",
4665
- children: [
4666
- /* @__PURE__ */ jsxs("svg", { width: "11", height: "11", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
4806
+ destination && /* @__PURE__ */ jsxs(Fragment, { children: [
4807
+ /* @__PURE__ */ jsx("span", { children: "\xB7" }),
4808
+ /* @__PURE__ */ jsxs("span", { className: "pollar-hist-item-issuer", children: [
4809
+ truncateMiddle(destination),
4810
+ /* @__PURE__ */ jsx(CopyButton, { value: destination, label: "Copy wallet address", className: "pollar-copy-btn-sm" })
4811
+ ] })
4812
+ ] })
4813
+ ] }),
4814
+ /* @__PURE__ */ jsxs("div", { className: "pollar-hist-item-footer", children: [
4815
+ /* @__PURE__ */ jsx("span", { children: formatDate(record.createdAt) }),
4816
+ hash && /* @__PURE__ */ jsxs(Fragment, { children: [
4817
+ /* @__PURE__ */ jsx("span", { className: "pollar-hist-item-dot", children: "\xB7" }),
4818
+ /* @__PURE__ */ jsx("span", { className: "pollar-hist-item-hash", children: truncateMiddle(hash, 6, 6) }),
4819
+ /* @__PURE__ */ jsx(CopyButton, { value: hash, label: "Copy transaction hash", className: "pollar-copy-btn-sm" }),
4820
+ /* @__PURE__ */ jsx(
4821
+ "a",
4822
+ {
4823
+ className: "pollar-hist-item-explorer",
4824
+ href: explorerUrl,
4825
+ target: "_blank",
4826
+ rel: "noopener noreferrer",
4827
+ "aria-label": "View on Stellar Explorer",
4828
+ children: /* @__PURE__ */ jsxs("svg", { width: "12", height: "12", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
4667
4829
  /* @__PURE__ */ jsx(
4668
4830
  "path",
4669
4831
  {
@@ -4683,11 +4845,10 @@ function TxHistoryModalTemplate({
4683
4845
  strokeLinejoin: "round"
4684
4846
  }
4685
4847
  )
4686
- ] }),
4687
- "Explorer"
4688
- ]
4689
- }
4690
- )
4848
+ ] })
4849
+ }
4850
+ )
4851
+ ] })
4691
4852
  ] })
4692
4853
  ] }, record.id);
4693
4854
  })
@@ -4741,7 +4902,7 @@ function TxHistoryModal({ onClose }) {
4741
4902
  }
4742
4903
  function formatBalance2(balance) {
4743
4904
  const n = parseFloat(balance);
4744
- return isNaN(n) ? balance : n.toLocaleString(void 0, { maximumFractionDigits: 7 });
4905
+ return isNaN(n) ? balance : n.toLocaleString(void 0, { minimumFractionDigits: 7, maximumFractionDigits: 7 });
4745
4906
  }
4746
4907
  function cropAddress2(address) {
4747
4908
  if (address.length <= 16) return address;
@@ -4750,7 +4911,13 @@ function cropAddress2(address) {
4750
4911
  function BalanceItem({ record }) {
4751
4912
  const balanceDiffers = record.balance !== record.available;
4752
4913
  return /* @__PURE__ */ jsxs("div", { className: "pollar-bal-item", children: [
4753
- /* @__PURE__ */ jsx("span", { className: "pollar-bal-asset", children: record.code }),
4914
+ /* @__PURE__ */ jsxs("div", { className: "pollar-bal-asset-info", children: [
4915
+ /* @__PURE__ */ jsx("span", { className: "pollar-bal-asset", children: record.code }),
4916
+ record.issuer && /* @__PURE__ */ jsxs("span", { className: "pollar-bal-issuer", children: [
4917
+ /* @__PURE__ */ jsx("span", { className: "pollar-bal-issuer-addr", children: cropAddress2(record.issuer) }),
4918
+ /* @__PURE__ */ jsx(CopyButton, { value: record.issuer, label: "Copy issuer address", className: "pollar-copy-btn-sm" })
4919
+ ] })
4920
+ ] }),
4754
4921
  /* @__PURE__ */ jsxs("div", { className: "pollar-bal-amounts", children: [
4755
4922
  /* @__PURE__ */ jsx("span", { className: "pollar-bal-amount", children: formatBalance2(record.balance) }),
4756
4923
  balanceDiffers && /* @__PURE__ */ jsxs("span", { className: "pollar-bal-available", children: [
@@ -4813,7 +4980,10 @@ function WalletBalanceModalTemplate({
4813
4980
  /* @__PURE__ */ jsx("button", { className: "pollar-modal-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M2 2l12 12M14 2L2 14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) })
4814
4981
  ] })
4815
4982
  ] }),
4816
- walletAddress && /* @__PURE__ */ jsx("div", { className: "pollar-bal-address", children: cropAddress2(walletAddress) }),
4983
+ walletAddress && /* @__PURE__ */ jsxs("div", { className: "pollar-bal-address-row", children: [
4984
+ /* @__PURE__ */ jsx("span", { className: "pollar-bal-address", children: cropAddress2(walletAddress) }),
4985
+ /* @__PURE__ */ jsx(CopyButton, { value: walletAddress, label: "Copy wallet address" })
4986
+ ] }),
4817
4987
  isLoading && /* @__PURE__ */ jsx("div", { className: "pollar-modal-empty", children: "Loading\u2026" }),
4818
4988
  walletBalance.step === "error" && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: walletBalance.message }),
4819
4989
  data && !data.exists && /* @__PURE__ */ jsxs("div", { className: "pollar-modal-empty", children: [