@pollar/react 0.7.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -33,7 +33,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
33
33
 
34
34
  // ../../node_modules/qr.js/lib/ErrorCorrectLevel.js
35
35
  var require_ErrorCorrectLevel = __commonJS({
36
- "../../node_modules/qr.js/lib/ErrorCorrectLevel.js"(exports$1, module) {
36
+ "../../node_modules/qr.js/lib/ErrorCorrectLevel.js"(exports, module) {
37
37
  module.exports = {
38
38
  L: 1,
39
39
  M: 0,
@@ -45,7 +45,7 @@ var require_ErrorCorrectLevel = __commonJS({
45
45
 
46
46
  // ../../node_modules/qr.js/lib/mode.js
47
47
  var require_mode = __commonJS({
48
- "../../node_modules/qr.js/lib/mode.js"(exports$1, module) {
48
+ "../../node_modules/qr.js/lib/mode.js"(exports, module) {
49
49
  module.exports = {
50
50
  MODE_NUMBER: 1 << 0,
51
51
  MODE_ALPHA_NUM: 1 << 1,
@@ -57,7 +57,7 @@ var require_mode = __commonJS({
57
57
 
58
58
  // ../../node_modules/qr.js/lib/8BitByte.js
59
59
  var require_BitByte = __commonJS({
60
- "../../node_modules/qr.js/lib/8BitByte.js"(exports$1, module) {
60
+ "../../node_modules/qr.js/lib/8BitByte.js"(exports, module) {
61
61
  var mode = require_mode();
62
62
  function QR8bitByte(data) {
63
63
  this.mode = mode.MODE_8BIT_BYTE;
@@ -79,7 +79,7 @@ var require_BitByte = __commonJS({
79
79
 
80
80
  // ../../node_modules/qr.js/lib/RSBlock.js
81
81
  var require_RSBlock = __commonJS({
82
- "../../node_modules/qr.js/lib/RSBlock.js"(exports$1, module) {
82
+ "../../node_modules/qr.js/lib/RSBlock.js"(exports, module) {
83
83
  var ECL = require_ErrorCorrectLevel();
84
84
  function QRRSBlock(totalCount, dataCount) {
85
85
  this.totalCount = totalCount;
@@ -328,7 +328,7 @@ var require_RSBlock = __commonJS({
328
328
 
329
329
  // ../../node_modules/qr.js/lib/BitBuffer.js
330
330
  var require_BitBuffer = __commonJS({
331
- "../../node_modules/qr.js/lib/BitBuffer.js"(exports$1, module) {
331
+ "../../node_modules/qr.js/lib/BitBuffer.js"(exports, module) {
332
332
  function QRBitBuffer() {
333
333
  this.buffer = new Array();
334
334
  this.length = 0;
@@ -363,7 +363,7 @@ var require_BitBuffer = __commonJS({
363
363
 
364
364
  // ../../node_modules/qr.js/lib/math.js
365
365
  var require_math = __commonJS({
366
- "../../node_modules/qr.js/lib/math.js"(exports$1, module) {
366
+ "../../node_modules/qr.js/lib/math.js"(exports, module) {
367
367
  var QRMath = {
368
368
  glog: function(n) {
369
369
  if (n < 1) {
@@ -401,7 +401,7 @@ var require_math = __commonJS({
401
401
 
402
402
  // ../../node_modules/qr.js/lib/Polynomial.js
403
403
  var require_Polynomial = __commonJS({
404
- "../../node_modules/qr.js/lib/Polynomial.js"(exports$1, module) {
404
+ "../../node_modules/qr.js/lib/Polynomial.js"(exports, module) {
405
405
  var math = require_math();
406
406
  function QRPolynomial(num, shift) {
407
407
  if (num.length == void 0) {
@@ -453,7 +453,7 @@ var require_Polynomial = __commonJS({
453
453
 
454
454
  // ../../node_modules/qr.js/lib/util.js
455
455
  var require_util = __commonJS({
456
- "../../node_modules/qr.js/lib/util.js"(exports$1, module) {
456
+ "../../node_modules/qr.js/lib/util.js"(exports, module) {
457
457
  var Mode = require_mode();
458
458
  var Polynomial = require_Polynomial();
459
459
  var math = require_math();
@@ -684,7 +684,7 @@ var require_util = __commonJS({
684
684
 
685
685
  // ../../node_modules/qr.js/lib/QRCode.js
686
686
  var require_QRCode = __commonJS({
687
- "../../node_modules/qr.js/lib/QRCode.js"(exports$1, module) {
687
+ "../../node_modules/qr.js/lib/QRCode.js"(exports, module) {
688
688
  var BitByte = require_BitByte();
689
689
  var RSBlock = require_RSBlock();
690
690
  var BitBuffer = require_BitBuffer();
@@ -1030,7 +1030,7 @@ var PollarModalFooter = () => {
1030
1030
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-footer-name", children: "Pollar" }),
1031
1031
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-footer-version", children: [
1032
1032
  "v",
1033
- "0.7.1"
1033
+ "0.8.0"
1034
1034
  ] })
1035
1035
  ] })
1036
1036
  ] });
@@ -1112,16 +1112,7 @@ function RuleCard({
1112
1112
  validity
1113
1113
  ] })
1114
1114
  ] }),
1115
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-dist-item-action", children: isClaimed ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-dist-item-status", "data-kind": "claimed", children: "Claimed" }) : effectivelyClaimable ? /* @__PURE__ */ jsxRuntime.jsx(
1116
- "button",
1117
- {
1118
- type: "button",
1119
- className: "pollar-btn-primary pollar-dist-claim-btn",
1120
- onClick: onClaim,
1121
- disabled: isClaiming,
1122
- children: isClaiming ? "Claiming\u2026" : "Claim"
1123
- }
1124
- ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-dist-item-status", "data-kind": "unavailable", children: reasonLabel(rule.reason) }) }),
1115
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-dist-item-action", children: isClaimed ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-dist-item-status", "data-kind": "claimed", children: "Claimed" }) : effectivelyClaimable ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-primary pollar-dist-claim-btn", onClick: onClaim, disabled: isClaiming, children: isClaiming ? "Claiming\u2026" : "Claim" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-dist-item-status", "data-kind": "unavailable", children: reasonLabel(rule.reason) }) }),
1125
1116
  errorMessage && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-dist-item-error", children: errorMessage })
1126
1117
  ] });
1127
1118
  }
@@ -1335,10 +1326,20 @@ function KycModalTemplate({
1335
1326
  ] }),
1336
1327
  step === "select_provider" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-kyc-providers", children: [
1337
1328
  providers.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { color: "var(--pollar-muted)", textAlign: "center" }, children: "No providers available for your country." }),
1338
- providers.map((p) => /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "pollar-kyc-provider-btn", disabled: isLoading, onClick: () => onSelectProvider(p), children: [
1339
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-kyc-provider-name", children: p.name }),
1340
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-kyc-provider-flow", children: p.flow })
1341
- ] }, p.id))
1329
+ providers.map((p) => /* @__PURE__ */ jsxRuntime.jsxs(
1330
+ "button",
1331
+ {
1332
+ type: "button",
1333
+ className: "pollar-kyc-provider-btn",
1334
+ disabled: isLoading,
1335
+ onClick: () => onSelectProvider(p),
1336
+ children: [
1337
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-kyc-provider-name", children: p.name }),
1338
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-kyc-provider-flow", children: p.flow })
1339
+ ]
1340
+ },
1341
+ p.id
1342
+ ))
1342
1343
  ] }),
1343
1344
  step === "verifying" && selectedProvider && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1344
1345
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-kyc-iframe-wrap", children: session?.kycUrl ? /* @__PURE__ */ jsxRuntime.jsx("iframe", { className: "pollar-kyc-iframe", src: session.kycUrl, title: "KYC verification", allow: "camera; microphone" }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-kyc-iframe-mock", children: [
@@ -1457,8 +1458,7 @@ function EmailCodeInput({ email, onSubmit }) {
1457
1458
  }
1458
1459
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-code-section", children: [
1459
1460
  /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "pollar-code-label", children: [
1460
- "Enter the 6-digit code sent to",
1461
- " ",
1461
+ "Enter the 6-digit code sent to ",
1462
1462
  email ? /* @__PURE__ */ jsxRuntime.jsx("strong", { children: email }) : "your email"
1463
1463
  ] }),
1464
1464
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-code-inputs", children: digits.map((digit, i) => /* @__PURE__ */ jsxRuntime.jsx(
@@ -1482,7 +1482,14 @@ function EmailCodeInput({ email, onSubmit }) {
1482
1482
  }
1483
1483
  var GithubButton = ({ disabled, onClick }) => {
1484
1484
  return /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "github-button", disabled, onClick, children: [
1485
- /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "github-button-icon", viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { fillRule: "evenodd", d: "M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z", clipRule: "evenodd" }) }),
1485
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "github-button-icon", viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx(
1486
+ "path",
1487
+ {
1488
+ fillRule: "evenodd",
1489
+ d: "M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z",
1490
+ clipRule: "evenodd"
1491
+ }
1492
+ ) }),
1486
1493
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "github-button-contents", children: "GitHub" })
1487
1494
  ] });
1488
1495
  };
@@ -1535,6 +1542,36 @@ var GoogleButton = ({ disabled, onClick }) => {
1535
1542
  ] })
1536
1543
  ] });
1537
1544
  };
1545
+ function DefaultFreighterAlbedoButtons({ onConnect, isLoading }) {
1546
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-wallet-list", children: [
1547
+ /* @__PURE__ */ jsxRuntime.jsxs(
1548
+ "button",
1549
+ {
1550
+ type: "button",
1551
+ disabled: isLoading,
1552
+ className: "pollar-wallet-list-btn",
1553
+ onClick: () => onConnect(core.WalletType.FREIGHTER),
1554
+ children: [
1555
+ /* @__PURE__ */ jsxRuntime.jsx("img", { src: LOGO_FREIGHTER, alt: "Freighter", className: "pollar-wallet-list-icon" }),
1556
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-wallet-list-name", children: "Freighter" })
1557
+ ]
1558
+ }
1559
+ ),
1560
+ /* @__PURE__ */ jsxRuntime.jsxs(
1561
+ "button",
1562
+ {
1563
+ type: "button",
1564
+ disabled: isLoading,
1565
+ className: "pollar-wallet-list-btn",
1566
+ onClick: () => onConnect(core.WalletType.ALBEDO),
1567
+ children: [
1568
+ /* @__PURE__ */ jsxRuntime.jsx("img", { src: LOGO_ALBEDO, alt: "Albedo", className: "pollar-wallet-list-icon" }),
1569
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-wallet-list-name", children: "Albedo" })
1570
+ ]
1571
+ }
1572
+ )
1573
+ ] });
1574
+ }
1538
1575
  var AUTH_STATE_MESSAGES = {
1539
1576
  idle: "",
1540
1577
  creating_session: "Initializing\u2026",
@@ -1579,8 +1616,8 @@ function LoginModalTemplate({
1579
1616
  onEmailChange,
1580
1617
  onEmailSubmit,
1581
1618
  onSocialLogin,
1582
- onFreighterConnect,
1583
- onAlbedoConnect,
1619
+ onWalletConnect,
1620
+ renderWallets,
1584
1621
  authState,
1585
1622
  codeInputKey,
1586
1623
  onCodeSubmit,
@@ -1616,9 +1653,35 @@ function LoginModalTemplate({
1616
1653
  const isEmailCodeError = authState.step === "error" && (authState.errorCode === core.AUTH_ERROR_CODES.EMAIL_CODE_EXPIRED || authState.errorCode === core.AUTH_ERROR_CODES.EMAIL_CODE_INVALID);
1617
1654
  const awaitingEmailCode = authState.step === "entering_code" || authState.step === "verifying_email_code" || isEmailCodeError;
1618
1655
  const statusMessage = authState.step === "error" ? authState.message : AUTH_STATE_MESSAGES[authState.step];
1619
- const BackButton = ({ onClick }) => /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-back-btn", onClick, "aria-label": "Back", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15 19l-7-7 7-7" }) }) });
1656
+ const BackButton = ({ onClick }) => /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-back-btn", onClick, "aria-label": "Back", children: /* @__PURE__ */ jsxRuntime.jsx(
1657
+ "svg",
1658
+ {
1659
+ width: "20",
1660
+ height: "20",
1661
+ viewBox: "0 0 24 24",
1662
+ fill: "none",
1663
+ stroke: "currentColor",
1664
+ strokeWidth: "2.5",
1665
+ strokeLinecap: "round",
1666
+ strokeLinejoin: "round",
1667
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15 19l-7-7 7-7" })
1668
+ }
1669
+ ) });
1620
1670
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-card pollar-modal", style: cssVars, onClick: (e) => e.stopPropagation(), children: [
1621
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-close-btn", onClick: onCancel, "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6L6 18M6 6l12 12" }) }) }),
1671
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-close-btn", onClick: onCancel, "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsx(
1672
+ "svg",
1673
+ {
1674
+ width: "18",
1675
+ height: "18",
1676
+ viewBox: "0 0 24 24",
1677
+ fill: "none",
1678
+ stroke: "currentColor",
1679
+ strokeWidth: "2.5",
1680
+ strokeLinecap: "round",
1681
+ strokeLinejoin: "round",
1682
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6L6 18M6 6l12 12" })
1683
+ }
1684
+ ) }),
1622
1685
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-header", children: [
1623
1686
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-logo-wrap", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: logoUrl ?? LOGO_POLLAR, alt: "Logo", className: "pollar-logo" }) }),
1624
1687
  /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-title", children: appName }),
@@ -1630,34 +1693,7 @@ function LoginModalTemplate({
1630
1693
  }) }, codeInputKey)
1631
1694
  ] }) : showWalletPicker ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1632
1695
  /* @__PURE__ */ jsxRuntime.jsx(BackButton, { onClick: () => setShowWalletPicker(false) }),
1633
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-wallet-list", children: [
1634
- /* @__PURE__ */ jsxRuntime.jsxs(
1635
- "button",
1636
- {
1637
- type: "button",
1638
- disabled: isLoading,
1639
- className: "pollar-wallet-list-btn",
1640
- onClick: onFreighterConnect,
1641
- children: [
1642
- /* @__PURE__ */ jsxRuntime.jsx("img", { src: LOGO_FREIGHTER, alt: "Freighter", className: "pollar-wallet-list-icon" }),
1643
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-wallet-list-name", children: "Freighter" })
1644
- ]
1645
- }
1646
- ),
1647
- /* @__PURE__ */ jsxRuntime.jsxs(
1648
- "button",
1649
- {
1650
- type: "button",
1651
- disabled: isLoading,
1652
- className: "pollar-wallet-list-btn",
1653
- onClick: onAlbedoConnect,
1654
- children: [
1655
- /* @__PURE__ */ jsxRuntime.jsx("img", { src: LOGO_ALBEDO, alt: "Albedo", className: "pollar-wallet-list-icon" }),
1656
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-wallet-list-name", children: "Albedo" })
1657
- ]
1658
- }
1659
- )
1660
- ] })
1696
+ renderWallets ? renderWallets({ onConnect: onWalletConnect, authState }) : /* @__PURE__ */ jsxRuntime.jsx(DefaultFreighterAlbedoButtons, { onConnect: onWalletConnect, isLoading })
1661
1697
  ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1662
