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

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.5"
1036
+ "0.10.1-rc.7"
1037
1037
  ] })
1038
1038
  ] })
1039
1039
  ] });
@@ -2554,12 +2554,23 @@ var INSTRUCTION_LABELS = {
2554
2554
  function flattenInstructions(instr) {
2555
2555
  const out = [];
2556
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
+ }
2557
2568
  let value = "";
2558
2569
  if (typeof v === "string" || typeof v === "number") value = String(v);
2559
2570
  else if (Array.isArray(v)) value = v.filter((x) => typeof x === "string" || typeof x === "number").join(", ");
2560
2571
  else continue;
2561
2572
  if (!value) continue;
2562
- out.push({ key: k, label: INSTRUCTION_LABELS[k] ?? k, value });
2573
+ out.push({ key: k, label: INSTRUCTION_LABELS[k] ?? k, value, kind: "text" });
2563
2574
  }
2564
2575
  return out;
2565
2576
  }
@@ -2785,9 +2796,16 @@ function RampWidgetTemplate({
2785
2796
  stellarTxHash.slice(-8)
2786
2797
  ] }) })
2787
2798
  ] }),
2788
- 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: [
2789
2800
  /* @__PURE__ */ jsx("span", { className: "pollar-ramp-payment-label", children: label }),
2790
- /* @__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 }) })
2791
2809
  ] }, key)),
2792
2810
  tosUrl && !depositInstructions && txStatus !== "completed" && /* @__PURE__ */ jsxs("button", { type: "button", className: "pollar-btn-primary", onClick: onOpenTos, children: [
2793
2811
  "Accept terms at ",
@@ -3667,7 +3685,7 @@ function SendModal({ onClose }) {
3667
3685
  const buildData = "buildData" in transaction ? transaction.buildData : null;
3668
3686
  const explorerNetwork = buildData?.summary.network?.toLowerCase().includes("testnet") ? "testnet" : buildData ? "public" : network === "testnet" ? "testnet" : "public";
3669
3687
  const explorerUrl = hash ? `https://stellar.expert/explorer/${explorerNetwork}/tx/${hash}` : null;
3670
- const IN_FLIGHT_STEPS2 = [
3688
+ const IN_FLIGHT_STEPS3 = [
3671
3689
  "building",
3672
3690
  "signing",
3673
3691
  "submitting",
@@ -3675,7 +3693,7 @@ function SendModal({ onClose }) {
3675
3693
  "signing-submitting",
3676
3694
  "building-signing-submitting"
3677
3695
  ];
3678
- const isInProgress = IN_FLIGHT_STEPS2.includes(transaction.step);
3696
+ const isInProgress = IN_FLIGHT_STEPS3.includes(transaction.step);
3679
3697
  const showBack = step === "tx" && (transaction.step === "error" || transaction.step === "success") && !isInProgress;
3680
3698
  const txTitle = isInProgress ? "Sending\u2026" : transaction.step === "success" ? "Sent!" : transaction.step === "error" ? "Send failed" : "Confirm Send";
3681
3699
  async function handleSubmit() {
@@ -4241,7 +4259,7 @@ function SwapModal({ onClose }) {
4241
4259
  const buildData = "buildData" in transaction ? transaction.buildData : null;
4242
4260
  const explorerNetwork = buildData?.summary.network?.toLowerCase().includes("testnet") ? "testnet" : buildData ? "public" : network === "testnet" ? "testnet" : "public";
4243
4261
  const explorerUrl = hash ? `https://stellar.expert/explorer/${explorerNetwork}/tx/${hash}` : null;
4244
- const IN_FLIGHT_STEPS2 = [
4262
+ const IN_FLIGHT_STEPS3 = [
4245
4263
  "building",
4246
4264
  "signing",
4247
4265
  "submitting",
@@ -4249,7 +4267,7 @@ function SwapModal({ onClose }) {
4249
4267
  "signing-submitting",
4250
4268
  "building-signing-submitting"
4251
4269
  ];
4252
- const isInProgress = IN_FLIGHT_STEPS2.includes(transaction.step);
4270
+ const isInProgress = IN_FLIGHT_STEPS3.includes(transaction.step);
4253
4271
  const showBack = step === "tx" && (transaction.step === "error" || transaction.step === "success") && !isInProgress;
4254
4272
  const txTitle = isInProgress ? "Swapping\u2026" : transaction.step === "success" ? "Swapped!" : transaction.step === "error" ? "Swap failed" : "Confirm Swap";
4255
4273
  async function handleSwap() {
@@ -4343,6 +4361,314 @@ function SwapModal({ onClose }) {
4343
4361
  }
4344
4362
  ) });
4345
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
+ }
4346
4672
  function describeDevice(s) {
4347
4673
  if (s.deviceLabel) return s.deviceLabel;
4348
4674
  if (!s.userAgent) return "Unknown device";
@@ -4695,6 +5021,30 @@ function formatDate(iso) {
4695
5021
  function truncateMiddle(value, head = 4, tail = 4) {
4696
5022
  return value.length <= head + tail + 1 ? value : `${value.slice(0, head)}\u2026${value.slice(-tail)}`;
4697
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
+ }
4698
5048
  function TxHistoryModalTemplate({
4699
5049
  theme,
4700
5050
  accentColor,
@@ -4769,7 +5119,6 @@ function TxHistoryModalTemplate({
4769
5119
  records.map((record) => {
4770
5120
  const hash = typeof record.hash === "string" && record.hash.length > 0 ? record.hash : void 0;
4771
5121
  const explorerUrl = hash ? `https://stellar.expert/explorer/${record.network === "testnet" ? "testnet" : "public"}/tx/${hash}` : void 0;
4772
- const destination = typeof record.details?.destination === "string" ? record.details.destination : void 0;
4773
5122
  const asset = typeof record.details?.asset === "string" ? record.details.asset : void 0;
4774
5123
  const colon = asset ? asset.indexOf(":") : -1;
4775
5124
  const trustline = record.operation === "change_trust" && asset && colon > 0 ? {
@@ -4777,6 +5126,7 @@ function TxHistoryModalTemplate({
4777
5126
  code: asset.slice(0, colon),
4778
5127
  issuer: asset.slice(colon + 1)
4779
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;
4780
5130
  return /* @__PURE__ */ jsxs("div", { className: "pollar-hist-item", children: [
4781
5131
  /* @__PURE__ */ jsxs("div", { className: "pollar-hist-item-top", children: [
4782
5132
  /* @__PURE__ */ jsx("span", { className: "pollar-hist-item-summary", children: trustline ? /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -4785,11 +5135,15 @@ function TxHistoryModalTemplate({
4785
5135
  ": ",
4786
5136
  trustline.code
4787
5137
  ] }),
4788
- /* @__PURE__ */ jsxs("span", { className: "pollar-hist-item-issuer", children: [
4789
- truncateMiddle(trustline.issuer),
4790
- /* @__PURE__ */ jsx(CopyButton, { value: trustline.issuer, label: "Copy issuer", className: "pollar-copy-btn-sm" })
4791
- ] })
4792
- ] }) : /* @__PURE__ */ jsx("span", { className: "pollar-hist-item-title", children: record.summary }) }),
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) }),
4793
5147
  /* @__PURE__ */ jsx(StatusBadge, { status: record.status })
4794
5148
  ] }),
4795
5149
  /* @__PURE__ */ jsxs("span", { className: "pollar-hist-item-meta", children: [
@@ -4802,13 +5156,6 @@ function TxHistoryModalTemplate({
4802
5156
  "\xB7 ",
4803
5157
  record.feeXlm,
4804
5158
  " XLM"
4805
- ] }),
4806
- destination && /* @__PURE__ */ jsxs(Fragment, { children: [
4807
- /* @__PURE__ */ jsx("span", { children: "\xB7" }),
4808
- /* @__PURE__ */ jsxs("span", { className: "pollar-hist-item-issuer", children: [
4809
- truncateMiddle(destination),
4810
- /* @__PURE__ */ jsx(CopyButton, { value: destination, label: "Copy wallet address", className: "pollar-copy-btn-sm" })
4811
- ] })
4812
5159
  ] })
4813
5160
  ] }),
4814
5161
  /* @__PURE__ */ jsxs("div", { className: "pollar-hist-item-footer", children: [
@@ -5194,6 +5541,7 @@ function PollarProvider({
5194
5541
  const [enabledAssetsModalOpen, setEnabledAssetsModalOpen] = useState(false);
5195
5542
  const [sendModalOpen, setSendModalOpen] = useState(false);
5196
5543
  const [swapModalOpen, setSwapModalOpen] = useState(false);
5544
+ const [earnModalOpen, setEarnModalOpen] = useState(false);
5197
5545
  const [receiveModalOpen, setReceiveModalOpen] = useState(false);
5198
5546
  const [sessionsModalOpen, setSessionsModalOpen] = useState(false);
5199
5547
  const [distributionRulesModalOpen, setDistributionRulesModalOpen] = useState(false);
@@ -5244,6 +5592,13 @@ function PollarProvider({
5244
5592
  getSwapQuote: (params) => pollarClient.getSwapQuote(params),
5245
5593
  swap: (quote, opts) => pollarClient.swap(quote, opts),
5246
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),
5247
5602
  // sessions
5248
5603
  sessions,
5249
5604
  openSessionsModal: () => setSessionsModalOpen(true),
@@ -5299,6 +5654,7 @@ function PollarProvider({
5299
5654
  enabledAssetsModalOpen && /* @__PURE__ */ jsx(ModalErrorBoundary, { onClose: () => setEnabledAssetsModalOpen(false), children: /* @__PURE__ */ jsx(EnabledAssetsModal, { onClose: () => setEnabledAssetsModalOpen(false) }) }),
5300
5655
  sendModalOpen && /* @__PURE__ */ jsx(ModalErrorBoundary, { onClose: () => setSendModalOpen(false), children: /* @__PURE__ */ jsx(SendModal, { onClose: () => setSendModalOpen(false) }) }),
5301
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) }) }),
5302
5658
  receiveModalOpen && /* @__PURE__ */ jsx(ModalErrorBoundary, { onClose: () => setReceiveModalOpen(false), children: /* @__PURE__ */ jsx(ReceiveModal, { onClose: () => setReceiveModalOpen(false) }) }),
5303
5659
  sessionsModalOpen && /* @__PURE__ */ jsx(ModalErrorBoundary, { onClose: () => setSessionsModalOpen(false), children: /* @__PURE__ */ jsx(SessionsModal, { onClose: () => setSessionsModalOpen(false) }) }),
5304
5660
  distributionRulesModalOpen && /* @__PURE__ */ jsx(ModalErrorBoundary, { onClose: () => setDistributionRulesModalOpen(false), children: /* @__PURE__ */ jsx(DistributionRulesModal, { onClose: () => setDistributionRulesModalOpen(false) }) })
@@ -5348,7 +5704,10 @@ function WalletButtonTemplate({
5348
5704
  itemColor,
5349
5705
  wrapperRef,
5350
5706
  isInProgress,
5707
+ showCreateAccount,
5708
+ creatingAccount,
5351
5709
  onToggleOpen,
5710
+ onCreateAccount,
5352
5711
  onCopy,
5353
5712
  onWalletBalance,
5354
5713
  onTxHistory,
@@ -5410,6 +5769,40 @@ function WalletButtonTemplate({
5410
5769
  }
5411
5770
  ),
5412
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
+ ] }),
5413
5806
  /* @__PURE__ */ jsxs("button", { className: "wallet-dropdown-item", style: { color: itemColor }, onClick: onSend, children: [
5414
5807
  /* @__PURE__ */ jsxs(
5415
5808
  "svg",
@@ -5649,9 +6042,12 @@ function WalletButton() {
5649
6042
  const walletType = wallet?.custody === "external" ? wallet.provider : null;
5650
6043
  const [open, setOpen] = useState(false);
5651
6044
  const [copied, setCopied] = useState(false);
6045
+ const [creating, setCreating] = useState(false);
6046
+ const [created, setCreated] = useState(false);
5652
6047
  const wrapperRef = useRef(null);
5653
6048
  const copyTimerRef = useRef(null);
5654
6049
  const isInProgress = transaction.step === "building" || transaction.step === "signing";
6050
+ const canCreateAccount = !created && wallet?.custody === "external" && wallet.existsOnStellar === false && wallet.fundingMode === "IMMEDIATE";
5655
6051
  const { theme = "light", accentColor = "#005DB4" } = styles;
5656
6052
  const isDark = theme === "dark";
5657
6053
  const dropdownBg = isDark ? "#18181b" : "#fff";
@@ -5686,6 +6082,20 @@ function WalletButton() {
5686
6082
  setOpen(false);
5687
6083
  getClient().logout();
5688
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
+ }
5689
6099
  function handleWalletBalance() {
5690
6100
  setOpen(false);
5691
6101
  openWalletBalanceModal();
@@ -5731,7 +6141,10 @@ function WalletButton() {
5731
6141
  wrapperRef,
5732
6142
  isInProgress,
5733
6143
  walletType,
6144
+ showCreateAccount: canCreateAccount,
6145
+ creatingAccount: creating,
5734
6146
  onToggleOpen: () => setOpen((v) => !v),
6147
+ onCreateAccount: handleCreateAccount,
5735
6148
  onCopy: handleCopy,
5736
6149
  onWalletBalance: handleWalletBalance,
5737
6150
  onTxHistory: handleTxHistory,
@@ -5747,6 +6160,6 @@ function WalletButton() {
5747
6160
  );
5748
6161
  }
5749
6162
 
5750
- 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 };
5751
6164
  //# sourceMappingURL=index.mjs.map
5752
6165
  //# sourceMappingURL=index.mjs.map