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