1698
  emailEnabled && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-email-section", children: [
1663
1699
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1672,7 +1708,17 @@ function LoginModalTemplate({
1672
1708
  onKeyDown: (e) => e.key === "Enter" && onEmailSubmit?.()
1673
1709
  }
1674
1710
  ),
1675
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", disabled: isLoading || !email, className: "pollar-btn-primary", style: { marginTop: "0.75rem", width: "100%" }, onClick: onEmailSubmit, children: "Submit" })
1711
+ /* @__PURE__ */ jsxRuntime.jsx(
1712
+ "button",
1713
+ {
1714
+ type: "button",
1715
+ disabled: isLoading || !email,
1716
+ className: "pollar-btn-primary",
1717
+ style: { marginTop: "0.75rem", width: "100%" },
1718
+ onClick: onEmailSubmit,
1719
+ children: "Submit"
1720
+ }
1721
+ )
1676
1722
  ] }),
1677
1723
  emailEnabled && enabledSocial.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-divider", children: [
1678
1724
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-divider-line" }),
@@ -1690,7 +1736,20 @@ function LoginModalTemplate({
1690
1736
  className: "pollar-wallet-entry-btn",
1691
1737
  onClick: () => setShowWalletPicker(true),
1692
1738
  children: [
1693
- /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "18", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" }) }),
1739
+ /* @__PURE__ */ jsxRuntime.jsx(
1740
+ "svg",
1741
+ {
1742
+ width: "18",
1743
+ height: "20",
1744
+ viewBox: "0 0 24 24",
1745
+ fill: "none",
1746
+ stroke: "currentColor",
1747
+ strokeWidth: "2",
1748
+ strokeLinecap: "round",
1749
+ strokeLinejoin: "round",
1750
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" })
1751
+ }
1752
+ ),
1694
1753
  "Wallet"
1695
1754
  ]
1696
1755
  }
@@ -1710,14 +1769,15 @@ function LoginModalTemplate({
1710
1769
  }
1711
1770
  function LoginModal({ onClose }) {
1712
1771
  const [email, setEmail] = react.useState("");
1713
- const { getClient, styles, appConfig: config } = usePollar();
1772
+ const { getClient, styles, appConfig: config, renderWallets } = usePollar();
1714
1773
  const [authState, setAuthState] = react.useState(() => getClient().getAuthState());
1715
1774
  const [codeInputKey, setCodeInputKey] = react.useState(0);
1716
1775
  const pendingEmail = react.useRef(null);
1717
1776
  const onCloseRef = react.useRef(onClose);
1718
1777
  onCloseRef.current = onClose;
1778
+ const autoCloseTimer = react.useRef(null);
1719
1779
  react.useEffect(() => {
1720
- return getClient().onAuthStateChange((next) => {
1780
+ const unsubscribe = getClient().onAuthStateChange((next) => {
1721
1781
  setAuthState(next);
1722
1782
  if (next.step === "entering_email" && pendingEmail.current) {
1723
1783
  getClient().sendEmailCode(pendingEmail.current);
@@ -1727,9 +1787,19 @@ function LoginModal({ onClose }) {
1727
1787
  setCodeInputKey((k) => k + 1);
1728
1788
  }
1729
1789
  if (next.step === "authenticated") {
1730
- setTimeout(onCloseRef.current, 1e3);
1790
+ autoCloseTimer.current = setTimeout(() => {
1791
+ autoCloseTimer.current = null;
1792
+ onCloseRef.current();
1793
+ }, 1e3);
1731
1794
  }
1732
1795
  });
1796
+ return () => {
1797
+ unsubscribe();
1798
+ if (autoCloseTimer.current !== null) {
1799
+ clearTimeout(autoCloseTimer.current);
1800
+ autoCloseTimer.current = null;
1801
+ }
1802
+ };
1733
1803
  }, [getClient]);
1734
1804
  const { theme = "light", accentColor = "#005DB4", logoUrl, emailEnabled, embeddedWallets, providers } = styles;
1735
1805
  function handleClose() {
@@ -1781,8 +1851,8 @@ function LoginModal({ onClose }) {
1781
1851
  onEmailChange: setEmail,
1782
1852
  onEmailSubmit: handleEmailSubmit,
1783
1853
  onSocialLogin: handleSocialLogin,
1784
- onFreighterConnect: () => handleWalletConnect(core.WalletType.FREIGHTER),
1785
- onAlbedoConnect: () => handleWalletConnect(core.WalletType.ALBEDO),
1854
+ onWalletConnect: handleWalletConnect,
1855
+ ...renderWallets !== void 0 && { renderWallets },
1786
1856
  authState,
1787
1857
  codeInputKey,
1788
1858
  onCodeSubmit: handleVerifyCode,
@@ -1899,8 +1969,26 @@ function RampWidgetTemplate({
1899
1969
  ] }),
1900
1970
  step === "input" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1901
1971
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-tabs", children: [
1902
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-ramp-tab", "data-active": direction === "onramp", onClick: () => onDirectionChange("onramp"), children: "Buy" }),
1903
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-ramp-tab", "data-active": direction === "offramp", onClick: () => onDirectionChange("offramp"), children: "Sell" })
1972
+ /* @__PURE__ */ jsxRuntime.jsx(
1973
+ "button",
1974
+ {
1975
+ type: "button",
1976
+ className: "pollar-ramp-tab",
1977
+ "data-active": direction === "onramp",
1978
+ onClick: () => onDirectionChange("onramp"),
1979
+ children: "Buy"
1980
+ }
1981
+ ),
1982
+ /* @__PURE__ */ jsxRuntime.jsx(
1983
+ "button",
1984
+ {
1985
+ type: "button",
1986
+ className: "pollar-ramp-tab",
1987
+ "data-active": direction === "offramp",
1988
+ onClick: () => onDirectionChange("offramp"),
1989
+ children: "Sell"
1990
+ }
1991
+ )
1904
1992
  ] }),
1905
1993
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-input-row", children: [
1906
1994
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-field", children: [
@@ -2005,17 +2093,79 @@ function RampWidgetTemplate({
2005
2093
  ] });
2006
2094
  }
2007
2095
  var MOCK_DEFAULT_QUOTES = [
2008
- { quoteId: "meld-default", provider: "Meld", fee: 1.2, feeCurrency: "USD", rate: 1, rail: "ACH", protocol: "REST", estimatedTime: "~20 min", recommended: true }
2096
+ {
2097
+ quoteId: "meld-default",
2098
+ provider: "Meld",
2099
+ fee: 1.2,
2100
+ feeCurrency: "USD",
2101
+ rate: 1,
2102
+ rail: "ACH",
2103
+ protocol: "REST",
2104
+ estimatedTime: "~20 min",
2105
+ recommended: true
2106
+ }
2009
2107
  ];
2010
2108
  var MOCK_QUOTES = {
2011
2109
  MX: [
2012
- { quoteId: "etherfuse-mx", provider: "Etherfuse", fee: 0.5, feeCurrency: "MXN", rate: 17.2, rail: "SPEI", protocol: "SEP-24", estimatedTime: "~10 min", recommended: true },
2013
- { quoteId: "alfredpay-mx", provider: "AlfredPay", fee: 0.8, feeCurrency: "MXN", rate: 17.1, rail: "SPEI", protocol: "REST", estimatedTime: "~15 min", recommended: false }
2110
+ {
2111
+ quoteId: "etherfuse-mx",
2112
+ provider: "Etherfuse",
2113
+ fee: 0.5,
2114
+ feeCurrency: "MXN",
2115
+ rate: 17.2,
2116
+ rail: "SPEI",
2117
+ protocol: "SEP-24",
2118
+ estimatedTime: "~10 min",
2119
+ recommended: true
2120
+ },
2121
+ {
2122
+ quoteId: "alfredpay-mx",
2123
+ provider: "AlfredPay",
2124
+ fee: 0.8,
2125
+ feeCurrency: "MXN",
2126
+ rate: 17.1,
2127
+ rail: "SPEI",
2128
+ protocol: "REST",
2129
+ estimatedTime: "~15 min",
2130
+ recommended: false
2131
+ }
2132
+ ],
2133
+ BR: [
2134
+ {
2135
+ quoteId: "abroad-br",
2136
+ provider: "Abroad",
2137
+ fee: 0.6,
2138
+ feeCurrency: "BRL",
2139
+ rate: 5.1,
2140
+ rail: "PIX",
2141
+ protocol: "REST",
2142
+ estimatedTime: "~5 min",
2143
+ recommended: true
2144
+ }
2014
2145
  ],
2015
- BR: [{ quoteId: "abroad-br", provider: "Abroad", fee: 0.6, feeCurrency: "BRL", rate: 5.1, rail: "PIX", protocol: "REST", estimatedTime: "~5 min", recommended: true }],
2016
2146
  CO: [
2017
- { quoteId: "abroad-co", provider: "Abroad", fee: 0.7, feeCurrency: "COP", rate: 4100, rail: "PSE", protocol: "REST", estimatedTime: "~10 min", recommended: true },
2018
- { quoteId: "koywe-co", provider: "Koywe", fee: 0.9, feeCurrency: "COP", rate: 4095, rail: "PSE", protocol: "REST", estimatedTime: "~15 min", recommended: false }
2147
+ {
2148
+ quoteId: "abroad-co",
2149
+ provider: "Abroad",
2150
+ fee: 0.7,
2151
+ feeCurrency: "COP",
2152
+ rate: 4100,
2153
+ rail: "PSE",
2154
+ protocol: "REST",
2155
+ estimatedTime: "~10 min",
2156
+ recommended: true
2157
+ },
2158
+ {
2159
+ quoteId: "koywe-co",
2160
+ provider: "Koywe",
2161
+ fee: 0.9,
2162
+ feeCurrency: "COP",
2163
+ rate: 4095,
2164
+ rail: "PSE",
2165
+ protocol: "REST",
2166
+ estimatedTime: "~15 min",
2167
+ recommended: false
2168
+ }
2019
2169
  ],
2020
2170
  DEFAULT: MOCK_DEFAULT_QUOTES
2021
2171
  };
@@ -2110,17 +2260,7 @@ function RampWidget({ onClose }) {
2110
2260
  // src/lib/qr-code/index.tsx
2111
2261
  var import_ErrorCorrectLevel = __toESM(require_ErrorCorrectLevel());
2112
2262
  var import_QRCode = __toESM(require_QRCode());
2113
- var QRCodeSvg = react.forwardRef(function QRCodeSvg2({
2114
- bgColor,
2115
- bgD,
2116
- fgD,
2117
- fgColor,
2118
- size,
2119
- title,
2120
- viewBoxSize,
2121
- xmlns = "http://www.w3.org/2000/svg",
2122
- ...props
2123
- }, ref) {
2263
+ var QRCodeSvg = react.forwardRef(function QRCodeSvg2({ bgColor, bgD, fgD, fgColor, size, title, viewBoxSize, xmlns = "http://www.w3.org/2000/svg", ...props }, ref) {
2124
2264
  return /* @__PURE__ */ jsxRuntime.jsxs("svg", { ...props, height: size, ref, viewBox: `0 0 ${viewBoxSize} ${viewBoxSize}`, width: size, xmlns, children: [
2125
2265
  title ? /* @__PURE__ */ jsxRuntime.jsx("title", { children: title }) : null,
2126
2266
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: bgD, fill: bgColor }),
@@ -2146,9 +2286,13 @@ var QRCode = react.forwardRef(function QRCode2({ bgColor = "#FFFFFF", fgColor =
2146
2286
  {
2147
2287
  ...props,
2148
2288
  bgColor,
2149
- bgD: cells.map((row, rowIndex) => row.map((cell, cellIndex) => !cell ? `M ${cellIndex} ${rowIndex} l 1 0 0 1 -1 0 Z` : "").join(" ")).join(" "),
2289
+ bgD: cells.map(
2290
+ (row, rowIndex) => row.map((cell, cellIndex) => !cell ? `M ${cellIndex} ${rowIndex} l 1 0 0 1 -1 0 Z` : "").join(" ")
2291
+ ).join(" "),
2150
2292
  fgColor,
2151
- fgD: cells.map((row, rowIndex) => row.map((cell, cellIndex) => cell ? `M ${cellIndex} ${rowIndex} l 1 0 0 1 -1 0 Z` : "").join(" ")).join(" "),
2293
+ fgD: cells.map(
2294
+ (row, rowIndex) => row.map((cell, cellIndex) => cell ? `M ${cellIndex} ${rowIndex} l 1 0 0 1 -1 0 Z` : "").join(" ")
2295
+ ).join(" "),
2152
2296
  ref,
2153
2297
  size,
2154
2298
  viewBoxSize: cells.length
@@ -2194,15 +2338,7 @@ function ReceiveModalTemplate({
2194
2338
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-header-actions", children: /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-modal-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2 2l12 12M14 2L2 14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) }) })
2195
2339
  ] }),
2196
2340
  walletAddress ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2197
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-receive-qr", children: /* @__PURE__ */ jsxRuntime.jsx(
2198
- QRCode,
2199
- {
2200
- value: walletAddress,
2201
- size: 180,
2202
- fgColor: isDark ? "#ffffff" : "#111827",
2203
- bgColor: "transparent"
2204
- }
2205
- ) }),
2341
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-receive-qr", children: /* @__PURE__ */ jsxRuntime.jsx(QRCode, { value: walletAddress, size: 180, fgColor: isDark ? "#ffffff" : "#111827", bgColor: "transparent" }) }),
2206
2342
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "pollar-receive-instructions", children: "Share your Stellar address to receive any asset. Only send Stellar assets to this address." }),
2207
2343
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-receive-address-row", children: [
2208
2344
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-receive-address", children: walletAddress }),
@@ -2247,11 +2383,22 @@ function ReceiveModal({ onClose }) {
2247
2383
  const { walletAddress, styles } = usePollar();
2248
2384
  const { theme = "light", accentColor = "#005DB4" } = styles;
2249
2385
  const [copied, setCopied] = react.useState(false);
2386
+ const copyTimerRef = react.useRef(null);
2387
+ react.useEffect(
2388
+ () => () => {
2389
+ if (copyTimerRef.current !== null) clearTimeout(copyTimerRef.current);
2390
+ },
2391
+ []
2392
+ );
2250
2393
  function handleCopy() {
2251
2394
  if (!walletAddress) return;
2252
2395
  navigator.clipboard.writeText(walletAddress).then(() => {
2253
2396
  setCopied(true);
2254
- setTimeout(() => setCopied(false), 2e3);
2397
+ if (copyTimerRef.current !== null) clearTimeout(copyTimerRef.current);
2398
+ copyTimerRef.current = setTimeout(() => {
2399
+ copyTimerRef.current = null;
2400
+ setCopied(false);
2401
+ }, 2e3);
2255
2402
  });
2256
2403
  }
2257
2404
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -2270,10 +2417,32 @@ var STATUS_MESSAGES = {
2270
2417
  idle: "",
2271
2418
  building: "Building transaction\u2026",
2272
2419
  built: "Ready to sign and send",
2273
- signing: "Signing and sending transaction\u2026",
2420
+ signing: "Signing transaction\u2026",
2421
+ signed: "Signed \u2014 ready to submit",
2422
+ submitting: "Submitting transaction\u2026",
2423
+ submitted: "Submitted \u2014 waiting for confirmation\u2026",
2424
+ "signing-submitting": "Signing and submitting transaction\u2026",
2425
+ "building-signing-submitting": "Processing transaction\u2026",
2274
2426
  success: "Transaction sent successfully",
2275
2427
  error: "Transaction failed"
2276
2428
  };
2429
+ var IN_FLIGHT_STEPS = /* @__PURE__ */ new Set([
2430
+ "building",
2431
+ "signing",
2432
+ "submitting",
2433
+ "submitted",
2434
+ "signing-submitting",
2435
+ "building-signing-submitting"
2436
+ ]);
2437
+ var SHOW_DETAILS_STEPS = /* @__PURE__ */ new Set([
2438
+ "built",
2439
+ "signing",
2440
+ "signed",
2441
+ "submitting",
2442
+ "submitted",
2443
+ "signing-submitting",
2444
+ "success"
2445
+ ]);
2277
2446
  function TxStatusView({
2278
2447
  transaction,
2279
2448
  showXdr,
@@ -2290,10 +2459,10 @@ function TxStatusView({
2290
2459
  const hash = transaction.step === "success" ? transaction.hash : null;
2291
2460
  const errorDetails = transaction.step === "error" ? transaction.details ?? null : null;
2292
2461
  const isBuilt = transaction.step === "built";
2293
- const isSigning = transaction.step === "signing";
2462
+ const isInFlight = IN_FLIGHT_STEPS.has(transaction.step);
2294
2463
  const isSuccess = transaction.step === "success";
2295
2464
  const isError = transaction.step === "error";
2296
- const showDetails = buildData !== null && (isBuilt || isSigning || isSuccess);
2465
+ const showDetails = buildData !== null && SHOW_DETAILS_STEPS.has(transaction.step);
2297
2466
  const walletImg = walletType === core.WalletType.FREIGHTER ? LOGO_FREIGHTER : walletType === core.WalletType.ALBEDO ? LOGO_ALBEDO : LOGO_POLLAR;
2298
2467
  const walletAlt = walletType === core.WalletType.FREIGHTER ? "Freighter" : walletType === core.WalletType.ALBEDO ? "Albedo" : "Pollar";
2299
2468
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -2336,7 +2505,7 @@ function TxStatusView({
2336
2505
  /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "pollar-tx-error-details-content", children: errorDetails })
2337
2506
  ] }),
2338
2507
  isBuilt && /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-btn-primary pollar-tx-sign-btn", onClick: onSignAndSend, children: "Sign & Send" }),
2339
- (isSigning || isSuccess || isError) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-wallet-spinner", children: [
2508
+ (isInFlight || isSuccess || isError) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-wallet-spinner", children: [
2340
2509
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-spinner-ring", children: [
2341
2510
  /* @__PURE__ */ jsxRuntime.jsxs(
2342
2511
  "svg",
@@ -2344,7 +2513,7 @@ function TxStatusView({
2344
2513
  viewBox: "0 0 88 88",
2345
2514
  width: "88",
2346
2515
  height: "88",
2347
- className: `pollar-tx-spinner-svg${isSigning ? " pollar-tx-spinner-rotating" : ""}`,
2516
+ className: `pollar-tx-spinner-svg${isInFlight ? " pollar-tx-spinner-rotating" : ""}`,
2348
2517
  "aria-hidden": true,
2349
2518
  children: [
2350
2519
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "44", cy: "44", r: "36", fill: "none", stroke: "var(--pollar-border)", strokeWidth: "3" }),
@@ -2358,9 +2527,9 @@ function TxStatusView({
2358
2527
  stroke: isSuccess ? "var(--pollar-success-text)" : isError ? "var(--pollar-error-text)" : "var(--pollar-accent)",
2359
2528
  strokeWidth: "3",
2360
2529
  strokeLinecap: "round",
2361
- strokeDasharray: isSigning ? "169.6 56.6" : "999 0",
2530
+ strokeDasharray: isInFlight ? "169.6 56.6" : "999 0",
2362
2531
  transform: "rotate(-90 44 44)",
2363
- style: { transition: isSigning ? "none" : "stroke 400ms, stroke-dasharray 400ms" }
2532
+ style: { transition: isInFlight ? "none" : "stroke 400ms, stroke-dasharray 400ms" }
2364
2533
  }
2365
2534
  )
2366
2535
  ]
@@ -2368,7 +2537,7 @@ function TxStatusView({
2368
2537
  ),
2369
2538
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-tx-wallet-icon", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: walletImg, alt: walletAlt, className: "pollar-tx-wallet-img" }) })
2370
2539
  ] }),
2371
- isSigning && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "pollar-tx-spinner-label", children: walletType === core.WalletType.FREIGHTER ? "Waiting for Freighter\u2026" : walletType === core.WalletType.ALBEDO ? "Waiting for Albedo\u2026" : "Signing and sending\u2026" }),
2540
+ isInFlight && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "pollar-tx-spinner-label", children: walletType === core.WalletType.FREIGHTER ? "Waiting for Freighter\u2026" : walletType === core.WalletType.ALBEDO ? "Waiting for Albedo\u2026" : "Signing and sending\u2026" }),
2372
2541
  isError && onRetry && "buildData" in transaction && transaction.buildData && /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-btn-secondary pollar-tx-retry-btn", onClick: onRetry, children: "Try again" })
2373
2542
  ] }),
