@pollar/react 0.10.1-rc.4 → 0.10.1-rc.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1033,7 +1033,7 @@ var PollarModalFooter = () => {
1033
1033
  /* @__PURE__ */ jsx("span", { className: "pollar-footer-name", children: "Pollar" }),
1034
1034
  /* @__PURE__ */ jsxs("span", { className: "pollar-footer-version", children: [
1035
1035
  "v",
1036
- "0.10.1-rc.4"
1036
+ "0.10.1-rc.6"
1037
1037
  ] })
1038
1038
  ] })
1039
1039
  ] });
@@ -1065,16 +1065,7 @@ function CopyButton({ value, label = "Copy", className }) {
1065
1065
  className: `pollar-copy-btn${className ? ` ${className}` : ""}`,
1066
1066
  onClick: handleCopy,
1067
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(
1069
- "path",
1070
- {
1071
- d: "M3.5 7l2.5 2.5 4.5-5",
1072
- stroke: "currentColor",
1073
- strokeWidth: "1.5",
1074
- strokeLinecap: "round",
1075
- strokeLinejoin: "round"
1076
- }
1077
- ) }) : /* @__PURE__ */ jsxs("svg", { width: "13", height: "13", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
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: [
1078
1069
  /* @__PURE__ */ jsx("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1.5", stroke: "currentColor", strokeWidth: "1.5" }),
1079
1070
  /* @__PURE__ */ jsx(
1080
1071
  "path",
@@ -2281,12 +2272,38 @@ function PrivyLoginSubmodal({
2281
2272
  fail(error);
2282
2273
  }
2283
2274
  }
2284
- 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
+ ) });
2285
2289
  const showEmail = options.includes("email");
2286
2290
  const showGoogle = options.includes("google");
2287
2291
  const showGithub = options.includes("github");