2374
2543
  isSuccess && hash && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-result", children: [
@@ -2436,7 +2605,7 @@ function TxStatusView({
2436
2605
  ModalStatusBanner,
2437
2606
  {
2438
2607
  message: STATUS_MESSAGES[transaction.step],
2439
- status: isError ? "ERROR" : isSigning || transaction.step === "building" ? "LOADING" : isSuccess ? "SUCCESS" : "NONE"
2608
+ status: isError ? "ERROR" : isInFlight ? "LOADING" : isSuccess ? "SUCCESS" : "NONE"
2440
2609
  }
2441
2610
  )
2442
2611
  ] });
@@ -2613,7 +2782,16 @@ function assetParam(record) {
2613
2782
  return { type: "credit_alphanum12", code: record.code, issuer: record.issuer };
2614
2783
  }
2615
2784
  function SendModal({ onClose }) {
2616
- const { walletBalance, refreshWalletBalance, buildTx, signAndSubmitTx, tx: transaction, walletType, network, styles } = usePollar();
2785
+ const {
2786
+ walletBalance,
2787
+ refreshWalletBalance,
2788
+ buildTx,
2789
+ signAndSubmitTx,
2790
+ tx: transaction,
2791
+ walletType,
2792
+ network,
2793
+ styles
2794
+ } = usePollar();
2617
2795
  const { theme = "light", accentColor = "#005DB4" } = styles;
2618
2796
  const [step, setStep] = react.useState("form");
2619
2797
  const [amount, setAmount] = react.useState("");
@@ -2622,9 +2800,16 @@ function SendModal({ onClose }) {
2622
2800
  const [showXdr, setShowXdr] = react.useState(false);
2623
2801
  const [copied, setCopied] = react.useState(false);
2624
2802
  const [formError, setFormError] = react.useState("");
2803
+ const copyTimerRef = react.useRef(null);
2625
2804
  react.useEffect(() => {
2626
2805
  void refreshWalletBalance();
2627
2806
  }, [refreshWalletBalance]);
2807
+ react.useEffect(
2808
+ () => () => {
2809
+ if (copyTimerRef.current !== null) clearTimeout(copyTimerRef.current);
2810
+ },
2811
+ []
2812
+ );
2628
2813
  const balanceData = walletBalance.step === "loaded" ? walletBalance.data : null;
2629
2814
  const allAssets = balanceData?.balances ?? [];
2630
2815
  const sortedAssets = [
@@ -2635,9 +2820,17 @@ function SendModal({ onClose }) {
2635
2820
  const buildData = "buildData" in transaction ? transaction.buildData : null;
2636
2821
  const explorerNetwork = buildData?.summary.network?.toLowerCase().includes("testnet") ? "testnet" : buildData ? "public" : network === "testnet" ? "testnet" : "public";
2637
2822
  const explorerUrl = hash ? `https://stellar.expert/explorer/${explorerNetwork}/tx/${hash}` : null;
2638
- const isInProgress = transaction.step === "building" || transaction.step === "signing";
2823
+ const IN_FLIGHT_STEPS2 = [
2824
+ "building",
2825
+ "signing",
2826
+ "submitting",
2827
+ "submitted",
2828
+ "signing-submitting",
2829
+ "building-signing-submitting"
2830
+ ];
2831
+ const isInProgress = IN_FLIGHT_STEPS2.includes(transaction.step);
2639
2832
  const showBack = step === "tx" && (transaction.step === "error" || transaction.step === "success") && !isInProgress;
2640
- const txTitle = transaction.step === "signing" ? "Sending\u2026" : transaction.step === "success" ? "Sent!" : transaction.step === "error" ? "Send failed" : "Confirm Send";
2833
+ const txTitle = isInProgress ? "Sending\u2026" : transaction.step === "success" ? "Sent!" : transaction.step === "error" ? "Send failed" : "Confirm Send";
2641
2834
  async function handleSubmit() {
2642
2835
  setFormError("");
2643
2836
  if (!selectedAsset) {
@@ -2669,7 +2862,11 @@ function SendModal({ onClose }) {
2669
2862
  if (!hash) return;
2670
2863
  navigator.clipboard.writeText(hash).then(() => {
2671
2864
  setCopied(true);
2672
- setTimeout(() => setCopied(false), 2e3);
2865
+ if (copyTimerRef.current !== null) clearTimeout(copyTimerRef.current);
2866
+ copyTimerRef.current = setTimeout(() => {
2867
+ copyTimerRef.current = null;
2868
+ setCopied(false);
2869
+ }, 2e3);
2673
2870
  });
2674
2871
  }
2675
2872
  async function handleRetry() {
@@ -2819,16 +3016,7 @@ function SessionsModalTemplate({
2819
3016
  "aria-hidden": true,
2820
3017
  children: [
2821
3018
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M11.5 6.5a5 5 0 11-1.5-3.536", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }),
2822
- /* @__PURE__ */ jsxRuntime.jsx(
2823
- "path",
2824
- {
2825
- d: "M10 1v3h-3",
2826
- stroke: "currentColor",
2827
- strokeWidth: "1.5",
2828
- strokeLinecap: "round",
2829
- strokeLinejoin: "round"
2830
- }
2831
- )
3019
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 1v3h-3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
2832
3020
  ]
2833
3021
  }
2834
3022
  ),
@@ -2896,9 +3084,12 @@ function SessionsModal({ onClose }) {
2896
3084
  const [revokingFamilyId, setRevokingFamilyId] = react.useState(null);
2897
3085
  const [signingOutEverywhere, setSigningOutEverywhere] = react.useState(false);
2898
3086
  const mountedRef = react.useRef(true);
2899
- react.useEffect(() => () => {
2900
- mountedRef.current = false;
2901
- }, []);
3087
+ react.useEffect(
3088
+ () => () => {
3089
+ mountedRef.current = false;
3090
+ },
3091
+ []
3092
+ );
2902
3093
  const onCloseRef = react.useRef(onClose);
2903
3094
  onCloseRef.current = onClose;
2904
3095
  react.useEffect(() => {
@@ -2930,9 +3121,7 @@ function SessionsModal({ onClose }) {
2930
3121
  await load();
2931
3122
  } catch {
2932
3123
  if (!mountedRef.current) return;
2933
- setState(
2934
- (prev) => prev.step === "loaded" ? { step: "error", message: "Failed to revoke session" } : prev
2935
- );
3124
+ setState((prev) => prev.step === "loaded" ? { step: "error", message: "Failed to revoke session" } : prev);
2936
3125
  } finally {
2937
3126
  if (mountedRef.current) setRevokingFamilyId(null);
2938
3127
  }
@@ -2996,55 +3185,53 @@ function TransactionModalTemplate({
2996
3185
  "--pollar-input-border-radius": "0.5rem",
2997
3186
  "--pollar-card-border-radius": "10px"
2998
3187
  };
2999
- return /* @__PURE__ */ jsxRuntime.jsxs(
3000
- "div",
3001
- {
3002
- className: "pollar-modal-card pollar-tx-modal",
3003
- "data-theme": theme,
3004
- style: cssVars,
3005
- onClick: (e) => e.stopPropagation(),
3006
- children: [
3007
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-header", children: /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Transaction" }) }),
3008
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-close-btn", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsx(
3009
- "svg",
3010
- {
3011
- width: "18",
3012
- height: "18",
3013
- viewBox: "0 0 24 24",
3014
- fill: "none",
3015
- stroke: "currentColor",
3016
- strokeWidth: "2.5",
3017
- strokeLinecap: "round",
3018
- strokeLinejoin: "round",
3019
- "aria-hidden": true,
3020
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6L6 18M6 6l12 12" })
3021
- }
3022
- ) }),
3023
- /* @__PURE__ */ jsxRuntime.jsx(
3024
- TxStatusView,
3025
- {
3026
- transaction,
3027
- showXdr,
3028
- copied,
3029
- explorerUrl,
3030
- walletType,
3031
- onSignAndSend,
3032
- onToggleXdr,
3033
- onCopyHash,
3034
- onRetry,
3035
- onDone: onClose
3036
- }
3037
- ),
3038
- /* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
3039
- ]
3040
- }
3041
- );
3188
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-card pollar-tx-modal", "data-theme": theme, style: cssVars, onClick: (e) => e.stopPropagation(), children: [
3189
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-header", children: /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Transaction" }) }),
3190
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-close-btn", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsx(
3191
+ "svg",
3192
+ {
3193
+ width: "18",
3194
+ height: "18",
3195
+ viewBox: "0 0 24 24",
3196
+ fill: "none",
3197
+ stroke: "currentColor",
3198
+ strokeWidth: "2.5",
3199
+ strokeLinecap: "round",
3200
+ strokeLinejoin: "round",
3201
+ "aria-hidden": true,
3202
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6L6 18M6 6l12 12" })
3203
+ }
3204
+ ) }),
3205
+ /* @__PURE__ */ jsxRuntime.jsx(
3206
+ TxStatusView,
3207
+ {
3208
+ transaction,
3209
+ showXdr,
3210
+ copied,
3211
+ explorerUrl,
3212
+ walletType,
3213
+ onSignAndSend,
3214
+ onToggleXdr,
3215
+ onCopyHash,
3216
+ onRetry,
3217
+ onDone: onClose
3218
+ }
3219
+ ),
3220
+ /* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
3221
+ ] });
3042
3222
  }
3043
3223
  function TransactionModal({ onClose }) {
3044
3224
  const { getClient, styles, tx: transaction, network, walletType } = usePollar();
3045
3225
  const { theme = "light", accentColor = "#005DB4" } = styles;
3046
3226
  const [showXdr, setShowXdr] = react.useState(false);
3047
3227
  const [copied, setCopied] = react.useState(false);
3228
+ const copyTimerRef = react.useRef(null);
3229
+ react.useEffect(
3230
+ () => () => {
3231
+ if (copyTimerRef.current !== null) clearTimeout(copyTimerRef.current);
3232
+ },
3233
+ []
3234
+ );
3048
3235
  const hash = transaction.step === "success" ? transaction.hash : null;
3049
3236
  const buildData = "buildData" in transaction ? transaction.buildData : null;
3050
3237
  const explorerNetwork = buildData?.summary.network?.toLowerCase().includes("testnet") ? "testnet" : buildData ? "public" : network === "testnet" ? "testnet" : "public";
@@ -3058,7 +3245,11 @@ function TransactionModal({ onClose }) {
3058
3245
  if (!hash) return;
3059
3246
  navigator.clipboard.writeText(hash).then(() => {
3060
3247
  setCopied(true);
3061
- setTimeout(() => setCopied(false), 2e3);
3248
+ if (copyTimerRef.current !== null) clearTimeout(copyTimerRef.current);
3249
+ copyTimerRef.current = setTimeout(() => {
3250
+ copyTimerRef.current = null;
3251
+ setCopied(false);
3252
+ }, 2e3);
3062
3253
  });
3063
3254
  }
3064
3255
  async function handleRetry() {
@@ -3125,97 +3316,128 @@ function TxHistoryModalTemplate({
3125
3316
  const hasPrev = offset > 0;
3126
3317
  const hasNext = offset + PAGE_SIZE < total;
3127
3318
  const showPagination = txHistory.step === "loaded" && total > PAGE_SIZE;
3128
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-card pollar-hist-modal", "data-theme": theme, style: cssVars, onClick: (e) => e.stopPropagation(), children: [
3129
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
3130
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Transaction History" }),
3131
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
3132
- /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-modal-refresh-btn", onClick: onRefresh, disabled: isLoading, children: [
3133
- /* @__PURE__ */ jsxRuntime.jsxs(
3134
- "svg",
3135
- {
3136
- className: `pollar-modal-refresh-icon${isLoading ? " spinning" : ""}`,
3137
- width: "13",
3138
- height: "13",
3139
- viewBox: "0 0 13 13",
3140
- fill: "none",
3141
- "aria-hidden": true,
3142
- children: [
3143
- /* @__PURE__ */ jsxRuntime.jsx(
3144
- "path",
3319
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3320
+ "div",
3321
+ {
3322
+ className: "pollar-modal-card pollar-hist-modal",
3323
+ "data-theme": theme,
3324
+ style: cssVars,
3325
+ onClick: (e) => e.stopPropagation(),
3326
+ children: [
3327
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
3328
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Transaction History" }),
3329
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
3330
+ /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-modal-refresh-btn", onClick: onRefresh, disabled: isLoading, children: [
3331
+ /* @__PURE__ */ jsxRuntime.jsxs(
3332
+ "svg",
3333
+ {
3334
+ className: `pollar-modal-refresh-icon${isLoading ? " spinning" : ""}`,
3335
+ width: "13",
3336
+ height: "13",
3337
+ viewBox: "0 0 13 13",
3338
+ fill: "none",
3339
+ "aria-hidden": true,
3340
+ children: [
3341
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M11.5 6.5a5 5 0 11-1.5-3.536", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }),
3342
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 1v3h-3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
3343
+ ]
3344
+ }
3345
+ ),
3346
+ "Refresh"
3347
+ ] }),
3348
+ /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-modal-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2 2l12 12M14 2L2 14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) })
3349
+ ] })
3350
+ ] }),
3351
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-list", children: [
3352
+ txHistory.step === "idle" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "Click Refresh to load transactions." }),
3353
+ isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "Loading\u2026" }),
3354
+ txHistory.step === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: txHistory.message }),
3355
+ txHistory.step === "loaded" && records.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No transactions yet." }),
3356
+ records.map((record) => {
3357
+ const explorerUrl = `https://stellar.expert/explorer/${record.network === "testnet" ? "testnet" : "public"}/tx/${record.hash}`;
3358
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-item", children: [
3359
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-hist-item-summary", children: record.summary }),
3360
+ /* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: record.status }),
3361
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-hist-item-meta", children: [
3362
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: record.operation }),
3363
+ record.feeXlm && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
3364
+ "\xB7 ",
3365
+ record.feeXlm,
3366
+ " XLM"
3367
+ ] }),
3368
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
3369
+ "\xB7 ",
3370
+ formatDate(record.createdAt)
3371
+ ] }),
3372
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\xB7" }),
3373
+ /* @__PURE__ */ jsxRuntime.jsxs(
3374
+ "a",
3145
3375
  {
3146
- d: "M11.5 6.5a5 5 0 11-1.5-3.536",
3147
- stroke: "currentColor",
3148
- strokeWidth: "1.5",
3149
- strokeLinecap: "round"
3376
+ className: "pollar-hist-item-explorer",
3377
+ href: explorerUrl,
3378
+ target: "_blank",
3379
+ rel: "noopener noreferrer",
3380
+ "aria-label": "View on Stellar Explorer",
3381
+ children: [
3382
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "11", height: "11", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
3383
+ /* @__PURE__ */ jsxRuntime.jsx(
3384
+ "path",
3385
+ {
3386
+ d: "M5 2H2a1 1 0 00-1 1v8a1 1 0 001 1h8a1 1 0 001-1V8",
3387
+ stroke: "currentColor",
3388
+ strokeWidth: "1.5",
3389
+ strokeLinecap: "round"
3390
+ }
3391
+ ),
3392
+ /* @__PURE__ */ jsxRuntime.jsx(
3393
+ "path",
3394
+ {
3395
+ d: "M8 1h4m0 0v4m0-4L6 7",
3396
+ stroke: "currentColor",
3397
+ strokeWidth: "1.5",
3398
+ strokeLinecap: "round",
3399
+ strokeLinejoin: "round"
3400
+ }
3401
+ )
3402
+ ] }),
3403
+ "Explorer"
3404
+ ]
3150
3405
  }
3151
- ),
3152
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 1v3h-3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
3153
- ]
3154
- }
3155
- ),
3156
- "Refresh"
3406
+ )
3407
+ ] })
3408
+ ] }, record.id);
3409
+ })
3157
3410
  ] }),
3158
- /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-modal-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2 2l12 12M14 2L2 14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) })
3159
- ] })
3160
- ] }),
3161
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-list", children: [
3162
- txHistory.step === "idle" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "Click Refresh to load transactions." }),
3163
- isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "Loading\u2026" }),
3164
- txHistory.step === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: txHistory.message }),
3165
- txHistory.step === "loaded" && records.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No transactions yet." }),
3166
- records.map((record) => {
3167
- const explorerUrl = `https://stellar.expert/explorer/${record.network === "testnet" ? "testnet" : "public"}/tx/${record.hash}`;
3168
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-item", children: [
3169
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-hist-item-summary", children: record.summary }),
3170
- /* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: record.status }),
3171
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-hist-item-meta", children: [
3172
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: record.operation }),
3173
- record.feeXlm && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
3174
- "\xB7 ",
3175
- record.feeXlm,
3176
- " XLM"
3177
- ] }),
3178
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
3179
- "\xB7 ",
3180
- formatDate(record.createdAt)
3181
- ] }),
3182
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\xB7" }),
3183
- /* @__PURE__ */ jsxRuntime.jsxs("a", { className: "pollar-hist-item-explorer", href: explorerUrl, target: "_blank", rel: "noopener noreferrer", "aria-label": "View on Stellar Explorer", children: [
3184
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "11", height: "11", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
3185
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 2H2a1 1 0 00-1 1v8a1 1 0 001 1h8a1 1 0 001-1V8", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }),
3186
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 1h4m0 0v4m0-4L6 7", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
3187
- ] }),
3188
- "Explorer"
3189
- ] })
3411
+ showPagination && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-pagination", children: [
3412
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-hist-pagination-info", children: [
3413
+ offset + 1,
3414
+ "\u2013",
3415
+ Math.min(offset + PAGE_SIZE, total),
3416
+ " of ",
3417
+ total
3418
+ ] }),
3419
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-pagination-btns", children: [
3420
+ /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-hist-page-btn", onClick: onPrev, disabled: !hasPrev, children: "\u2190 Prev" }),
3421
+ /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-hist-page-btn", onClick: onNext, disabled: !hasNext, children: "Next \u2192" })
3190
3422
  ] })