2288
2292
  return /* @__PURE__ */ jsxs("div", { className: "pollar-modal-card pollar-modal", style: cssVars, onClick: (e) => e.stopPropagation(), children: [
2289
- /* @__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
+ ) }),
2290
2307
  /* @__PURE__ */ jsxs("div", { className: "pollar-header", children: [
2291
2308
  /* @__PURE__ */ jsx("div", { className: "pollar-logo-wrap", children: /* @__PURE__ */ jsx("img", { src: logoUrl ?? LOGO_POLLAR, alt: "Logo", className: "pollar-logo" }) }),
2292
2309
  /* @__PURE__ */ jsx("h2", { className: "pollar-title", children: appName }),
@@ -2537,13 +2554,23 @@ var INSTRUCTION_LABELS = {
2537
2554
  function flattenInstructions(instr) {
2538
2555
  const out = [];
2539
2556
  for (const [k, v] of Object.entries(instr)) {
2557
+ if (k === "qrBase64") {
2558
+ if (typeof v === "string" && v) out.push({ key: k, label: INSTRUCTION_LABELS[k] ?? "Payment QR", value: v, kind: "qr" });
2559
+ continue;
2560
+ }
2561
+ if ((k === "expiresAt" || k === "expires_at") && (typeof v === "number" || typeof v === "string")) {
2562
+ const ms = Number(v);
2563
+ if (Number.isFinite(ms) && ms > 0) {
2564
+ out.push({ key: k, label: INSTRUCTION_LABELS[k] ?? "Expires", value: new Date(ms).toLocaleString(), kind: "datetime" });
2565
+ }
2566
+ continue;
2567
+ }
2540
2568
  let value = "";
2541
2569
  if (typeof v === "string" || typeof v === "number") value = String(v);
2542
- else if (Array.isArray(v))
2543
- value = v.filter((x) => typeof x === "string" || typeof x === "number").join(", ");
2570
+ else if (Array.isArray(v)) value = v.filter((x) => typeof x === "string" || typeof x === "number").join(", ");
2544
2571
  else continue;
2545
2572
  if (!value) continue;
2546
- out.push({ key: k, label: INSTRUCTION_LABELS[k] ?? k, value });
2573
+ out.push({ key: k, label: INSTRUCTION_LABELS[k] ?? k, value, kind: "text" });
2547
2574
  }
2548
2575
  return out;
2549
2576
  }
@@ -2565,6 +2592,7 @@ function RampWidgetTemplate({
2565
2592
  provider,
2566
2593
  txStatus,
2567
2594
  kycUrl,
2595
+ tosUrl,
2568
2596
  stellarTxHash,
2569
2597
  depositInstructions,
2570
2598
  canComplete,
@@ -2578,6 +2606,7 @@ function RampWidgetTemplate({
2578
2606
  onSelectQuote,
2579
2607
  onContactContinue,
2580
2608
  onOpenKyc,
2609
+ onOpenTos,
2581
2610
  onCompleteWithdraw,
2582
2611
  onRetry,
2583
2612
  onRefresh,
@@ -2767,11 +2796,22 @@ function RampWidgetTemplate({
2767
2796
  stellarTxHash.slice(-8)
2768
2797
  ] }) })
2769
2798
  ] }),
2770
- depositInstructions && txStatus !== "completed" && flattenInstructions(depositInstructions).map(({ key, label, value }) => /* @__PURE__ */ jsxs("div", { className: "pollar-ramp-payment-field", children: [
2799
+ depositInstructions && txStatus !== "completed" && flattenInstructions(depositInstructions).map(({ key, label, value, kind }) => /* @__PURE__ */ jsxs("div", { className: "pollar-ramp-payment-field", children: [
2771
2800
  /* @__PURE__ */ jsx("span", { className: "pollar-ramp-payment-label", children: label }),
2772
- /* @__PURE__ */ jsx("div", { className: "pollar-ramp-payment-value", children: /* @__PURE__ */ jsx("code", { style: { wordBreak: "break-all" }, children: value }) })
2801
+ /* @__PURE__ */ jsx("div", { className: "pollar-ramp-payment-value", children: kind === "qr" ? /* @__PURE__ */ jsx(
2802
+ "img",
2803
+ {
2804
+ src: value.startsWith("data:") ? value : `data:image/png;base64,${value}`,
2805
+ alt: label,
2806
+ style: { width: "100%", maxWidth: 220, height: "auto", display: "block", margin: "0 auto" }
2807
+ }
2808
+ ) : kind === "datetime" ? /* @__PURE__ */ jsx("span", { children: value }) : /* @__PURE__ */ jsx("code", { style: { wordBreak: "break-all" }, children: value }) })
2773
2809
  ] }, key)),
2774
- kycUrl && txStatus !== "completed" && /* @__PURE__ */ jsxs("button", { type: "button", className: "pollar-btn-primary", onClick: onOpenKyc, children: [
2810
+ tosUrl && !depositInstructions && txStatus !== "completed" && /* @__PURE__ */ jsxs("button", { type: "button", className: "pollar-btn-primary", onClick: onOpenTos, children: [
2811
+ "Accept terms at ",
2812
+ provider
2813
+ ] }),
2814
+ kycUrl && !depositInstructions && txStatus !== "completed" && /* @__PURE__ */ jsxs("button", { type: "button", className: "pollar-btn-primary", onClick: onOpenKyc, children: [
2775
2815
  "Continue at ",
2776
2816
  provider
2777
2817
  ] }),
@@ -2813,6 +2853,7 @@ function RampWidget({ onClose }) {
2813
2853
  const [txId, setTxId] = useState(null);
2814
2854
  const [provider, setProvider] = useState("");
2815
2855
  const [kycUrl, setKycUrl] = useState(null);
2856
+ const [tosUrl, setTosUrl] = useState(null);
2816
2857
  const [txStatus, setTxStatus] = useState(null);
2817
2858
  const [stellarTxHash, setStellarTxHash] = useState(null);
2818
2859
  const [depositInstructions, setDepositInstructions] = useState(null);
@@ -2831,8 +2872,7 @@ function RampWidget({ onClose }) {
2831
2872
  setTxStatus(tx.status);
2832
2873
  if (tx.stellarTxHash) setStellarTxHash(tx.stellarTxHash);
2833
2874
  if (tx.kycUrl) setKycUrl(tx.kycUrl);
2834
- const di = tx.depositInstructions;
2835
- if (di) setDepositInstructions(di);
2875
+ if (tx.depositInstructions) setDepositInstructions(tx.depositInstructions);
2836
2876
  if (TERMINAL.includes(tx.status)) clearInterval(id);
2837
2877
  } catch {
2838
2878
  }
@@ -2880,8 +2920,7 @@ function RampWidget({ onClose }) {
2880
2920
  setTxStatus(tx.status);
2881
2921
  if (tx.stellarTxHash) setStellarTxHash(tx.stellarTxHash);
2882
2922
  if (tx.kycUrl) setKycUrl(tx.kycUrl);
2883
- const di = tx.depositInstructions;
2884
- if (di) setDepositInstructions(di);
2923
+ if (tx.depositInstructions) setDepositInstructions(tx.depositInstructions);
2885
2924
  }
2886
2925
  } catch {
2887
2926
  } finally {
@@ -2895,6 +2934,7 @@ function RampWidget({ onClose }) {
2895
2934
  setTxId(null);
2896
2935
  setProvider("");
2897
2936
  setKycUrl(null);
2937
+ setTosUrl(null);
2898
2938
  setTxStatus(null);
2899
2939
  setStellarTxHash(null);
2900
2940
  setDepositInstructions(null);
@@ -2921,6 +2961,7 @@ function RampWidget({ onClose }) {
2921
2961
  return;
2922
2962
  }
2923
2963
  setKycUrl(result.kycUrl ?? null);
2964
+ setTosUrl(result.tosUrl ?? null);
2924
2965
  setTxStatus(result.status);
2925
2966
  setStellarTxHash(result.stellarTxHash ?? null);
2926
2967
  setDepositInstructions(result.depositInstructions ?? null);
@@ -2985,6 +3026,9 @@ function RampWidget({ onClose }) {
2985
3026
  function handleOpenKyc() {
2986
3027
  if (kycUrl) window.open(kycUrl, "_blank", "noopener,noreferrer");
2987
3028
  }
3029
+ function handleOpenTos() {
3030
+ if (tosUrl) window.open(tosUrl, "_blank", "noopener,noreferrer");
3031
+ }
2988
3032
  async function handleCompleteWithdraw() {
2989
3033
  if (!txId) return;
2990
3034
  setCompleting(true);
@@ -3027,6 +3071,7 @@ function RampWidget({ onClose }) {
3027
3071
  provider,
3028
3072
  txStatus,
3029
3073
  kycUrl,
3074
+ tosUrl,
3030
3075
  stellarTxHash,
3031
3076
  depositInstructions,
3032
3077
  canComplete,
@@ -3040,6 +3085,7 @@ function RampWidget({ onClose }) {
3040
3085
  onSelectQuote: handleSelectQuote,
3041
3086
  onContactContinue: handleContactContinue,
3042
3087
  onOpenKyc: handleOpenKyc,
3088
+ onOpenTos: handleOpenTos,
3043
3089
  onCompleteWithdraw: handleCompleteWithdraw,
3044
3090
  onRetry: resetToInput,
3045
3091
  onRefresh: handleRefresh,
@@ -3205,6 +3251,43 @@ function ReceiveModal({ onClose }) {
3205
3251
  }
3206
3252
  ) });
3207
3253
  }
3254
+ function formatAmount2(value) {
3255
+ const n = parseFloat(value);
3256
+ return isNaN(n) ? value : n.toLocaleString(void 0, { maximumFractionDigits: 7 });
3257
+ }
3258
+ var optionLabel = (o) => o.available !== void 0 ? `${o.code} \u2014 ${formatAmount2(o.available)} available` : o.code;
3259
+ function AssetSelect({
3260
+ label,
3261
+ value,
3262
+ options,
3263
+ onChange,
3264
+ loading = false,
3265
+ disabled = false,
3266
+ appGroupLabel = "App assets",
3267
+ otherGroupLabel = "Other assets",
3268
+ children
3269
+ }) {
3270
+ const appAssets = options.filter((o) => o.enabledInApp);
3271
+ const otherAssets = options.filter((o) => !o.enabledInApp);
3272
+ return /* @__PURE__ */ jsxs("div", { className: "pollar-send-field", children: [
3273
+ /* @__PURE__ */ jsx("label", { className: "pollar-send-label", children: label }),
3274
+ loading ? /* @__PURE__ */ jsx("div", { className: "pollar-send-skeleton" }) : /* @__PURE__ */ jsxs(
3275
+ "select",
3276
+ {
3277
+ className: "pollar-input pollar-send-select",
3278
+ value,
3279
+ disabled,
3280
+ onChange: (e) => onChange(e.target.value),
3281
+ children: [
3282
+ value === "" && /* @__PURE__ */ jsx("option", { value: "", disabled: true, hidden: true }),
3283
+ appAssets.length > 0 && /* @__PURE__ */ jsx("optgroup", { label: appGroupLabel, children: appAssets.map((o) => /* @__PURE__ */ jsx("option", { value: o.key, children: optionLabel(o) }, o.key)) }),
3284
+ otherAssets.length > 0 && /* @__PURE__ */ jsx("optgroup", { label: otherGroupLabel, children: otherAssets.map((o) => /* @__PURE__ */ jsx("option", { value: o.key, children: optionLabel(o) }, o.key)) })
3285
+ ]
3286
+ }
3287
+ ),
3288
+ !loading && children
3289
+ ] });
3290
+ }
3208
3291
  var STATUS_MESSAGES = {
3209
3292
  idle: "",
3210
3293
  building: "Building transaction\u2026",
@@ -3457,8 +3540,6 @@ function SendModalTemplate({
3457
3540
  "--pollar-input-border-radius": "0.5rem",
3458
3541
  "--pollar-card-border-radius": "10px"
3459
3542
  };
3460
- const enabledAssets = assets.filter((a) => a.enabledInApp);
3461
- const otherAssets = assets.filter((a) => !a.enabledInApp);
3462
3543
  const selectedKey = selectedAsset ? assetKey3(selectedAsset) : "";
3463
3544
  const canSubmit = !!selectedAsset && !!amount && !!destination.trim() && !isLoadingBalance;
3464
3545
  const title = step === "form" ? "Send" : txTitle;
@@ -3478,36 +3559,24 @@ function SendModalTemplate({
3478
3559
  !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" }) }) }) })
3479
3560
  ] }),
3480
3561
  step === "form" && /* @__PURE__ */ jsxs(Fragment, { children: [
3481
- /* @__PURE__ */ jsxs("div", { className: "pollar-send-field", children: [
3482
- /* @__PURE__ */ jsx("label", { className: "pollar-send-label", children: "Asset" }),
3483
- isLoadingBalance ? /* @__PURE__ */ jsx("div", { className: "pollar-send-skeleton" }) : /* @__PURE__ */ jsxs(
3484
- "select",
3485
- {
3486
- className: "pollar-input pollar-send-select",
3487
- value: selectedKey,
3488
- onChange: (e) => {
3489
- const all = [...enabledAssets, ...otherAssets];
3490
- const found = all.find((a) => assetKey3(a) === e.target.value);
3491
- if (found) onSelectAsset(found);
3492
- },
3493
- children: [
3494
- /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: "Select asset" }),
3495
- enabledAssets.length > 0 && /* @__PURE__ */ jsx("optgroup", { label: "App assets", children: enabledAssets.map((a) => /* @__PURE__ */ jsxs("option", { value: assetKey3(a), children: [
3496
- a.code,
3497
- " \u2014 ",
3498
- formatBalance(a.available),
3499
- " available"
3500
- ] }, assetKey3(a))) }),
3501
- otherAssets.length > 0 && /* @__PURE__ */ jsx("optgroup", { label: "Other assets", children: otherAssets.map((a) => /* @__PURE__ */ jsxs("option", { value: assetKey3(a), children: [
3502
- a.code,
3503
- " \u2014 ",
3504
- formatBalance(a.available),
3505
- " available"
3506
- ] }, assetKey3(a))) })
3507
- ]
3562
+ /* @__PURE__ */ jsx(
3563
+ AssetSelect,
3564
+ {
3565
+ label: "Asset",
3566
+ value: selectedKey,
3567
+ loading: isLoadingBalance,
3568
+ options: assets.map((a) => ({
3569
+ key: assetKey3(a),
3570
+ code: a.code,
3571
+ available: a.available,
3572
+ enabledInApp: a.enabledInApp
3573
+ })),
3574
+ onChange: (key) => {
3575
+ const found = assets.find((a) => assetKey3(a) === key);
3576
+ if (found) onSelectAsset(found);
3508
3577
  }
3509
- )
3510
- ] }),
3578
+ }
3579
+ ),
3511
3580
  /* @__PURE__ */ jsxs("div", { className: "pollar-send-field", children: [
3512
3581
  /* @__PURE__ */ jsxs("div", { className: "pollar-send-label-row", children: [
3513
3582
  /* @__PURE__ */ jsx("label", { className: "pollar-send-label", children: "Amount" }),
@@ -3607,13 +3676,16 @@ function SendModal({ onClose }) {
3607
3676
  const allAssets = balanceData?.balances ?? [];
3608
3677
  const sortedAssets = [
3609
3678
  ...allAssets.filter((b) => b.enabledInApp),
3610
- ...allAssets.filter((b) => !b.enabledInApp && parseFloat(b.balance) > 0)
3679
+ ...allAssets.filter((b) => !b.enabledInApp && (b.type === "native" || parseFloat(b.balance) > 0))
3611
3680
  ];
3681
+ useEffect(() => {
3682
+ if (!selectedAsset && sortedAssets.length > 0) setSelectedAsset(sortedAssets[0]);
3683
+ }, [sortedAssets, selectedAsset]);
3612
3684
  const hash = transaction.step === "success" ? transaction.hash : null;
3613
3685
  const buildData = "buildData" in transaction ? transaction.buildData : null;
3614
3686
  const explorerNetwork = buildData?.summary.network?.toLowerCase().includes("testnet") ? "testnet" : buildData ? "public" : network === "testnet" ? "testnet" : "public";
3615
3687
  const explorerUrl = hash ? `https://stellar.expert/explorer/${explorerNetwork}/tx/${hash}` : null;
3616
- const IN_FLIGHT_STEPS2 = [
3688
+ const IN_FLIGHT_STEPS3 = [
3617
3689
  "building",
3618
3690
  "signing",
3619
3691
  "submitting",
@@ -3621,7 +3693,7 @@ function SendModal({ onClose }) {
3621
3693
  "signing-submitting",
3622
3694
  "building-signing-submitting"
3623
3695
  ];
3624
- const isInProgress = IN_FLIGHT_STEPS2.includes(transaction.step);
3696
+ const isInProgress = IN_FLIGHT_STEPS3.includes(transaction.step);
3625
3697
  const showBack = step === "tx" && (transaction.step === "error" || transaction.step === "success") && !isInProgress;
3626
3698
  const txTitle = isInProgress ? "Sending\u2026" : transaction.step === "success" ? "Sent!" : transaction.step === "error" ? "Send failed" : "Confirm Send";
3627
3699
  async function handleSubmit() {
@@ -3715,7 +3787,7 @@ var PROVIDER_LABELS = {
3715
3787
  soroswap: "Soroswap",
3716
3788
  sdex: "Stellar DEX"
3717
3789
  };
3718
- function formatAmount2(value) {
3790
+ function formatAmount3(value) {
3719
3791
  const n = parseFloat(value);
3720
3792
  return isNaN(n) ? value : n.toLocaleString(void 0, { maximumFractionDigits: 7 });
3721
3793
  }
@@ -3798,214 +3870,229 @@ function SwapModalTemplate({
3798
3870
  const buyKey = selectedBuy ? assetOptionKey(selectedBuy) : "";
3799
3871
  const canSwap = !smartUnsupported && !!selectedSell && !!selectedBuy && !!amount && !!quote && !quoteLoading && !isLoadingData;
3800
3872
  const title = step === "form" ? "Swap" : txTitle;
3801
- return /* @__PURE__ */ jsxs("div", { className: "pollar-modal-card pollar-send-modal", "data-theme": theme, style: cssVars, onClick: (e) => e.stopPropagation(), children: [
3802
- /* @__PURE__ */ jsxs("div", { className: "pollar-modal-header", children: [
3803
- /* @__PURE__ */ jsxs("div", { className: "pollar-send-header-left", children: [
3804
- 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" }) }) }),
3805
- /* @__PURE__ */ jsx("h2", { className: "pollar-modal-title", children: title })
3806
- ] }),
3807
- !isInProgress && /* @__PURE__ */ jsxs("div", { className: "pollar-modal-header-actions", children: [
3808
- step === "form" && /* @__PURE__ */ jsx(
3809
- "button",
3810
- {
3811
- type: "button",
3812
- className: "pollar-modal-close",
3813
- onClick: onRefresh,
3814
- disabled: configLoading || isLoadingData,
3815
- "aria-label": "Refresh",
3816
- title: "Refresh balances and options",
3817
- children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsx(
3818
- "path",
3873
+ return /* @__PURE__ */ jsxs(
3874
+ "div",
3875
+ {
3876
+ className: "pollar-modal-card pollar-send-modal",
3877
+ "data-theme": theme,
3878
+ style: cssVars,
3879
+ onClick: (e) => e.stopPropagation(),
3880
+ children: [
3881
+ /* @__PURE__ */ jsxs("div", { className: "pollar-modal-header", children: [
3882
+ /* @__PURE__ */ jsxs("div", { className: "pollar-send-header-left", children: [
3883
+ 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" }) }) }),
3884
+ /* @__PURE__ */ jsx("h2", { className: "pollar-modal-title", children: title })
3885
+ ] }),
3886
+ !isInProgress && /* @__PURE__ */ jsxs("div", { className: "pollar-modal-header-actions", children: [
3887
+ step === "form" && /* @__PURE__ */ jsx(
3888
+ "button",
3819
3889
  {
3820
- d: "M13.5 8a5.5 5.5 0 1 1-1.6-3.9M13.5 2.5v3h-3",
3821
- stroke: "currentColor",
3822
- strokeWidth: "1.6",
3823
- strokeLinecap: "round",
3824
- strokeLinejoin: "round"
3890
+ type: "button",
3891
+ className: "pollar-modal-close",
3892
+ onClick: onRefresh,
3893
+ disabled: configLoading || isLoadingData,
3894
+ "aria-label": "Refresh",
3895
+ title: "Refresh balances and options",
3896
+ children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsx(
3897
+ "path",
3898
+ {
3899
+ d: "M13.5 8a5.5 5.5 0 1 1-1.6-3.9M13.5 2.5v3h-3",
3900
+ stroke: "currentColor",
3901
+ strokeWidth: "1.6",
3902
+ strokeLinecap: "round",
3903
+ strokeLinejoin: "round"
3904
+ }
3905
+ ) })
3825
3906
  }
3826
- ) })
3827
- }
3828
- ),
3829
- /* @__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" }) }) })
3830
- ] })
3831
- ] }),
3832
- step === "form" && configLoading && /* @__PURE__ */ jsx("div", { className: "pollar-send-hint", children: "Loading swap options\u2026" }),
3833
- step === "form" && !configLoading && swapUnavailable && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: "Swap is not available for this app." }),
3834
- step === "form" && !configLoading && !swapUnavailable && /* @__PURE__ */ jsxs(Fragment, { children: [
3835
- smartUnsupported && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: "Swaps are not yet available for smart (passkey) wallets." }),
3836
- /* @__PURE__ */ jsxs("div", { className: "pollar-send-field", children: [
3837
- /* @__PURE__ */ jsx("label", { className: "pollar-send-label", children: "You pay" }),
3838
- isLoadingData ? /* @__PURE__ */ jsx("div", { className: "pollar-send-skeleton" }) : /* @__PURE__ */ jsxs(
3839
- "select",
3840
- {
3841
- className: "pollar-input pollar-send-select",
3842
- value: sellKey,
3843
- onChange: (e) => {
3844
- const found = sellOptions.find((o) => assetOptionKey(o) === e.target.value);
3845
- if (found) onSelectSell(found);
3846
- },
3847
- children: [
3848
- /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: "Select asset to sell" }),
3849
- sellOptions.map((o) => /* @__PURE__ */ jsxs("option", { value: assetOptionKey(o), children: [
3850
- o.code,
3851
- o.available !== void 0 ? ` \u2014 ${formatAmount2(o.available)} available` : ""
3852
- ] }, assetOptionKey(o)))
3853
- ]
3854
- }
3855
- )
3856
- ] }),
3857
- /* @__PURE__ */ jsxs("div", { className: "pollar-send-field", children: [
3858
- /* @__PURE__ */ jsxs("div", { className: "pollar-send-label-row", children: [
3859
- /* @__PURE__ */ jsx("label", { className: "pollar-send-label", children: "Amount" }),
3860
- selectedSell?.available !== void 0 && /* @__PURE__ */ jsxs("span", { className: "pollar-send-hint", children: [
3861
- "Available: ",
3862
- formatAmount2(selectedSell.available),
3863
- " ",
3864
- selectedSell.code
3907
+ ),
3908
+ /* @__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" }) }) })
3865
3909
  ] })
3866
3910
  ] }),
3867
- /* @__PURE__ */ jsx(
3868
- "input",
3869
- {
3870
- className: "pollar-input",
3871
- type: "text",
3872
- inputMode: "decimal",
3873
- placeholder: "0.00",
3874
- value: amount,
3875
- onChange: (e) => onAmountChange(e.target.value)
3876
- }
3877
- )
3878
- ] }),
3879
- /* @__PURE__ */ jsxs("div", { className: "pollar-send-field", children: [
3880
- /* @__PURE__ */ jsx("label", { className: "pollar-send-label", children: "You receive" }),
3881
- isLoadingData ? /* @__PURE__ */ jsx("div", { className: "pollar-send-skeleton" }) : /* @__PURE__ */ jsxs(
3882
- "select",
3883
- {
3884
- className: "pollar-input pollar-send-select",
3885
- value: buyKey,
3886
- onChange: (e) => {
3887
- const found = buyOptions.find((o) => assetOptionKey(o) === e.target.value);
3888
- if (found) onSelectBuy(found);
3889
- },
3890
- children: [
3891
- /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: "Select asset to buy" }),
3892
- buyOptions.map((o) => /* @__PURE__ */ jsxs("option", { value: assetOptionKey(o), children: [
3893
- o.code,
3894
- o.enabledInApp ? "" : " (external)"
3895
- ] }, assetOptionKey(o)))
3896
- ]
3897
- }
3898
- ),
3899
- !isLoadingData && (customOpen ? /* @__PURE__ */ jsxs("div", { className: "pollar-swap-custom", children: [
3911
+ step === "form" && configLoading && /* @__PURE__ */ jsx("div", { className: "pollar-send-hint", children: "Loading swap options\u2026" }),
3912
+ step === "form" && !configLoading && swapUnavailable && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: "Swap is not available for this app." }),
3913
+ step === "form" && !swapUnavailable && /* @__PURE__ */ jsxs(Fragment, { children: [
3914
+ smartUnsupported && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: "Swaps are not yet available for smart (passkey) wallets." }),
3900
3915
  /* @__PURE__ */ jsx(
3901
- "input",
3916
+ AssetSelect,
3902
3917
  {
3903
- className: "pollar-input",
3904
- type: "text",
3905
- placeholder: "Code (e.g. USDC)",
3906
- value: customCode,
3907
- onChange: (e) => setCustomCode(e.target.value)
3918
+ label: "You pay",
3919
+ value: sellKey,
3920
+ loading: isLoadingData,
3921
+ disabled: configLoading,
3922
+ options: sellOptions.map((o) => ({
3923
+ key: assetOptionKey(o),
3924
+ code: o.code,
3925
+ available: o.available,
3926
+ enabledInApp: o.enabledInApp
3927
+ })),
3928
+ onChange: (key) => {
3929
+ const found = sellOptions.find((o) => assetOptionKey(o) === key);
3930
+ if (found) onSelectSell(found);
3931
+ }
3908
3932
  }
3909
3933
  ),
3934
+ /* @__PURE__ */ jsxs("div", { className: "pollar-send-field", children: [
3935
+ /* @__PURE__ */ jsxs("div", { className: "pollar-send-label-row", children: [
3936
+ /* @__PURE__ */ jsx("label", { className: "pollar-send-label", children: "Amount" }),
3937
+ selectedSell?.available !== void 0 && /* @__PURE__ */ jsxs("span", { className: "pollar-send-hint", children: [
3938
+ "Available: ",
3939
+ formatAmount3(selectedSell.available),
3940
+ " ",
3941
+ selectedSell.code
3942
+ ] })
3943
+ ] }),
3944
+ /* @__PURE__ */ jsx(
3945
+ "input",
3946
+ {
3947
+ className: "pollar-input",
3948
+ type: "text",
3949
+ inputMode: "decimal",
3950
+ placeholder: "0.00",
3951
+ value: amount,
3952
+ disabled: configLoading,
3953
+ onChange: (e) => onAmountChange(e.target.value)
3954
+ }
3955
+ )
3956
+ ] }),
3910
3957
  /* @__PURE__ */ jsx(
3911
- "input",
3958
+ AssetSelect,
3912
3959
  {
3913
- className: "pollar-input",
3914
- type: "text",
3915
- placeholder: "Issuer (G...)",
3916
- value: customIssuer,
3917
- onChange: (e) => setCustomIssuer(e.target.value)
3960
+ label: "You receive",
3961
+ value: buyKey,
3962
+ loading: isLoadingData,
3963
+ disabled: configLoading,
3964
+ options: buyOptions.map((o) => ({
3965
+ key: assetOptionKey(o),
3966
+ code: o.code,
3967
+ enabledInApp: o.enabledInApp
3968
+ })),
3969
+ onChange: (key) => {
3970
+ const found = buyOptions.find((o) => assetOptionKey(o) === key);
3971
+ if (found) onSelectBuy(found);
3972
+ },
3973
+ children: customOpen ? /* @__PURE__ */ jsxs("div", { className: "pollar-swap-custom", children: [
3974
+ /* @__PURE__ */ jsx(
3975
+ "input",
3976
+ {
3977
+ className: "pollar-input",
3978
+ type: "text",
3979
+ placeholder: "Code (e.g. USDC)",
3980
+ value: customCode,
3981
+ onChange: (e) => setCustomCode(e.target.value)
3982
+ }
3983
+ ),
3984
+ /* @__PURE__ */ jsx(
3985
+ "input",
3986
+ {
3987
+ className: "pollar-input",
3988
+ type: "text",
3989
+ placeholder: "Issuer (G...)",
3990
+ value: customIssuer,
3991
+ onChange: (e) => setCustomIssuer(e.target.value)
3992
+ }
3993
+ ),
3994
+ customError && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: customError }),
3995
+ /* @__PURE__ */ jsxs("div", { className: "pollar-swap-custom-actions", children: [
3996
+ /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-btn-primary", onClick: submitCustomToken, children: "Add token" }),
3997
+ /* @__PURE__ */ jsx(
3998
+ "button",
3999
+ {
4000
+ type: "button",
4001
+ className: "pollar-swap-custom-cancel",
4002
+ onClick: () => {
4003
+ setCustomOpen(false);
4004
+ setCustomError("");
4005
+ },
4006
+ children: "Cancel"
4007
+ }
4008
+ )
4009
+ ] })
4010
+ ] }) : /* @__PURE__ */ jsx(
4011
+ "button",
4012
+ {
4013
+ type: "button",
4014
+ className: "pollar-swap-custom-toggle",
4015
+ disabled: configLoading,
4016
+ onClick: () => setCustomOpen(true),
4017
+ children: "+ Add a token by code / issuer"
4018
+ }
4019
+ )
3918
4020
  }
3919
4021
  ),
3920
- customError && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: customError }),
3921
- /* @__PURE__ */ jsxs("div", { className: "pollar-swap-custom-actions", children: [
3922
- /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-btn-primary", onClick: submitCustomToken, children: "Add token" }),
4022
+ /* @__PURE__ */ jsxs("div", { className: "pollar-send-field", children: [
4023
+ /* @__PURE__ */ jsx("label", { className: "pollar-send-label", children: "Route" }),
3923
4024
  /* @__PURE__ */ jsx(
3924
- "button",
4025
+ "select",
3925
4026
  {
3926
- type: "button",
3927
- className: "pollar-swap-custom-cancel",
3928
- onClick: () => {
3929
- setCustomOpen(false);
3930
- setCustomError("");
3931
- },
3932
- children: "Cancel"
4027
+ className: "pollar-input pollar-send-select",
4028
+ value: provider,
4029
+ disabled: configLoading || providers.length === 0,
4030
+ onChange: (e) => onProviderChange(e.target.value),
4031
+ 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))
3933
4032
  }
3934
4033
  )
3935
- ] })
3936
- ] }) : /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-swap-custom-toggle", onClick: () => setCustomOpen(true), children: "+ Add a token by code / issuer" }))
3937
- ] }),
3938
- /* @__PURE__ */ jsxs("div", { className: "pollar-send-field", children: [
3939
- /* @__PURE__ */ jsx("label", { className: "pollar-send-label", children: "Route" }),
3940
- /* @__PURE__ */ jsx(
3941
- "select",
4034
+ ] }),
4035
+ quoteLoading && /* @__PURE__ */ jsx("div", { className: "pollar-send-hint", children: "Fetching best price\u2026" }),
4036
+ !quoteLoading && quoteError && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: quoteError }),
4037
+ !quoteLoading && !quoteError && quote && selectedBuy && /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote", children: [
4038
+ /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote-row", children: [
4039
+ /* @__PURE__ */ jsx("span", { className: "pollar-send-hint", children: "You receive" }),
4040
+ /* @__PURE__ */ jsxs("span", { children: [
4041
+ "~ ",
4042
+ formatAmount3(quote.amountOut),
4043
+ " ",
4044
+ selectedBuy.code
4045
+ ] })
4046
+ ] }),
4047
+ /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote-row", children: [
4048
+ /* @__PURE__ */ jsx("span", { className: "pollar-send-hint", children: "Minimum received" }),
4049
+ /* @__PURE__ */ jsxs("span", { children: [
4050
+ formatAmount3(quote.minReceived),
4051
+ " ",
4052
+ selectedBuy.code
4053
+ ] })
4054
+ ] }),
4055
+ /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote-row", children: [
4056
+ /* @__PURE__ */ jsx("span", { className: "pollar-send-hint", children: "Price impact" }),
4057
+ /* @__PURE__ */ jsxs("span", { children: [
4058
+ quote.priceImpactPct,
4059
+ "%"
4060
+ ] })
4061
+ ] }),
4062
+ /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote-row", children: [
4063
+ /* @__PURE__ */ jsx("span", { className: "pollar-send-hint", children: "Route" }),
4064
+ /* @__PURE__ */ jsx("span", { children: PROVIDER_LABELS[quote.provider] })
4065
+ ] })
4066
+ ] }),
4067
+ !quoteLoading && !quoteError && !quote && selectedSell && selectedBuy && !!amount && /* @__PURE__ */ jsx("div", { className: "pollar-send-hint", children: "No route found for this pair." }),
4068
+ buyNeedsTrustline && selectedBuy && /* @__PURE__ */ jsxs("div", { className: "pollar-swap-trustline-notice", children: [
4069
+ "To receive ",
4070
+ selectedBuy.code,
4071
+ " your wallet needs a trustline. Swapping will create it first (~0.5 XLM reserve, refundable if you later remove it)."
4072
+ ] }),
4073
+ formError && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: formError }),
4074
+ /* @__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" }) })
4075
+ ] }),
4076
+ step === "tx" && /* @__PURE__ */ jsx(
4077
+ TxStatusView,
3942
4078
  {
3943
- className: "pollar-input pollar-send-select",
3944
- value: provider,
3945
- onChange: (e) => onProviderChange(e.target.value),
3946
- children: providers.map((p) => /* @__PURE__ */ jsx("option", { value: p, children: PROVIDER_LABELS[p] }, p))
4079
+ transaction,
4080
+ showXdr,
4081
+ copied,
4082
+ explorerUrl,
4083
+ walletType,
4084
+ onSignAndSend: () => {
4085
+ },
4086
+ onToggleXdr,
4087
+ onCopyHash,
4088
+ onRetry,
4089
+ onDone
3947
4090
  }
3948
- )
3949
- ] }),
3950
- quoteLoading && /* @__PURE__ */ jsx("div", { className: "pollar-send-hint", children: "Fetching best price\u2026" }),
3951
- !quoteLoading && quoteError && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: quoteError }),
3952
- !quoteLoading && !quoteError && quote && selectedBuy && /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote", children: [
3953
- /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote-row", children: [
3954
- /* @__PURE__ */ jsx("span", { className: "pollar-send-hint", children: "You receive" }),
3955
- /* @__PURE__ */ jsxs("span", { children: [
3956
- "~ ",
3957
- formatAmount2(quote.amountOut),
3958
- " ",
3959
- selectedBuy.code
3960
- ] })
3961
- ] }),
3962
- /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote-row", children: [
3963
- /* @__PURE__ */ jsx("span", { className: "pollar-send-hint", children: "Minimum received" }),
3964
- /* @__PURE__ */ jsxs("span", { children: [
3965
- formatAmount2(quote.minReceived),
3966
- " ",
3967
- selectedBuy.code
3968
- ] })
3969
- ] }),
3970
- /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote-row", children: [
3971
- /* @__PURE__ */ jsx("span", { className: "pollar-send-hint", children: "Price impact" }),
3972
- /* @__PURE__ */ jsxs("span", { children: [
3973
- quote.priceImpactPct,
3974
- "%"
3975
- ] })
3976
- ] }),
3977
- /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote-row", children: [
3978
- /* @__PURE__ */ jsx("span", { className: "pollar-send-hint", children: "Route" }),
3979
- /* @__PURE__ */ jsx("span", { children: PROVIDER_LABELS[quote.provider] })
3980
- ] })
3981
- ] }),
3982
- !quoteLoading && !quoteError && !quote && selectedSell && selectedBuy && !!amount && /* @__PURE__ */ jsx("div", { className: "pollar-send-hint", children: "No route found for this pair." }),
3983
- buyNeedsTrustline && selectedBuy && /* @__PURE__ */ jsxs("div", { className: "pollar-swap-trustline-notice", children: [
3984
- "To receive ",
3985
- selectedBuy.code,
3986
- " your wallet needs a trustline. Swapping will create it first (~0.5 XLM reserve, refundable if you later remove it)."
3987
- ] }),
3988
- formError && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: formError }),
3989
- /* @__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" }) })
3990
- ] }),
3991
- step === "tx" && /* @__PURE__ */ jsx(
3992
- TxStatusView,
3993
- {
3994
- transaction,
3995
- showXdr,
3996
- copied,
3997
- explorerUrl,
3998
- walletType,
3999
- onSignAndSend: () => {
4000
- },
4001
- onToggleXdr,
4002
- onCopyHash,
4003
- onRetry,
4004
- onDone
4005
- }
4006
- ),
4007
- /* @__PURE__ */ jsx(PollarModalFooter, {})
4008
- ] });
4091
+ ),
4092
+ /* @__PURE__ */ jsx(PollarModalFooter, {})
4093
+ ]
4094
+ }
4095
+ );
4009
4096
  }
4010
4097
  var QUOTE_DEBOUNCE_MS = 400;
4011
4098
  function toRef(a) {
@@ -4083,7 +4170,7 @@ function SwapModal({ onClose }) {
4083
4170
  const balances = walletBalance.step === "loaded" ? walletBalance.data.balances : [];
4084
4171
  const assetRecords = enabledAssets.step === "loaded" ? enabledAssets.data.assets : [];
4085
4172
  const isLoadingData = walletBalance.step === "loading" || enabledAssets.step === "loading";
4086
- 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 }));
4173
+ 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 }));
4087
4174
  const buyKeyOfSell = selectedSell ? `${selectedSell.code}:${selectedSell.issuer ?? "native"}` : "";
4088
4175
  const optKey = (o) => `${o.code}:${o.issuer ?? "native"}`;
4089
4176
  const enabledBuy = assetRecords.map((a) => ({
@@ -4101,9 +4188,19 @@ function SwapModal({ onClose }) {
4101
4188
  })).filter((o) => !enabledKeys.has(optKey(o)));
4102
4189
  const knownKeys = /* @__PURE__ */ new Set([...enabledKeys, ...catalogBuy.map(optKey)]);
4103
4190
  const customBuy = customTokens.filter((o) => !knownKeys.has(optKey(o)));
4104
- const buyOptions = [...enabledBuy, ...catalogBuy, ...customBuy].filter(
4105
- (o) => optKey(o) !== buyKeyOfSell
4106
- );
4191
+ const buyOptions = [...enabledBuy, ...catalogBuy, ...customBuy].filter((o) => optKey(o) !== buyKeyOfSell);
4192
+ useEffect(() => {
4193
+ if (sellOptions.length === 0) return;
4194
+ if (!selectedSell || !sellOptions.some((o) => optKey(o) === optKey(selectedSell))) {
4195
+ setSelectedSell(sellOptions[0]);
4196
+ }
4197
+ }, [sellOptions, selectedSell]);
4198
+ useEffect(() => {
4199
+ if (buyOptions.length === 0) return;
4200
+ if (!selectedBuy || !buyOptions.some((o) => optKey(o) === optKey(selectedBuy))) {
4201
+ setSelectedBuy(buyOptions[0]);
4202
+ }
4203
+ }, [buyOptions, selectedBuy]);
4107
4204
  function addCustomToken(code, issuer) {
4108
4205
  const c = code.trim().toUpperCase();
4109
4206
  const i = issuer.trim();
@@ -4162,7 +4259,7 @@ function SwapModal({ onClose }) {
4162
4259
  const buildData = "buildData" in transaction ? transaction.buildData : null;
4163
4260
  const explorerNetwork = buildData?.summary.network?.toLowerCase().includes("testnet") ? "testnet" : buildData ? "public" : network === "testnet" ? "testnet" : "public";
4164
4261
  const explorerUrl = hash ? `https://stellar.expert/explorer/${explorerNetwork}/tx/${hash}` : null;
4165
- const IN_FLIGHT_STEPS2 = [
4262
+ const IN_FLIGHT_STEPS3 = [
4166
4263
  "building",
4167
4264
  "signing",
4168
4265
  "submitting",
@@ -4170,7 +4267,7 @@ function SwapModal({ onClose }) {
4170
4267
  "signing-submitting",
4171
4268
  "building-signing-submitting"
4172
4269
  ];
4173
- const isInProgress = IN_FLIGHT_STEPS2.includes(transaction.step);
4270
+ const isInProgress = IN_FLIGHT_STEPS3.includes(transaction.step);
4174
4271
  const showBack = step === "tx" && (transaction.step === "error" || transaction.step === "success") && !isInProgress;
4175
4272
  const txTitle = isInProgress ? "Swapping\u2026" : transaction.step === "success" ? "Swapped!" : transaction.step === "error" ? "Swap failed" : "Confirm Swap";
4176
4273
  async function handleSwap() {
@@ -4264,6 +4361,314 @@ function SwapModal({ onClose }) {
4264
4361
  }
4265
4362
  ) });
4266
4363
  }
4364
+ var POSITION_POLL_MS = 1e4;
4365
+ var PROVIDER_LABELS2 = {
4366
+ blend: "Blend",
4367
+ defindex: "DeFindex"
4368
+ };
4369
+ var IN_FLIGHT_STEPS2 = ["building", "signing", "submitting", "submitted", "signing-submitting", "building-signing-submitting"];
4370
+ function formatAmount4(value) {
4371
+ const n = parseFloat(value);
4372
+ return isNaN(n) ? value : n.toLocaleString(void 0, { maximumFractionDigits: 7 });
4373
+ }
4374
+ function EarnModal({ onClose }) {
4375
+ const {
4376
+ getEarnProviders,
4377
+ getEarnOpportunities,
4378
+ getEarnPosition,
4379
+ earnDeposit,
4380
+ earnWithdraw,
4381
+ tx: transaction,
4382
+ wallet,
4383
+ network,
4384
+ styles
4385
+ } = usePollar();
4386
+ const walletType = wallet?.custody === "external" ? wallet.provider : null;
4387
+ const smartUnsupported = wallet?.custody === "smart";
4388
+ const { theme = "light", accentColor = "#005DB4" } = styles;
4389
+ const isDark = theme === "dark";
4390
+ const [step, setStep] = useState("form");
4391
+ const [tab, setTab] = useState("deposit");
4392
+ const [providers, setProviders] = useState(null);
4393
+ const [provider, setProvider] = useState(null);
4394
+ const [opportunities, setOpportunities] = useState([]);
4395
+ const [opportunityId, setOpportunityId] = useState("");
4396
+ const [position, setPosition] = useState(null);
4397
+ const [amount, setAmount] = useState("");
4398
+ const [loadingOpps, setLoadingOpps] = useState(false);
4399
+ const [formError, setFormError] = useState("");
4400
+ const [showXdr, setShowXdr] = useState(false);
4401
+ const [copied, setCopied] = useState(false);
4402
+ const copyTimerRef = useRef(null);
4403
+ const loadProviders = useCallback(() => {
4404
+ setProviders(null);
4405
+ return getEarnProviders().then((ps) => {
4406
+ setProviders(ps);
4407
+ setProvider((cur) => cur ?? ps[0] ?? null);
4408
+ }).catch(() => setProviders([]));
4409
+ }, [getEarnProviders]);
4410
+ useEffect(() => {
4411
+ void loadProviders();
4412
+ }, [loadProviders]);
4413
+ useEffect(() => {
4414
+ if (!provider) return;
4415
+ let cancelled = false;
4416
+ setLoadingOpps(true);
4417
+ getEarnOpportunities(provider).then((opps) => {
4418
+ if (cancelled) return;
4419
+ setOpportunities(opps);
4420
+ setOpportunityId((cur) => opps.some((o) => o.id === cur) ? cur : opps[0]?.id ?? "");
4421
+ }).catch(() => {
4422
+ if (!cancelled) setOpportunities([]);
4423
+ }).finally(() => {
4424
+ if (!cancelled) setLoadingOpps(false);
4425
+ });
4426
+ return () => {
4427
+ cancelled = true;
4428
+ };
4429
+ }, [provider, getEarnOpportunities]);
4430
+ const selectedOpportunity = opportunities.find((o) => o.id === opportunityId) ?? null;
4431
+ const refreshPosition = useCallback(() => {
4432
+ if (!provider || !opportunityId || !wallet) return;
4433
+ getEarnPosition({ provider, opportunity: opportunityId }).then(setPosition).catch(() => {
4434
+ });
4435
+ }, [provider, opportunityId, wallet, getEarnPosition]);
4436
+ useEffect(() => {
4437
+ setPosition(null);
4438
+ refreshPosition();
4439
+ }, [refreshPosition]);
4440
+ useEffect(() => {
4441
+ if (step !== "form" || !provider || !opportunityId) return;
4442
+ const id = setInterval(refreshPosition, POSITION_POLL_MS);
4443
+ return () => clearInterval(id);
4444
+ }, [step, provider, opportunityId, refreshPosition]);
4445
+ useEffect(
4446
+ () => () => {
4447
+ if (copyTimerRef.current !== null) clearTimeout(copyTimerRef.current);
4448
+ },
4449
+ []
4450
+ );
4451
+ const providersLoading = providers === null;
4452
+ const earnUnavailable = providers !== null && providers.length === 0;
4453
+ const withdrawUnit = position?.withdrawUnit ?? "asset";
4454
+ const assetCode = selectedOpportunity?.asset.code ?? "";
4455
+ const amountUnitLabel = tab === "deposit" ? assetCode : withdrawUnit === "shares" ? "shares" : assetCode;
4456
+ const hash = transaction.step === "success" ? transaction.hash : null;
4457
+ const buildData = "buildData" in transaction ? transaction.buildData : null;
4458
+ const explorerNetwork = buildData?.summary.network?.toLowerCase().includes("testnet") ? "testnet" : buildData ? "public" : network === "testnet" ? "testnet" : "public";
4459
+ const explorerUrl = hash ? `https://stellar.expert/explorer/${explorerNetwork}/tx/${hash}` : null;
4460
+ const isInProgress = IN_FLIGHT_STEPS2.includes(transaction.step);
4461
+ const showBack = step === "tx" && (transaction.step === "error" || transaction.step === "success") && !isInProgress;
4462
+ const txTitle = isInProgress ? tab === "deposit" ? "Depositing\u2026" : "Withdrawing\u2026" : transaction.step === "success" ? "Done!" : transaction.step === "error" ? tab === "deposit" ? "Deposit failed" : "Withdraw failed" : "Confirm";
4463
+ const canSubmit = !smartUnsupported && !!provider && !!opportunityId && !!amount && parseFloat(amount) > 0 && !providersLoading && !loadingOpps;
4464
+ const cssVars = {
4465
+ "--pollar-accent": accentColor,
4466
+ "--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
4467
+ "--pollar-border": isDark ? "#374151" : "#e5e7eb",
4468
+ "--pollar-text": isDark ? "#ffffff" : "#111827",
4469
+ "--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
4470
+ "--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
4471
+ "--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
4472
+ "--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
4473
+ "--pollar-error-text": isDark ? "#f87171" : "#dc2626",
4474
+ "--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
4475
+ "--pollar-buttons-border-radius": "6px",
4476
+ "--pollar-buttons-height": "44px",
4477
+ "--pollar-input-height": "44px",
4478
+ "--pollar-input-border-radius": "0.5rem",
4479
+ "--pollar-card-border-radius": "10px"
4480
+ };
4481
+ async function handleSubmit() {
4482
+ setFormError("");
4483
+ if (smartUnsupported) {
4484
+ setFormError("Earn is not yet supported for smart (passkey) wallets");
4485
+ return;
4486
+ }
4487
+ if (!provider || !opportunityId) {
4488
+ setFormError("Select a vault or pool");
4489
+ return;
4490
+ }
4491
+ const parsed = parseFloat(amount);
4492
+ if (!amount || isNaN(parsed) || parsed <= 0) {
4493
+ setFormError("Enter a valid amount");
4494
+ return;
4495
+ }
4496
+ if (tab === "withdraw" && position && parsed > parseFloat(position.withdrawable)) {
4497
+ setFormError("Amount exceeds your position");
4498
+ return;
4499
+ }
4500
+ setStep("tx");
4501
+ const params = { provider, opportunity: opportunityId, amount };
4502
+ const outcome = tab === "deposit" ? await earnDeposit(params) : await earnWithdraw(params);
4503
+ if (outcome.status === "success" || outcome.status === "pending") {
4504
+ setAmount("");
4505
+ refreshPosition();
4506
+ }
4507
+ }
4508
+ async function handleRetry() {
4509
+ if (transaction.step !== "error" || !provider || !opportunityId) return;
4510
+ const params = { provider, opportunity: opportunityId, amount };
4511
+ if (tab === "deposit") await earnDeposit(params);
4512
+ else await earnWithdraw(params);
4513
+ }
4514
+ function handleCopyHash() {
4515
+ if (!hash) return;
4516
+ navigator.clipboard.writeText(hash).then(() => {
4517
+ setCopied(true);
4518
+ if (copyTimerRef.current !== null) clearTimeout(copyTimerRef.current);
4519
+ copyTimerRef.current = setTimeout(() => {
4520
+ copyTimerRef.current = null;
4521
+ setCopied(false);
4522
+ }, 2e3);
4523
+ });
4524
+ }
4525
+ function handleBack() {
4526
+ setStep("form");
4527
+ setShowXdr(false);
4528
+ setCopied(false);
4529
+ refreshPosition();
4530
+ }
4531
+ const title = step === "form" ? "Earn" : txTitle;
4532
+ return /* @__PURE__ */ jsx("div", { className: "pollar-overlay", onClick: !isInProgress ? onClose : void 0, children: /* @__PURE__ */ jsxs("div", { className: "pollar-modal-card pollar-send-modal", "data-theme": theme, style: cssVars, onClick: (e) => e.stopPropagation(), children: [
4533
+ /* @__PURE__ */ jsxs("div", { className: "pollar-modal-header", children: [
4534
+ /* @__PURE__ */ jsxs("div", { className: "pollar-send-header-left", children: [
4535
+ showBack && /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-modal-close", onClick: handleBack, "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" }) }) }),
4536
+ /* @__PURE__ */ jsx("h2", { className: "pollar-modal-title", children: title })
4537
+ ] }),
4538
+ !isInProgress && /* @__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" }) }) })
4539
+ ] }),
4540
+ step === "form" && providersLoading && /* @__PURE__ */ jsx("div", { className: "pollar-send-hint", children: "Loading Earn options\u2026" }),
4541
+ step === "form" && earnUnavailable && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: "Earn is not available for this app." }),
4542
+ step === "form" && !earnUnavailable && /* @__PURE__ */ jsxs(Fragment, { children: [
4543
+ smartUnsupported && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: "Earn is not yet available for smart (passkey) wallets." }),
4544
+ /* @__PURE__ */ jsxs("div", { className: "pollar-earn-tabs", children: [
4545
+ /* @__PURE__ */ jsx(
4546
+ "button",
4547
+ {
4548
+ type: "button",
4549
+ className: `pollar-earn-tab${tab === "deposit" ? " pollar-earn-tab-active" : ""}`,
4550
+ onClick: () => {
4551
+ setTab("deposit");
4552
+ setFormError("");
4553
+ },
4554
+ children: "Deposit"
4555
+ }
4556
+ ),
4557
+ /* @__PURE__ */ jsx(
4558
+ "button",
4559
+ {
4560
+ type: "button",
4561
+ className: `pollar-earn-tab${tab === "withdraw" ? " pollar-earn-tab-active" : ""}`,
4562
+ onClick: () => {
4563
+ setTab("withdraw");
4564
+ setFormError("");
4565
+ },
4566
+ children: "Withdraw"
4567
+ }
4568
+ )
4569
+ ] }),
4570
+ providers && providers.length > 1 && /* @__PURE__ */ jsxs("div", { className: "pollar-send-field", children: [
4571
+ /* @__PURE__ */ jsx("label", { className: "pollar-send-label", children: "Provider" }),
4572
+ /* @__PURE__ */ jsx(
4573
+ "select",
4574
+ {
4575
+ className: "pollar-input pollar-send-select",
4576
+ value: provider ?? "",
4577
+ onChange: (e) => setProvider(e.target.value),
4578
+ children: providers.map((p) => /* @__PURE__ */ jsx("option", { value: p, children: PROVIDER_LABELS2[p] }, p))
4579
+ }
4580
+ )
4581
+ ] }),
4582
+ /* @__PURE__ */ jsxs("div", { className: "pollar-send-field", children: [
4583
+ /* @__PURE__ */ jsx("label", { className: "pollar-send-label", children: provider === "defindex" ? "Vault" : "Pool" }),
4584
+ /* @__PURE__ */ jsx(
4585
+ "select",
4586
+ {
4587
+ className: "pollar-input pollar-send-select",
4588
+ value: opportunityId,
4589
+ disabled: loadingOpps || opportunities.length === 0,
4590
+ onChange: (e) => setOpportunityId(e.target.value),
4591
+ children: opportunities.length === 0 ? /* @__PURE__ */ jsx("option", { value: "", children: loadingOpps ? "Loading\u2026" : "None available" }) : opportunities.map((o) => /* @__PURE__ */ jsxs("option", { value: o.id, children: [
4592
+ o.name,
4593
+ " \xB7 ",
4594
+ o.apy.toFixed(2),
4595
+ "% APY"
4596
+ ] }, o.id))
4597
+ }
4598
+ )
4599
+ ] }),
4600
+ selectedOpportunity && /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote", children: [
4601
+ /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote-row", children: [
4602
+ /* @__PURE__ */ jsx("span", { className: "pollar-send-hint", children: "Your position" }),
4603
+ /* @__PURE__ */ jsxs("span", { children: [
4604
+ position ? formatAmount4(position.balance) : "\u2026",
4605
+ " ",
4606
+ assetCode
4607
+ ] })
4608
+ ] }),
4609
+ /* @__PURE__ */ jsxs("div", { className: "pollar-swap-quote-row", children: [
4610
+ /* @__PURE__ */ jsx("span", { className: "pollar-send-hint", children: "APY" }),
4611
+ /* @__PURE__ */ jsxs("span", { className: "pollar-earn-live", children: [
4612
+ selectedOpportunity.apy.toFixed(2),
4613
+ "%"
4614
+ ] })
4615
+ ] })
4616
+ ] }),
4617
+ /* @__PURE__ */ jsxs("div", { className: "pollar-send-field", children: [
4618
+ /* @__PURE__ */ jsxs("div", { className: "pollar-send-label-row", children: [
4619
+ /* @__PURE__ */ jsx("label", { className: "pollar-send-label", children: tab === "deposit" ? "Amount" : "Withdraw amount" }),
4620
+ tab === "withdraw" && position && /* @__PURE__ */ jsxs(
4621
+ "button",
4622
+ {
4623
+ type: "button",
4624
+ className: "pollar-swap-custom-toggle",
4625
+ onClick: () => setAmount(position.withdrawable),
4626
+ children: [
4627
+ "Max: ",
4628
+ formatAmount4(position.withdrawable),
4629
+ " ",
4630
+ amountUnitLabel
4631
+ ]
4632
+ }
4633
+ )
4634
+ ] }),
4635
+ /* @__PURE__ */ jsxs("div", { className: "pollar-earn-amount", children: [
4636
+ /* @__PURE__ */ jsx(
4637
+ "input",
4638
+ {
4639
+ className: "pollar-input",
4640
+ type: "text",
4641
+ inputMode: "decimal",
4642
+ placeholder: "0.00",
4643
+ value: amount,
4644
+ onChange: (e) => setAmount(e.target.value)
4645
+ }
4646
+ ),
4647
+ amountUnitLabel && /* @__PURE__ */ jsx("span", { className: "pollar-earn-amount-unit", children: amountUnitLabel })
4648
+ ] })
4649
+ ] }),
4650
+ formError && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: formError }),
4651
+ /* @__PURE__ */ jsx("div", { className: "pollar-modal-actions", children: /* @__PURE__ */ jsx("button", { className: "pollar-btn-primary", onClick: () => void handleSubmit(), disabled: !canSubmit, children: tab === "deposit" ? "Deposit" : "Withdraw" }) })
4652
+ ] }),
4653
+ step === "tx" && /* @__PURE__ */ jsx(
4654
+ TxStatusView,
4655
+ {
4656
+ transaction,
4657
+ showXdr,
4658
+ copied,
4659
+ explorerUrl,
4660
+ walletType,
4661
+ onSignAndSend: () => {
4662
+ },
4663
+ onToggleXdr: () => setShowXdr((v) => !v),
4664
+ onCopyHash: handleCopyHash,
4665
+ onRetry: () => void handleRetry(),
4666
+ onDone: onClose
4667
+ }
4668
+ ),
4669
+ /* @__PURE__ */ jsx(PollarModalFooter, {})
4670
+ ] }) });
4671
+ }
4267
4672
  function describeDevice(s) {
4268
4673
  if (s.deviceLabel) return s.deviceLabel;
4269
4674
  if (!s.userAgent) return "Unknown device";
@@ -4613,6 +5018,33 @@ function StatusBadge({ status }) {
4613
5018
  function formatDate(iso) {
4614
5019
  return new Date(iso).toLocaleDateString(void 0, { month: "short", day: "numeric", year: "numeric" });
4615
5020
  }
5021
+ function truncateMiddle(value, head = 4, tail = 4) {
5022
+ return value.length <= head + tail + 1 ? value : `${value.slice(0, head)}\u2026${value.slice(-tail)}`;
5023
+ }
5024
+ var STELLAR_ADDRESS = /\b[GC][A-Z2-7]{55}\b/g;
5025
+ function AddressChip({ value, label }) {
5026
+ return /* @__PURE__ */ jsxs("span", { className: "pollar-hist-item-issuer", children: [
5027
+ truncateMiddle(value),
5028
+ /* @__PURE__ */ jsx(CopyButton, { value, label, className: "pollar-copy-btn-sm" })
5029
+ ] });
5030
+ }
5031
+ function renderSummary(summary) {
5032
+ const parts = [];
5033
+ let last = 0;
5034
+ let key = 0;
5035
+ STELLAR_ADDRESS.lastIndex = 0;
5036
+ for (let m = STELLAR_ADDRESS.exec(summary); m !== null; m = STELLAR_ADDRESS.exec(summary)) {
5037
+ if (m.index > last) parts.push(/* @__PURE__ */ jsx("span", { children: summary.slice(last, m.index) }, key++));
5038
+ const address = m[0];
5039
+ parts.push(
5040
+ /* @__PURE__ */ jsx(AddressChip, { value: address, label: address[0] === "C" ? "Copy contract address" : "Copy wallet address" }, key++)
5041
+ );
5042
+ last = m.index + address.length;
5043
+ }
5044
+ if (parts.length === 0) return /* @__PURE__ */ jsx("span", { className: "pollar-hist-item-title", children: summary });
5045
+ if (last < summary.length) parts.push(/* @__PURE__ */ jsx("span", { children: summary.slice(last) }, key++));
5046
+ return parts;
5047
+ }
4616
5048
  function TxHistoryModalTemplate({
4617
5049
  theme,
4618
5050
  accentColor,
@@ -4685,11 +5117,35 @@ function TxHistoryModalTemplate({
4685
5117
  txHistory.step === "error" && /* @__PURE__ */ jsx("div", { className: "pollar-modal-empty", children: txHistory.message }),
4686
5118
  txHistory.step === "loaded" && records.length === 0 && /* @__PURE__ */ jsx("div", { className: "pollar-modal-empty", children: "No transactions yet." }),
4687
5119
  records.map((record) => {
4688
- const explorerUrl = `https://stellar.expert/explorer/${record.network === "testnet" ? "testnet" : "public"}/tx/${record.hash}`;
4689
- const destination = typeof record.details?.destination === "string" ? record.details.destination : void 0;
5120
+ const hash = typeof record.hash === "string" && record.hash.length > 0 ? record.hash : void 0;
5121
+ const explorerUrl = hash ? `https://stellar.expert/explorer/${record.network === "testnet" ? "testnet" : "public"}/tx/${hash}` : void 0;
5122
+ const asset = typeof record.details?.asset === "string" ? record.details.asset : void 0;
5123
+ const colon = asset ? asset.indexOf(":") : -1;
5124
+ const trustline = record.operation === "change_trust" && asset && colon > 0 ? {
5125
+ prefix: record.summary.split(":")[0],
5126
+ code: asset.slice(0, colon),
5127
+ issuer: asset.slice(colon + 1)
5128
+ } : void 0;
5129
+ const contract = record.operation === "invoke_contract" && typeof record.details?.contractId === "string" && typeof record.details?.method === "string" ? { method: record.details.method, contractId: record.details.contractId } : void 0;
4690
5130
  return /* @__PURE__ */ jsxs("div", { className: "pollar-hist-item", children: [
4691
- /* @__PURE__ */ jsx("span", { className: "pollar-hist-item-summary", children: record.summary }),
4692
- /* @__PURE__ */ jsx(StatusBadge, { status: record.status }),
5131
+ /* @__PURE__ */ jsxs("div", { className: "pollar-hist-item-top", children: [
5132
+ /* @__PURE__ */ jsx("span", { className: "pollar-hist-item-summary", children: trustline ? /* @__PURE__ */ jsxs(Fragment, { children: [
5133
+ /* @__PURE__ */ jsxs("span", { className: "pollar-hist-item-title", children: [
5134
+ trustline.prefix,
5135
+ ": ",
5136
+ trustline.code
5137
+ ] }),
5138
+ /* @__PURE__ */ jsx(AddressChip, { value: trustline.issuer, label: "Copy issuer" })
5139
+ ] }) : contract ? /* @__PURE__ */ jsxs(Fragment, { children: [
5140
+ /* @__PURE__ */ jsxs("span", { className: "pollar-hist-item-title", children: [
5141
+ "Invoke ",
5142
+ contract.method,
5143
+ "() on"
5144
+ ] }),
5145
+ /* @__PURE__ */ jsx(AddressChip, { value: contract.contractId, label: "Copy contract address" })
5146
+ ] }) : renderSummary(record.summary) }),
5147
+ /* @__PURE__ */ jsx(StatusBadge, { status: record.status })
5148
+ ] }),
4693
5149
  /* @__PURE__ */ jsxs("span", { className: "pollar-hist-item-meta", children: [
4694
5150
  /* @__PURE__ */ jsx("span", { children: record.operation }),
4695
5151
  typeof record.details?.sponsored === "boolean" && /* @__PURE__ */ jsxs("span", { children: [
@@ -4700,26 +5156,23 @@ function TxHistoryModalTemplate({
4700
5156
  "\xB7 ",
4701
5157
  record.feeXlm,
4702
5158
  " XLM"
4703
- ] }),
4704
- /* @__PURE__ */ jsxs("span", { children: [
4705
- "\xB7 ",
4706
- formatDate(record.createdAt)
4707
- ] }),
4708
- destination && /* @__PURE__ */ jsxs(Fragment, { children: [
4709
- /* @__PURE__ */ jsx("span", { children: "\xB7" }),
4710
- /* @__PURE__ */ jsx(CopyButton, { value: destination, label: "Copy wallet address", className: "pollar-copy-btn-sm" })
4711
- ] }),
4712
- /* @__PURE__ */ jsx("span", { children: "\xB7" }),
4713
- /* @__PURE__ */ jsxs(
4714
- "a",
4715
- {
4716
- className: "pollar-hist-item-explorer",
4717
- href: explorerUrl,
4718
- target: "_blank",
4719
- rel: "noopener noreferrer",
4720
- "aria-label": "View on Stellar Explorer",
4721
- children: [
4722
- /* @__PURE__ */ jsxs("svg", { width: "11", height: "11", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
5159
+ ] })
5160
+ ] }),
5161
+ /* @__PURE__ */ jsxs("div", { className: "pollar-hist-item-footer", children: [
5162
+ /* @__PURE__ */ jsx("span", { children: formatDate(record.createdAt) }),
5163
+ hash && /* @__PURE__ */ jsxs(Fragment, { children: [
5164
+ /* @__PURE__ */ jsx("span", { className: "pollar-hist-item-dot", children: "\xB7" }),
5165
+ /* @__PURE__ */ jsx("span", { className: "pollar-hist-item-hash", children: truncateMiddle(hash, 6, 6) }),
5166
+ /* @__PURE__ */ jsx(CopyButton, { value: hash, label: "Copy transaction hash", className: "pollar-copy-btn-sm" }),
5167
+ /* @__PURE__ */ jsx(
5168
+ "a",
5169
+ {
5170
+ className: "pollar-hist-item-explorer",
5171
+ href: explorerUrl,
5172
+ target: "_blank",
5173
+ rel: "noopener noreferrer",
5174
+ "aria-label": "View on Stellar Explorer",
5175
+ children: /* @__PURE__ */ jsxs("svg", { width: "12", height: "12", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
4723
5176
  /* @__PURE__ */ jsx(
4724
5177
  "path",
4725
5178
  {
@@ -4739,11 +5192,10 @@ function TxHistoryModalTemplate({
4739
5192
  strokeLinejoin: "round"
4740
5193
  }
4741
5194
  )
4742
- ] }),
4743
- "Explorer"
4744
- ]
4745
- }
4746
- )
5195
+ ] })
5196
+ }
5197
+ )
5198
+ ] })
4747
5199
  ] })
4748
5200
  ] }, record.id);
4749
5201
  })
@@ -5089,6 +5541,7 @@ function PollarProvider({
5089
5541
  const [enabledAssetsModalOpen, setEnabledAssetsModalOpen] = useState(false);
5090
5542
  const [sendModalOpen, setSendModalOpen] = useState(false);
5091
5543
  const [swapModalOpen, setSwapModalOpen] = useState(false);
5544
+ const [earnModalOpen, setEarnModalOpen] = useState(false);
5092
5545
  const [receiveModalOpen, setReceiveModalOpen] = useState(false);
5093
5546
  const [sessionsModalOpen, setSessionsModalOpen] = useState(false);
5094
5547
  const [distributionRulesModalOpen, setDistributionRulesModalOpen] = useState(false);
@@ -5139,6 +5592,13 @@ function PollarProvider({
5139
5592
  getSwapQuote: (params) => pollarClient.getSwapQuote(params),
5140
5593
  swap: (quote, opts) => pollarClient.swap(quote, opts),
5141
5594
  openSwapModal: () => setSwapModalOpen(true),
5595
+ // earn
5596
+ getEarnProviders: () => pollarClient.getEarnProviders(),
5597
+ getEarnOpportunities: (provider) => pollarClient.getEarnOpportunities(provider),
5598
+ getEarnPosition: (params) => pollarClient.getEarnPosition(params),
5599
+ earnDeposit: (params) => pollarClient.earnDeposit(params),
5600
+ earnWithdraw: (params) => pollarClient.earnWithdraw(params),
5601
+ openEarnModal: () => setEarnModalOpen(true),
5142
5602
  // sessions
5143
5603
  sessions,
5144
5604
  openSessionsModal: () => setSessionsModalOpen(true),
@@ -5194,6 +5654,7 @@ function PollarProvider({
5194
5654
  enabledAssetsModalOpen && /* @__PURE__ */ jsx(ModalErrorBoundary, { onClose: () => setEnabledAssetsModalOpen(false), children: /* @__PURE__ */ jsx(EnabledAssetsModal, { onClose: () => setEnabledAssetsModalOpen(false) }) }),
5195
5655
  sendModalOpen && /* @__PURE__ */ jsx(ModalErrorBoundary, { onClose: () => setSendModalOpen(false), children: /* @__PURE__ */ jsx(SendModal, { onClose: () => setSendModalOpen(false) }) }),
5196
5656
  swapModalOpen && /* @__PURE__ */ jsx(ModalErrorBoundary, { onClose: () => setSwapModalOpen(false), children: /* @__PURE__ */ jsx(SwapModal, { onClose: () => setSwapModalOpen(false) }) }),
5657
+ earnModalOpen && /* @__PURE__ */ jsx(ModalErrorBoundary, { onClose: () => setEarnModalOpen(false), children: /* @__PURE__ */ jsx(EarnModal, { onClose: () => setEarnModalOpen(false) }) }),
5197
5658
  receiveModalOpen && /* @__PURE__ */ jsx(ModalErrorBoundary, { onClose: () => setReceiveModalOpen(false), children: /* @__PURE__ */ jsx(ReceiveModal, { onClose: () => setReceiveModalOpen(false) }) }),
5198
5659
  sessionsModalOpen && /* @__PURE__ */ jsx(ModalErrorBoundary, { onClose: () => setSessionsModalOpen(false), children: /* @__PURE__ */ jsx(SessionsModal, { onClose: () => setSessionsModalOpen(false) }) }),
5199
5660
  distributionRulesModalOpen && /* @__PURE__ */ jsx(ModalErrorBoundary, { onClose: () => setDistributionRulesModalOpen(false), children: /* @__PURE__ */ jsx(DistributionRulesModal, { onClose: () => setDistributionRulesModalOpen(false) }) })
@@ -5243,7 +5704,10 @@ function WalletButtonTemplate({
5243
5704
  itemColor,
5244
5705
  wrapperRef,
5245
5706
  isInProgress,
5707
+ showCreateAccount,
5708
+ creatingAccount,
5246
5709
  onToggleOpen,
5710
+ onCreateAccount,
5247
5711
  onCopy,
5248
5712
  onWalletBalance,
5249
5713
  onTxHistory,
@@ -5305,6 +5769,40 @@ function WalletButtonTemplate({
5305
5769
  }
5306
5770
  ),
5307
5771
  open && /* @__PURE__ */ jsxs("div", { className: "wallet-dropdown", style: { backgroundColor: dropdownBg, borderColor: dropdownBorder }, children: [
5772
+ showCreateAccount && /* @__PURE__ */ jsxs(Fragment, { children: [
5773
+ /* @__PURE__ */ jsxs(
5774
+ "button",
5775
+ {
5776
+ className: "wallet-dropdown-item",
5777
+ style: { color: itemColor },
5778
+ onClick: onCreateAccount,
5779
+ disabled: creatingAccount,
5780
+ children: [
5781
+ /* @__PURE__ */ jsxs(
5782
+ "svg",
5783
+ {
5784
+ width: "14",
5785
+ height: "14",
5786
+ viewBox: "0 0 24 24",
5787
+ fill: "none",
5788
+ stroke: "currentColor",
5789
+ strokeWidth: "2",
5790
+ strokeLinecap: "round",
5791
+ strokeLinejoin: "round",
5792
+ children: [
5793
+ /* @__PURE__ */ jsx("path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }),
5794
+ /* @__PURE__ */ jsx("circle", { cx: "9", cy: "7", r: "4" }),
5795
+ /* @__PURE__ */ jsx("line", { x1: "19", y1: "8", x2: "19", y2: "14" }),
5796
+ /* @__PURE__ */ jsx("line", { x1: "22", y1: "11", x2: "16", y2: "11" })
5797
+ ]
5798
+ }
5799
+ ),
5800
+ creatingAccount ? "Creating account\u2026" : "Create account"
5801
+ ]
5802
+ }
5803
+ ),
5804
+ /* @__PURE__ */ jsx("div", { className: "wallet-dropdown-divider" })
5805
+ ] }),
5308
5806
  /* @__PURE__ */ jsxs("button", { className: "wallet-dropdown-item", style: { color: itemColor }, onClick: onSend, children: [
5309
5807
  /* @__PURE__ */ jsxs(
5310
5808
  "svg",
@@ -5544,9 +6042,12 @@ function WalletButton() {
5544
6042
  const walletType = wallet?.custody === "external" ? wallet.provider : null;
5545
6043
  const [open, setOpen] = useState(false);
5546
6044
  const [copied, setCopied] = useState(false);
6045
+ const [creating, setCreating] = useState(false);
6046
+ const [created, setCreated] = useState(false);
5547
6047
  const wrapperRef = useRef(null);
5548
6048
  const copyTimerRef = useRef(null);
5549
6049
  const isInProgress = transaction.step === "building" || transaction.step === "signing";
6050
+ const canCreateAccount = !created && wallet?.custody === "external" && wallet.existsOnStellar === false && wallet.fundingMode === "IMMEDIATE";
5550
6051
  const { theme = "light", accentColor = "#005DB4" } = styles;
5551
6052
  const isDark = theme === "dark";
5552
6053
  const dropdownBg = isDark ? "#18181b" : "#fff";
@@ -5581,6 +6082,20 @@ function WalletButton() {
5581
6082
  setOpen(false);
5582
6083
  getClient().logout();
5583
6084
  }
6085
+ async function handleCreateAccount() {
6086
+ if (creating) return;
6087
+ setCreating(true);
6088
+ try {
6089
+ const res = await getClient().createAccount();
6090
+ if (res.status === "success" || res.status === "pending") {
6091
+ setCreated(true);
6092
+ setOpen(false);
6093
+ await getClient().refreshBalance();
6094
+ }
6095
+ } finally {
6096
+ setCreating(false);
6097
+ }
6098
+ }
5584
6099
  function handleWalletBalance() {
5585
6100
  setOpen(false);
5586
6101
  openWalletBalanceModal();
@@ -5626,7 +6141,10 @@ function WalletButton() {
5626
6141
  wrapperRef,
5627
6142
  isInProgress,
5628
6143
  walletType,
6144
+ showCreateAccount: canCreateAccount,
6145
+ creatingAccount: creating,
5629
6146
  onToggleOpen: () => setOpen((v) => !v),
6147
+ onCreateAccount: handleCreateAccount,
5630
6148
  onCopy: handleCopy,
5631
6149
  onWalletBalance: handleWalletBalance,
5632
6150
  onTxHistory: handleTxHistory,
@@ -5642,6 +6160,6 @@ function WalletButton() {
5642
6160
  );
5643
6161
  }
5644
6162
 
5645
- export { DistributionRulesModal, DistributionRulesModalTemplate, EnabledAssetsModal, EnabledAssetsModalTemplate, KycModal, KycModalTemplate, KycStatus, LoginModalTemplate, PollarProvider, RampWidget, RampWidgetTemplate, ReceiveModal, ReceiveModalTemplate, RouteDisplay, SendModal, SendModalTemplate, SessionsModal, SessionsModalTemplate, SwapModal, SwapModalTemplate, TransactionModalTemplate, TxHistoryModalTemplate, TxStatusView, WalletBalanceModal, WalletBalanceModalTemplate, WalletButton, WalletButtonTemplate, createPollarAdapterHook, usePollar };
6163
+ export { DistributionRulesModal, DistributionRulesModalTemplate, EarnModal, EnabledAssetsModal, EnabledAssetsModalTemplate, KycModal, KycModalTemplate, KycStatus, LoginModalTemplate, PollarProvider, RampWidget, RampWidgetTemplate, ReceiveModal, ReceiveModalTemplate, RouteDisplay, SendModal, SendModalTemplate, SessionsModal, SessionsModalTemplate, SwapModal, SwapModalTemplate, TransactionModalTemplate, TxHistoryModalTemplate, TxStatusView, WalletBalanceModal, WalletBalanceModalTemplate, WalletButton, WalletButtonTemplate, createPollarAdapterHook, usePollar };
5646
6164
  //# sourceMappingURL=index.mjs.map
5647
6165
  //# sourceMappingURL=index.mjs.map