3191
- ] }, record.id);
3192
- })
3193
- ] }),
3194
- showPagination && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-pagination", children: [
3195
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-hist-pagination-info", children: [
3196
- offset + 1,
3197
- "\u2013",
3198
- Math.min(offset + PAGE_SIZE, total),
3199
- " of ",
3200
- total
3201
- ] }),
3202
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-pagination-btns", children: [
3203
- /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-hist-page-btn", onClick: onPrev, disabled: !hasPrev, children: "\u2190 Prev" }),
3204
- /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-hist-page-btn", onClick: onNext, disabled: !hasNext, children: "Next \u2192" })
3205
- ] })
3206
- ] }),
3207
- /* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
3208
- ] });
3423
+ ] }),
3424
+ /* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
3425
+ ]
3426
+ }
3427
+ );
3209
3428
  }
3210
3429
  var PAGE_SIZE2 = 10;
3211
3430
  function TxHistoryModal({ onClose }) {
3212
3431
  const { getClient, styles, txHistory } = usePollar();
3213
3432
  const { theme = "light", accentColor = "#005DB4" } = styles;
3214
3433
  const [offset, setOffset] = react.useState(0);
3215
- const load = react.useCallback((nextOffset) => {
3216
- setOffset(nextOffset);
3217
- void getClient().fetchTxHistory({ limit: PAGE_SIZE2, offset: nextOffset });
3218
- }, [getClient]);
3434
+ const load = react.useCallback(
3435
+ (nextOffset) => {
3436
+ setOffset(nextOffset);
3437
+ void getClient().fetchTxHistory({ limit: PAGE_SIZE2, offset: nextOffset });
3438
+ },
3439
+ [getClient]
3440
+ );
3219
3441
  react.useEffect(() => {
3220
3442
  load(0);
3221
3443
  }, [load]);
@@ -3338,28 +3560,31 @@ function WalletBalanceModal({ onClose }) {
3338
3560
  }
3339
3561
  ) });
3340
3562
  }
3341
- var emptyResponse = {
3342
- application: {
3343
- name: ""
3344
- },
3563
+ var DEFAULT_APP_CONFIG = {
3564
+ application: { name: "" },
3345
3565
  styles: {}
3346
3566
  };
3347
- async function fetchRemoteConfig(client) {
3348
- const content = await client.getAppConfig();
3349
- return content ?? emptyResponse;
3567
+ function sessionsEqual(a, b) {
3568
+ if (a === b) return true;
3569
+ if (!a || !b) return false;
3570
+ return a.clientSessionId === b.clientSessionId && a.userId === b.userId && a.status === b.status && a.token?.accessToken === b.token?.accessToken && a.token?.refreshToken === b.token?.refreshToken && a.token?.expiresAt === b.token?.expiresAt && a.wallet?.publicKey === b.wallet?.publicKey;
3350
3571
  }
3351
3572
  var PollarContext = react.createContext(null);
3352
- function PollarProvider({ config, styles: propStyles, adapters, children }) {
3353
- const [pollarClient] = react.useState(() => new core.PollarClient(config));
3573
+ function PollarProvider({
3574
+ client,
3575
+ appConfig: appConfigProp,
3576
+ ui,
3577
+ adapters,
3578
+ onStorageDegrade,
3579
+ children
3580
+ }) {
3581
+ const [pollarClient] = react.useState(() => client instanceof core.PollarClient ? client : new core.PollarClient(client));
3354
3582
  const [networkState, setNetworkState] = react.useState(() => pollarClient.getNetworkState());
3355
3583
  const [sessionState, setSessionState] = react.useState(null);
3356
3584
  const [transaction, setTransaction] = react.useState({ step: "idle" });
3357
3585
  const [txHistory, setTxHistory] = react.useState({ step: "idle" });
3358
3586
  const [walletBalance, setWalletBalance] = react.useState({ step: "idle" });
3359
- const [remoteConfig, setRemoteConfig] = react.useState(emptyResponse);
3360
- const [styles, setStyles] = react.useState(propStyles ?? {});
3361
- const propStylesRef = react.useRef(propStyles);
3362
- propStylesRef.current = propStyles;
3587
+ const [resolvedConfig, setResolvedConfig] = react.useState(() => appConfigProp ?? DEFAULT_APP_CONFIG);
3363
3588
  react.useEffect(() => {
3364
3589
  return pollarClient.onTransactionStateChange(setTransaction);
3365
3590
  }, [pollarClient]);
@@ -3374,28 +3599,32 @@ function PollarProvider({ config, styles: propStyles, adapters, children }) {
3374
3599
  setNetworkState(state);
3375
3600
  });
3376
3601
  }, [pollarClient]);
3602
+ react.useEffect(() => {
3603
+ if (!onStorageDegrade) return;
3604
+ return pollarClient.onStorageDegrade(onStorageDegrade);
3605
+ }, [pollarClient, onStorageDegrade]);
3377
3606
  react.useEffect(() => {
3378
3607
  return pollarClient.onAuthStateChange((authState) => {
3379
3608
  if (authState.step === "authenticated") {
3380
- setSessionState((prev) => JSON.stringify(prev) !== JSON.stringify(authState.session) ? authState.session : prev);
3609
+ setSessionState((prev) => sessionsEqual(prev, authState.session) ? prev : authState.session);
3381
3610
  } else if (authState.step === "idle") {
3382
3611
  setSessionState(null);
3383
3612
  }
3384
3613
  });
3385
3614
  }, [pollarClient]);
3386
3615
  react.useEffect(() => {
3387
- const propStyles2 = propStylesRef.current;
3388
- fetchRemoteConfig(pollarClient).then((fetched) => {
3389
- setRemoteConfig(fetched);
3390
- setStyles({
3391
- ...fetched.styles,
3392
- ...propStyles2,
3393
- providers: { ...fetched.styles?.providers, ...propStyles2?.providers }
3394
- });
3395
- }).catch(() => {
3396
- setStyles(propStyles2 ?? {});
3616
+ if (appConfigProp !== void 0) return;
3617
+ let cancelled = false;
3618
+ pollarClient.getAppConfig().then((fetched) => {
3619
+ if (cancelled || !fetched) return;
3620
+ setResolvedConfig(fetched);
3621
+ }).catch((err) => {
3622
+ console.error("[PollarProvider] getAppConfig failed", err);
3397
3623
  });
3398
- }, [pollarClient]);
3624
+ return () => {
3625
+ cancelled = true;
3626
+ };
3627
+ }, [pollarClient, appConfigProp]);
3399
3628
  const [loginModalOpen, setLoginModalOpen] = react.useState(false);
3400
3629
  const [transactionModalOpen, setTransactionModalOpen] = react.useState(false);
3401
3630
  const [kycModalOpen, setKycModalOpen] = react.useState(false);
@@ -3407,13 +3636,13 @@ function PollarProvider({ config, styles: propStyles, adapters, children }) {
3407
3636
  const [receiveModalOpen, setReceiveModalOpen] = react.useState(false);
3408
3637
  const [sessionsModalOpen, setSessionsModalOpen] = react.useState(false);
3409
3638
  const [distributionRulesModalOpen, setDistributionRulesModalOpen] = react.useState(false);
3410
- const adaptersRef = react.useRef(adapters);
3411
- adaptersRef.current = adapters;
3412
3639
  const walletAddress = sessionState?.wallet?.publicKey || "";
3413
3640
  const getClient = react.useCallback(() => pollarClient, [pollarClient]);
3414
3641
  const refreshWalletBalance = react.useCallback(() => pollarClient.refreshBalance(walletAddress), [pollarClient, walletAddress]);
3415
- const contextValue = react.useMemo(
3416
- () => ({
3642
+ const renderWallets = ui?.renderWallets;
3643
+ const contextValue = react.useMemo(() => {
3644
+ const styles = resolvedConfig.styles ?? {};
3645
+ return {
3417
3646
  // session
3418
3647
  walletAddress,
3419
3648
  isAuthenticated: !!walletAddress,
@@ -3428,6 +3657,10 @@ function PollarProvider({ config, styles: propStyles, adapters, children }) {
3428
3657
  tx: transaction,
3429
3658
  buildTx: (operation, params, options) => pollarClient.buildTx(operation, params, options),
3430
3659
  signAndSubmitTx: (unsignedXdr) => pollarClient.signAndSubmitTx(unsignedXdr),
3660
+ signTx: (unsignedXdr) => pollarClient.signTx(unsignedXdr),
3661
+ submitTx: (signedXdr) => pollarClient.submitTx(signedXdr),
3662
+ buildAndSignAndSubmitTx: (operation, params, options) => pollarClient.buildAndSignAndSubmitTx(operation, params, options),
3663
+ runTx: (operation, params, options) => pollarClient.runTx(operation, params, options),
3431
3664
  openTxModal: () => setTransactionModalOpen(true),
3432
3665
  // tx history
3433
3666
  txHistory,
@@ -3454,23 +3687,24 @@ function PollarProvider({ config, styles: propStyles, adapters, children }) {
3454
3687
  // ramp
3455
3688
  openRampModal: () => setRampModalOpen(true),
3456
3689
  // config
3457
- appConfig: remoteConfig,
3690
+ appConfig: resolvedConfig,
3458
3691
  styles,
3459
- adapters: adaptersRef.current
3460
- }),
3461
- [
3462
- walletAddress,
3463
- pollarClient,
3464
- getClient,
3465
- transaction,
3466
- txHistory,
3467
- walletBalance,
3468
- refreshWalletBalance,
3469
- networkState,
3470
- remoteConfig,
3471
- styles
3472
- ]
3473
- );
3692
+ renderWallets,
3693
+ adapters
3694
+ };
3695
+ }, [
3696
+ walletAddress,
3697
+ pollarClient,
3698
+ getClient,
3699
+ transaction,
3700
+ txHistory,
3701
+ walletBalance,
3702
+ refreshWalletBalance,
3703
+ networkState,
3704
+ resolvedConfig,
3705
+ adapters,
3706
+ renderWallets
3707
+ ]);
3474
3708
  return /* @__PURE__ */ jsxRuntime.jsxs(PollarContext.Provider, { value: contextValue, children: [
3475
3709
  children,
3476
3710
  loginModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setLoginModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(LoginModal, { onClose: () => setLoginModalOpen(false) }) }),
@@ -3514,7 +3748,7 @@ function createPollarAdapterHook(key) {
3514
3748
  name,
3515
3749
  async (params) => {
3516
3750
  const { unsignedTransaction } = await fn(params);
3517
- await signAndSubmitTx(unsignedTransaction);
3751
+ return signAndSubmitTx(unsignedTransaction);
3518
3752
  }
3519
3753
  ])
3520
3754
  );
@@ -3563,33 +3797,22 @@ function WalletButtonTemplate({
3563
3797
  "aria-busy": isInProgress,
3564
3798
  children: [
3565
3799
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "wallet-btn-label", children: cropWallet(walletAddress) }),
3566
- isInProgress ? /* @__PURE__ */ jsxRuntime.jsxs(
3567
- "svg",
3568
- {
3569
- className: "wallet-btn-spinner",
3570
- viewBox: "0 0 12 12",
3571
- width: "12",
3572
- height: "12",
3573
- fill: "none",
3574
- "aria-hidden": true,
3575
- children: [
3576
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "6", cy: "6", r: "4.5", stroke: "rgba(255,255,255,0.35)", strokeWidth: "1.5" }),
3577
- /* @__PURE__ */ jsxRuntime.jsx(
3578
- "circle",
3579
- {
3580
- cx: "6",
3581
- cy: "6",
3582
- r: "4.5",
3583
- stroke: "white",
3584
- strokeWidth: "1.5",
3585
- strokeLinecap: "round",
3586
- strokeDasharray: "14 9",
3587
- transform: "rotate(-90 6 6)"
3588
- }
3589
- )
3590
- ]
3591
- }
3592
- ) : /* @__PURE__ */ jsxRuntime.jsx(
3800
+ isInProgress ? /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "wallet-btn-spinner", viewBox: "0 0 12 12", width: "12", height: "12", fill: "none", "aria-hidden": true, children: [
3801
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "6", cy: "6", r: "4.5", stroke: "rgba(255,255,255,0.35)", strokeWidth: "1.5" }),
3802
+ /* @__PURE__ */ jsxRuntime.jsx(
3803
+ "circle",
3804
+ {
3805
+ cx: "6",
3806
+ cy: "6",
3807
+ r: "4.5",
3808
+ stroke: "white",
3809
+ strokeWidth: "1.5",
3810
+ strokeLinecap: "round",
3811
+ strokeDasharray: "14 9",
3812
+ transform: "rotate(-90 6 6)"
3813
+ }
3814
+ )
3815
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(
3593
3816
  "svg",
3594
3817
  {
3595
3818
  className: `wallet-chevron${open ? " open" : ""}`,
@@ -3607,53 +3830,131 @@ function WalletButtonTemplate({
3607
3830
  ),
3608
3831
  open && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "wallet-dropdown", style: { backgroundColor: dropdownBg, borderColor: dropdownBorder }, children: [
3609
3832
  /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "wallet-dropdown-item", style: { color: itemColor }, onClick: onSend, children: [
3610
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
3611
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "22", y1: "2", x2: "11", y2: "13" }),
3612
- /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
3613
- ] }),
3833
+ /* @__PURE__ */ jsxRuntime.jsxs(
3834
+ "svg",
3835
+ {
3836
+ width: "14",
3837
+ height: "14",
3838
+ viewBox: "0 0 24 24",
3839
+ fill: "none",
3840
+ stroke: "currentColor",
3841
+ strokeWidth: "2",
3842
+ strokeLinecap: "round",
3843
+ strokeLinejoin: "round",
3844
+ children: [
3845
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "22", y1: "2", x2: "11", y2: "13" }),
3846
+ /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
3847
+ ]
3848
+ }
3849
+ ),
3614
3850
  "Send"
3615
3851
  ] }),
3616
3852
  /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "wallet-dropdown-item", style: { color: itemColor }, onClick: onReceive, children: [
3617
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
3618
- /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "8 17 12 21 16 17" }),
3619
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "12", x2: "12", y2: "21" }),
3620
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20.88 18.09A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.29" })
3621
- ] }),
3853
+ /* @__PURE__ */ jsxRuntime.jsxs(
3854
+ "svg",
3855
+ {
3856
+ width: "14",
3857
+ height: "14",
3858
+ viewBox: "0 0 24 24",
3859
+ fill: "none",
3860
+ stroke: "currentColor",
3861
+ strokeWidth: "2",
3862
+ strokeLinecap: "round",
3863
+ strokeLinejoin: "round",
3864
+ children: [
3865
+ /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "8 17 12 21 16 17" }),
3866
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "12", x2: "12", y2: "21" }),
3867
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20.88 18.09A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.29" })
3868
+ ]
3869
+ }
3870
+ ),
3622
3871
  "Receive"
3623
3872
  ] }),
3624
3873
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "wallet-dropdown-divider" }),
3625
3874
  /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "wallet-dropdown-item", style: { color: itemColor }, onClick: onCopy, children: [
3626
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
3627
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
3628
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
3629
- ] }),
3875
+ /* @__PURE__ */ jsxRuntime.jsxs(
3876
+ "svg",
3877
+ {
3878
+ width: "14",
3879
+ height: "14",
3880
+ viewBox: "0 0 24 24",
3881
+ fill: "none",
3882
+ stroke: "currentColor",
3883
+ strokeWidth: "2",
3884
+ strokeLinecap: "round",
3885
+ strokeLinejoin: "round",
3886
+ children: [
3887
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
3888
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
3889
+ ]
3890
+ }
3891
+ ),
3630
3892
  copied ? "Copied!" : "Copy address"
3631
3893
  ] }),
3632
3894
  /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "wallet-dropdown-item", style: { color: itemColor }, onClick: onWalletBalance, children: [
3633
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
3634
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "1", y: "4", width: "22", height: "16", rx: "2", ry: "2" }),
3635
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "16", cy: "12", r: "2" }),
3636
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M22 8H12" })
3637
- ] }),
3895
+ /* @__PURE__ */ jsxRuntime.jsxs(
3896
+ "svg",
3897
+ {
3898
+ width: "14",
3899
+ height: "14",
3900
+ viewBox: "0 0 24 24",
3901
+ fill: "none",
3902
+ stroke: "currentColor",
3903
+ strokeWidth: "2",
3904
+ strokeLinecap: "round",
3905
+ strokeLinejoin: "round",
3906
+ children: [
3907
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "1", y: "4", width: "22", height: "16", rx: "2", ry: "2" }),
3908
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "16", cy: "12", r: "2" }),
3909
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M22 8H12" })
3910
+ ]
3911
+ }
3912
+ ),
3638
3913
  "Wallet balance"
3639
3914
  ] }),
3640
3915
  /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "wallet-dropdown-item", style: { color: itemColor }, onClick: onTxHistory, children: [
3641
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
3642
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
3643
- /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "14,2 14,8 20,8" }),
3644
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "16", y1: "13", x2: "8", y2: "13" }),
3645
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "16", y1: "17", x2: "8", y2: "17" }),
3646
- /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "10,9 9,9 8,9" })
3647
- ] }),
3916
+ /* @__PURE__ */ jsxRuntime.jsxs(
3917
+ "svg",
3918
+ {
3919
+ width: "14",
3920
+ height: "14",
3921
+ viewBox: "0 0 24 24",
3922
+ fill: "none",
3923
+ stroke: "currentColor",
3924
+ strokeWidth: "2",
3925
+ strokeLinecap: "round",
3926
+ strokeLinejoin: "round",
3927
+ children: [
3928
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
3929
+ /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "14,2 14,8 20,8" }),
3930
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "16", y1: "13", x2: "8", y2: "13" }),
3931
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "16", y1: "17", x2: "8", y2: "17" }),
3932
+ /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "10,9 9,9 8,9" })
3933
+ ]
3934
+ }
3935
+ ),
3648
3936
  "Transaction history"
3649
3937
  ] }),
3650
3938
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "wallet-dropdown-divider" }),
3651
3939
  /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "wallet-dropdown-item danger", onClick: onLogout, children: [
3652
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
3653
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" }),
3654
- /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "16,17 21,12 16,7" }),
3655
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "21", y1: "12", x2: "9", y2: "12" })
3656
- ] }),
3940
+ /* @__PURE__ */ jsxRuntime.jsxs(
3941
+ "svg",
3942
+ {
3943
+ width: "14",
3944
+ height: "14",
3945
+ viewBox: "0 0 24 24",
3946
+ fill: "none",
3947
+ stroke: "currentColor",
3948
+ strokeWidth: "2",
3949
+ strokeLinecap: "round",
3950
+ strokeLinejoin: "round",
3951
+ children: [
3952
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" }),
3953
+ /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "16,17 21,12 16,7" }),
3954
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "21", y1: "12", x2: "9", y2: "12" })
3955
+ ]
3956
+ }
3957
+ ),
3657
3958
  "Log out"
3658
3959
  ] })
3659
3960
  ] })
@@ -3675,6 +3976,7 @@ function WalletButton() {
3675
3976
  const [open, setOpen] = react.useState(false);
3676
3977
  const [copied, setCopied] = react.useState(false);
3677
3978
  const wrapperRef = react.useRef(null);
3979
+ const copyTimerRef = react.useRef(null);
3678
3980
  const isInProgress = transaction.step === "building" || transaction.step === "signing";
3679
3981
  const { theme = "light", accentColor = "#005DB4" } = styles;
3680
3982
  const isDark = theme === "dark";
@@ -3690,11 +3992,21 @@ function WalletButton() {
3690
3992
  document.addEventListener("mousedown", handleClickOutside);
3691
3993
  return () => document.removeEventListener("mousedown", handleClickOutside);
3692
3994
  }, []);
3995
+ react.useEffect(
3996
+ () => () => {
3997
+ if (copyTimerRef.current !== null) clearTimeout(copyTimerRef.current);
3998
+ },
3999
+ []
4000
+ );
3693
4001
  async function handleCopy() {
3694
4002
  if (!walletAddress) return;
3695
4003
  await navigator.clipboard.writeText(walletAddress);
3696
4004
  setCopied(true);
3697
- setTimeout(() => setCopied(false), 1500);
4005
+ if (copyTimerRef.current !== null) clearTimeout(copyTimerRef.current);
4006
+ copyTimerRef.current = setTimeout(() => {
4007
+ copyTimerRef.current = null;
4008
+ setCopied(false);
4009
+ }, 1500);
3698
4010
  }
3699
4011
  function handleLogout() {
3700
4012
  setOpen(false);