@pollar/react 0.7.0 → 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.0"
1033
+ "0.8.0"
1034
1034
  ] })
1035
1035
  ] })
1036
1036
  ] });
@@ -1054,6 +1054,212 @@ function ModalStatusBanner({ message, status, onCancel, onRetry }) {
1054
1054
  status === "ERROR" && onRetry && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-status-cancel", onClick: onRetry, children: "Retry" })
1055
1055
  ] });
1056
1056
  }
1057
+ var PERIOD_LABEL = {
1058
+ DAY: "every 24h",
1059
+ DAY_CALENDAR: "daily",
1060
+ WEEK: "every 7 days",
1061
+ MONTH: "every 30 days",
1062
+ MONTH_CALENDAR: "monthly",
1063
+ LIFETIME: "one-time"
1064
+ };
1065
+ var REASON_LABEL = {
1066
+ DISTRIBUTION_RULE_DISABLED: "Disabled",
1067
+ DISTRIBUTION_RULE_NOT_STARTED: "Not started yet",
1068
+ DISTRIBUTION_RULE_EXPIRED: "Expired",
1069
+ DISTRIBUTION_RULE_EXHAUSTED: "Fully claimed",
1070
+ DISTRIBUTION_RATE_LIMIT_EXCEEDED: "Already claimed"
1071
+ };
1072
+ function reasonLabel(reason) {
1073
+ if (!reason) return "Not available";
1074
+ return REASON_LABEL[reason] ?? "Not available";
1075
+ }
1076
+ function formatAmount(amount) {
1077
+ const n = parseFloat(amount);
1078
+ return isNaN(n) ? amount : n.toLocaleString(void 0, { maximumFractionDigits: 7 });
1079
+ }
1080
+ function formatValidity(rule) {
1081
+ const from = rule.validFrom ? new Date(rule.validFrom) : null;
1082
+ const until = rule.validUntil ? new Date(rule.validUntil) : null;
1083
+ if (!from && !until) return null;
1084
+ const fmt = (d) => d.toLocaleDateString(void 0, { month: "short", day: "numeric", year: "numeric" });
1085
+ if (from && until) return `${fmt(from)} \u2192 ${fmt(until)}`;
1086
+ if (until) return `Until ${fmt(until)}`;
1087
+ if (from) return `From ${fmt(from)}`;
1088
+ return null;
1089
+ }
1090
+ function RuleCard({
1091
+ rule,
1092
+ isClaiming,
1093
+ isClaimed,
1094
+ errorMessage,
1095
+ onClaim
1096
+ }) {
1097
+ const validity = formatValidity(rule);
1098
+ const effectivelyClaimable = rule.claimable && !isClaimed;
1099
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-dist-item", "data-claimable": effectivelyClaimable ? "true" : "false", children: [
1100
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-dist-item-row", children: [
1101
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-dist-item-name", children: rule.name }),
1102
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-dist-item-amount", children: [
1103
+ formatAmount(rule.amount),
1104
+ " ",
1105
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-dist-item-asset", children: rule.assetCode })
1106
+ ] })
1107
+ ] }),
1108
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-dist-item-meta", children: [
1109
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: PERIOD_LABEL[rule.period] }),
1110
+ validity && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
1111
+ "\xB7 ",
1112
+ validity
1113
+ ] })
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("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) }) }),
1116
+ errorMessage && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-dist-item-error", children: errorMessage })
1117
+ ] });
1118
+ }
1119
+ function DistributionRulesModalTemplate({
1120
+ theme,
1121
+ accentColor,
1122
+ state,
1123
+ claimingId,
1124
+ claimErrors,
1125
+ claimedIds,
1126
+ onRefresh,
1127
+ onClaim,
1128
+ onClose
1129
+ }) {
1130
+ const isDark = theme === "dark";
1131
+ const cssVars = {
1132
+ "--pollar-accent": accentColor,
1133
+ "--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
1134
+ "--pollar-border": isDark ? "#374151" : "#e5e7eb",
1135
+ "--pollar-text": isDark ? "#ffffff" : "#111827",
1136
+ "--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
1137
+ "--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
1138
+ "--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
1139
+ "--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
1140
+ "--pollar-error-text": isDark ? "#f87171" : "#dc2626",
1141
+ "--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
1142
+ "--pollar-buttons-border-radius": "6px",
1143
+ "--pollar-buttons-height": "44px",
1144
+ "--pollar-input-height": "44px",
1145
+ "--pollar-input-border-radius": "0.5rem",
1146
+ "--pollar-card-border-radius": "10px"
1147
+ };
1148
+ const isLoading = state.step === "loading";
1149
+ const rules = state.step === "loaded" ? state.rules : [];
1150
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1151
+ "div",
1152
+ {
1153
+ className: "pollar-modal-card pollar-dist-modal",
1154
+ "data-theme": theme,
1155
+ style: cssVars,
1156
+ onClick: (e) => e.stopPropagation(),
1157
+ children: [
1158
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
1159
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Distribution Rules" }),
1160
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
1161
+ /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-modal-refresh-btn", onClick: onRefresh, disabled: isLoading, children: [
1162
+ /* @__PURE__ */ jsxRuntime.jsxs(
1163
+ "svg",
1164
+ {
1165
+ className: `pollar-modal-refresh-icon${isLoading ? " spinning" : ""}`,
1166
+ width: "13",
1167
+ height: "13",
1168
+ viewBox: "0 0 13 13",
1169
+ fill: "none",
1170
+ "aria-hidden": true,
1171
+ children: [
1172
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M11.5 6.5a5 5 0 11-1.5-3.536", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }),
1173
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 1v3h-3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
1174
+ ]
1175
+ }
1176
+ ),
1177
+ "Refresh"
1178
+ ] }),
1179
+ /* @__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" }) }) })
1180
+ ] })
1181
+ ] }),
1182
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-dist-list", children: [
1183
+ isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "Loading\u2026" }),
1184
+ state.step === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: state.message }),
1185
+ state.step === "loaded" && rules.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No distribution rules available." }),
1186
+ rules.map((rule) => /* @__PURE__ */ jsxRuntime.jsx(
1187
+ RuleCard,
1188
+ {
1189
+ rule,
1190
+ isClaiming: claimingId === rule.id,
1191
+ isClaimed: claimedIds.has(rule.id),
1192
+ ...claimErrors[rule.id] && { errorMessage: claimErrors[rule.id] },
1193
+ onClaim: () => onClaim(rule)
1194
+ },
1195
+ rule.id
1196
+ ))
1197
+ ] }),
1198
+ /* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
1199
+ ]
1200
+ }
1201
+ );
1202
+ }
1203
+ function DistributionRulesModal({ onClose }) {
1204
+ const { getClient, styles } = usePollar();
1205
+ const { theme = "light", accentColor = "#005DB4" } = styles;
1206
+ const [state, setState] = react.useState({ step: "idle" });
1207
+ const [claimingId, setClaimingId] = react.useState(null);
1208
+ const [claimErrors, setClaimErrors] = react.useState({});
1209
+ const [claimedIds, setClaimedIds] = react.useState(() => /* @__PURE__ */ new Set());
1210
+ const load = react.useCallback(async () => {
1211
+ setState({ step: "loading" });
1212
+ try {
1213
+ const rules = await getClient().listDistributionRules();
1214
+ setState({ step: "loaded", rules });
1215
+ } catch (err) {
1216
+ const message = err instanceof Error ? err.message : "Failed to load distribution rules";
1217
+ setState({ step: "error", message });
1218
+ }
1219
+ }, [getClient]);
1220
+ react.useEffect(() => {
1221
+ void load();
1222
+ }, [load]);
1223
+ const handleClaim = react.useCallback(
1224
+ async (rule) => {
1225
+ setClaimingId(rule.id);
1226
+ setClaimErrors((prev) => {
1227
+ if (!prev[rule.id]) return prev;
1228
+ const next = { ...prev };
1229
+ delete next[rule.id];
1230
+ return next;
1231
+ });
1232
+ try {
1233
+ await getClient().claimDistributionRule({ ruleId: rule.id });
1234
+ setClaimedIds((prev) => {
1235
+ const next = new Set(prev);
1236
+ next.add(rule.id);
1237
+ return next;
1238
+ });
1239
+ } catch (err) {
1240
+ const message = err instanceof Error ? err.message : "Claim failed";
1241
+ setClaimErrors((prev) => ({ ...prev, [rule.id]: message }));
1242
+ } finally {
1243
+ setClaimingId(null);
1244
+ }
1245
+ },
1246
+ [getClient]
1247
+ );
1248
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
1249
+ DistributionRulesModalTemplate,
1250
+ {
1251
+ theme,
1252
+ accentColor,
1253
+ state,
1254
+ claimingId,
1255
+ claimErrors,
1256
+ claimedIds,
1257
+ onRefresh: () => void load(),
1258
+ onClaim: handleClaim,
1259
+ onClose
1260
+ }
1261
+ ) });
1262
+ }
1057
1263
  var STATUS_CONFIG = {
1058
1264
  none: { label: "Not started", color: "#6b7280", dot: false },
1059
1265
  pending: { label: "Pending review", color: "#f59e0b", dot: true },
@@ -1120,10 +1326,20 @@ function KycModalTemplate({
1120
1326
  ] }),
1121
1327
  step === "select_provider" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-kyc-providers", children: [
1122
1328
  providers.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { color: "var(--pollar-muted)", textAlign: "center" }, children: "No providers available for your country." }),
1123
- providers.map((p) => /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "pollar-kyc-provider-btn", disabled: isLoading, onClick: () => onSelectProvider(p), children: [
1124
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-kyc-provider-name", children: p.name }),
1125
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-kyc-provider-flow", children: p.flow })
1126
- ] }, 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
+ ))
1127
1343
  ] }),
1128
1344
  step === "verifying" && selectedProvider && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1129
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: [
@@ -1242,8 +1458,7 @@ function EmailCodeInput({ email, onSubmit }) {
1242
1458
  }
1243
1459
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-code-section", children: [
1244
1460
  /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "pollar-code-label", children: [
1245
- "Enter the 6-digit code sent to",
1246
- " ",
1461
+ "Enter the 6-digit code sent to ",
1247
1462
  email ? /* @__PURE__ */ jsxRuntime.jsx("strong", { children: email }) : "your email"
1248
1463
  ] }),
1249
1464
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-code-inputs", children: digits.map((digit, i) => /* @__PURE__ */ jsxRuntime.jsx(
@@ -1267,7 +1482,14 @@ function EmailCodeInput({ email, onSubmit }) {
1267
1482
  }
1268
1483
  var GithubButton = ({ disabled, onClick }) => {
1269
1484
  return /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "github-button", disabled, onClick, children: [
1270
- /* @__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
+ ) }),
1271
1493
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "github-button-contents", children: "GitHub" })
1272
1494
  ] });
1273
1495
  };
@@ -1320,6 +1542,36 @@ var GoogleButton = ({ disabled, onClick }) => {
1320
1542
  ] })
1321
1543
  ] });
1322
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
+ }
1323
1575
  var AUTH_STATE_MESSAGES = {
1324
1576
  idle: "",
1325
1577
  creating_session: "Initializing\u2026",
@@ -1364,8 +1616,8 @@ function LoginModalTemplate({
1364
1616
  onEmailChange,
1365
1617
  onEmailSubmit,
1366
1618
  onSocialLogin,
1367
- onFreighterConnect,
1368
- onAlbedoConnect,
1619
+ onWalletConnect,
1620
+ renderWallets,
1369
1621
  authState,
1370
1622
  codeInputKey,
1371
1623
  onCodeSubmit,
@@ -1401,9 +1653,35 @@ function LoginModalTemplate({
1401
1653
  const isEmailCodeError = authState.step === "error" && (authState.errorCode === core.AUTH_ERROR_CODES.EMAIL_CODE_EXPIRED || authState.errorCode === core.AUTH_ERROR_CODES.EMAIL_CODE_INVALID);
1402
1654
  const awaitingEmailCode = authState.step === "entering_code" || authState.step === "verifying_email_code" || isEmailCodeError;
1403
1655
  const statusMessage = authState.step === "error" ? authState.message : AUTH_STATE_MESSAGES[authState.step];
1404
- 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
+ ) });
1405
1670
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-card pollar-modal", style: cssVars, onClick: (e) => e.stopPropagation(), children: [
1406
- /* @__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
+ ) }),
1407
1685
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-header", children: [
1408
1686
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-logo-wrap", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: logoUrl ?? LOGO_POLLAR, alt: "Logo", className: "pollar-logo" }) }),
1409
1687
  /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-title", children: appName }),
@@ -1415,34 +1693,7 @@ function LoginModalTemplate({
1415
1693
  }) }, codeInputKey)
1416
1694
  ] }) : showWalletPicker ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1417
1695
  /* @__PURE__ */ jsxRuntime.jsx(BackButton, { onClick: () => setShowWalletPicker(false) }),
1418
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-wallet-list", children: [
1419
- /* @__PURE__ */ jsxRuntime.jsxs(
1420
- "button",
1421
- {
1422
- type: "button",
1423
- disabled: isLoading,
1424
- className: "pollar-wallet-list-btn",
1425
- onClick: onFreighterConnect,
1426
- children: [
1427
- /* @__PURE__ */ jsxRuntime.jsx("img", { src: LOGO_FREIGHTER, alt: "Freighter", className: "pollar-wallet-list-icon" }),
1428
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-wallet-list-name", children: "Freighter" })
1429
- ]
1430
- }
1431
- ),
1432
- /* @__PURE__ */ jsxRuntime.jsxs(
1433
- "button",
1434
- {
1435
- type: "button",
1436
- disabled: isLoading,
1437
- className: "pollar-wallet-list-btn",
1438
- onClick: onAlbedoConnect,
1439
- children: [
1440
- /* @__PURE__ */ jsxRuntime.jsx("img", { src: LOGO_ALBEDO, alt: "Albedo", className: "pollar-wallet-list-icon" }),
1441
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-wallet-list-name", children: "Albedo" })
1442
- ]
1443
- }
1444
- )
1445
- ] })
1696
+ renderWallets ? renderWallets({ onConnect: onWalletConnect, authState }) : /* @__PURE__ */ jsxRuntime.jsx(DefaultFreighterAlbedoButtons, { onConnect: onWalletConnect, isLoading })
1446
1697
  ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1447
1698
  emailEnabled && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-email-section", children: [
1448
1699
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1457,7 +1708,17 @@ function LoginModalTemplate({
1457
1708
  onKeyDown: (e) => e.key === "Enter" && onEmailSubmit?.()
1458
1709
  }
1459
1710
  ),
1460
- /* @__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
+ )
1461
1722
  ] }),
1462
1723
  emailEnabled && enabledSocial.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-divider", children: [
1463
1724
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-divider-line" }),
@@ -1475,7 +1736,20 @@ function LoginModalTemplate({
1475
1736
  className: "pollar-wallet-entry-btn",
1476
1737
  onClick: () => setShowWalletPicker(true),
1477
1738
  children: [
1478
- /* @__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
+ ),
1479
1753
  "Wallet"
1480
1754
  ]
1481
1755
  }
@@ -1495,14 +1769,15 @@ function LoginModalTemplate({
1495
1769
  }
1496
1770
  function LoginModal({ onClose }) {
1497
1771
  const [email, setEmail] = react.useState("");
1498
- const { getClient, styles, appConfig: config } = usePollar();
1772
+ const { getClient, styles, appConfig: config, renderWallets } = usePollar();
1499
1773
  const [authState, setAuthState] = react.useState(() => getClient().getAuthState());
1500
1774
  const [codeInputKey, setCodeInputKey] = react.useState(0);
1501
1775
  const pendingEmail = react.useRef(null);
1502
1776
  const onCloseRef = react.useRef(onClose);
1503
1777
  onCloseRef.current = onClose;
1778
+ const autoCloseTimer = react.useRef(null);
1504
1779
  react.useEffect(() => {
1505
- return getClient().onAuthStateChange((next) => {
1780
+ const unsubscribe = getClient().onAuthStateChange((next) => {
1506
1781
  setAuthState(next);
1507
1782
  if (next.step === "entering_email" && pendingEmail.current) {
1508
1783
  getClient().sendEmailCode(pendingEmail.current);
@@ -1512,9 +1787,19 @@ function LoginModal({ onClose }) {
1512
1787
  setCodeInputKey((k) => k + 1);
1513
1788
  }
1514
1789
  if (next.step === "authenticated") {
1515
- setTimeout(onCloseRef.current, 1e3);
1790
+ autoCloseTimer.current = setTimeout(() => {
1791
+ autoCloseTimer.current = null;
1792
+ onCloseRef.current();
1793
+ }, 1e3);
1516
1794
  }
1517
1795
  });
1796
+ return () => {
1797
+ unsubscribe();
1798
+ if (autoCloseTimer.current !== null) {
1799
+ clearTimeout(autoCloseTimer.current);
1800
+ autoCloseTimer.current = null;
1801
+ }
1802
+ };
1518
1803
  }, [getClient]);
1519
1804
  const { theme = "light", accentColor = "#005DB4", logoUrl, emailEnabled, embeddedWallets, providers } = styles;
1520
1805
  function handleClose() {
@@ -1566,8 +1851,8 @@ function LoginModal({ onClose }) {
1566
1851
  onEmailChange: setEmail,
1567
1852
  onEmailSubmit: handleEmailSubmit,
1568
1853
  onSocialLogin: handleSocialLogin,
1569
- onFreighterConnect: () => handleWalletConnect(core.WalletType.FREIGHTER),
1570
- onAlbedoConnect: () => handleWalletConnect(core.WalletType.ALBEDO),
1854
+ onWalletConnect: handleWalletConnect,
1855
+ ...renderWallets !== void 0 && { renderWallets },
1571
1856
  authState,
1572
1857
  codeInputKey,
1573
1858
  onCodeSubmit: handleVerifyCode,
@@ -1577,166 +1862,6 @@ function LoginModal({ onClose }) {
1577
1862
  }
1578
1863
  ) });
1579
1864
  }
1580
-
1581
- // src/lib/qr-code/index.tsx
1582
- var import_ErrorCorrectLevel = __toESM(require_ErrorCorrectLevel());
1583
- var import_QRCode = __toESM(require_QRCode());
1584
- var QRCodeSvg = react.forwardRef(function QRCodeSvg2({
1585
- bgColor,
1586
- bgD,
1587
- fgD,
1588
- fgColor,
1589
- size,
1590
- title,
1591
- viewBoxSize,
1592
- xmlns = "http://www.w3.org/2000/svg",
1593
- ...props
1594
- }, ref) {
1595
- return /* @__PURE__ */ jsxRuntime.jsxs("svg", { ...props, height: size, ref, viewBox: `0 0 ${viewBoxSize} ${viewBoxSize}`, width: size, xmlns, children: [
1596
- title ? /* @__PURE__ */ jsxRuntime.jsx("title", { children: title }) : null,
1597
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: bgD, fill: bgColor }),
1598
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: fgD, fill: fgColor })
1599
- ] });
1600
- });
1601
- QRCodeSvg.displayName = "QRCodeSvg";
1602
- function bytesToBinaryString(bytes) {
1603
- return bytes.map((b) => String.fromCharCode(b & 255)).join("");
1604
- }
1605
- function encodeStringToUtf8Bytes(input) {
1606
- return Array.from(new TextEncoder().encode(input));
1607
- }
1608
- var QRCode = react.forwardRef(function QRCode2({ bgColor = "#FFFFFF", fgColor = "#000000", level = "L", size = 256, value, ...props }, ref) {
1609
- const qrcode = new import_QRCode.default(-1, import_ErrorCorrectLevel.default[level]);
1610
- const utf8Bytes = encodeStringToUtf8Bytes(value);
1611
- const binaryString = bytesToBinaryString(utf8Bytes);
1612
- qrcode.addData(binaryString, "Byte");
1613
- qrcode.make();
1614
- const cells = qrcode.modules;
1615
- return /* @__PURE__ */ jsxRuntime.jsx(
1616
- QRCodeSvg,
1617
- {
1618
- ...props,
1619
- bgColor,
1620
- bgD: cells.map((row, rowIndex) => row.map((cell, cellIndex) => !cell ? `M ${cellIndex} ${rowIndex} l 1 0 0 1 -1 0 Z` : "").join(" ")).join(" "),
1621
- fgColor,
1622
- fgD: cells.map((row, rowIndex) => row.map((cell, cellIndex) => cell ? `M ${cellIndex} ${rowIndex} l 1 0 0 1 -1 0 Z` : "").join(" ")).join(" "),
1623
- ref,
1624
- size,
1625
- viewBoxSize: cells.length
1626
- }
1627
- );
1628
- });
1629
- function ReceiveModalTemplate({
1630
- theme,
1631
- accentColor,
1632
- walletAddress,
1633
- copied,
1634
- onCopy,
1635
- onClose
1636
- }) {
1637
- const isDark = theme === "dark";
1638
- const cssVars = {
1639
- "--pollar-accent": accentColor,
1640
- "--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
1641
- "--pollar-border": isDark ? "#374151" : "#e5e7eb",
1642
- "--pollar-text": isDark ? "#ffffff" : "#111827",
1643
- "--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
1644
- "--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
1645
- "--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
1646
- "--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
1647
- "--pollar-error-text": isDark ? "#f87171" : "#dc2626",
1648
- "--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
1649
- "--pollar-buttons-border-radius": "6px",
1650
- "--pollar-buttons-height": "44px",
1651
- "--pollar-input-height": "44px",
1652
- "--pollar-input-border-radius": "0.5rem",
1653
- "--pollar-card-border-radius": "10px"
1654
- };
1655
- return /* @__PURE__ */ jsxRuntime.jsxs(
1656
- "div",
1657
- {
1658
- className: "pollar-modal-card pollar-receive-modal",
1659
- "data-theme": theme,
1660
- style: cssVars,
1661
- onClick: (e) => e.stopPropagation(),
1662
- children: [
1663
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
1664
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Receive" }),
1665
- /* @__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" }) }) }) })
1666
- ] }),
1667
- walletAddress ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1668
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-receive-qr", children: /* @__PURE__ */ jsxRuntime.jsx(
1669
- QRCode,
1670
- {
1671
- value: walletAddress,
1672
- size: 180,
1673
- fgColor: isDark ? "#ffffff" : "#111827",
1674
- bgColor: "transparent"
1675
- }
1676
- ) }),
1677
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "pollar-receive-instructions", children: "Share your Stellar address to receive any asset. Only send Stellar assets to this address." }),
1678
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-receive-address-row", children: [
1679
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-receive-address", children: walletAddress }),
1680
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-receive-copy-btn", onClick: onCopy, "aria-label": "Copy address", children: copied ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1681
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
1682
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
1683
- /* @__PURE__ */ jsxRuntime.jsx(
1684
- "path",
1685
- {
1686
- d: "M3.5 7l2.5 2.5 4.5-5",
1687
- stroke: "white",
1688
- strokeWidth: "1.5",
1689
- strokeLinecap: "round",
1690
- strokeLinejoin: "round"
1691
- }
1692
- )
1693
- ] }),
1694
- "Copied!"
1695
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1696
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
1697
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1.5", stroke: "currentColor", strokeWidth: "1.5" }),
1698
- /* @__PURE__ */ jsxRuntime.jsx(
1699
- "path",
1700
- {
1701
- d: "M3 9H2a1 1 0 01-1-1V2a1 1 0 011-1h6a1 1 0 011 1v1",
1702
- stroke: "currentColor",
1703
- strokeWidth: "1.5",
1704
- strokeLinecap: "round"
1705
- }
1706
- )
1707
- ] }),
1708
- "Copy address"
1709
- ] }) })
1710
- ] })
1711
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No wallet connected." }),
1712
- /* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
1713
- ]
1714
- }
1715
- );
1716
- }
1717
- function ReceiveModal({ onClose }) {
1718
- const { walletAddress, styles } = usePollar();
1719
- const { theme = "light", accentColor = "#005DB4" } = styles;
1720
- const [copied, setCopied] = react.useState(false);
1721
- function handleCopy() {
1722
- if (!walletAddress) return;
1723
- navigator.clipboard.writeText(walletAddress).then(() => {
1724
- setCopied(true);
1725
- setTimeout(() => setCopied(false), 2e3);
1726
- });
1727
- }
1728
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
1729
- ReceiveModalTemplate,
1730
- {
1731
- theme,
1732
- accentColor,
1733
- walletAddress,
1734
- copied,
1735
- onCopy: handleCopy,
1736
- onClose
1737
- }
1738
- ) });
1739
- }
1740
1865
  var RAIL_LABELS = {
1741
1866
  SPEI: "SPEI (Mexico)",
1742
1867
  PIX: "PIX (Brazil)",
@@ -1844,8 +1969,26 @@ function RampWidgetTemplate({
1844
1969
  ] }),
1845
1970
  step === "input" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1846
1971
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-tabs", children: [
1847
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-ramp-tab", "data-active": direction === "onramp", onClick: () => onDirectionChange("onramp"), children: "Buy" }),
1848
- /* @__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
+ )
1849
1992
  ] }),
1850
1993
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-input-row", children: [
1851
1994
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-field", children: [
@@ -1950,17 +2093,79 @@ function RampWidgetTemplate({
1950
2093
  ] });
1951
2094
  }
1952
2095
  var MOCK_DEFAULT_QUOTES = [
1953
- { 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
+ }
1954
2107
  ];
1955
2108
  var MOCK_QUOTES = {
1956
2109
  MX: [
1957
- { quoteId: "etherfuse-mx", provider: "Etherfuse", fee: 0.5, feeCurrency: "MXN", rate: 17.2, rail: "SPEI", protocol: "SEP-24", estimatedTime: "~10 min", recommended: true },
1958
- { 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
+ }
1959
2145
  ],
1960
- BR: [{ quoteId: "abroad-br", provider: "Abroad", fee: 0.6, feeCurrency: "BRL", rate: 5.1, rail: "PIX", protocol: "REST", estimatedTime: "~5 min", recommended: true }],
1961
2146
  CO: [
1962
- { quoteId: "abroad-co", provider: "Abroad", fee: 0.7, feeCurrency: "COP", rate: 4100, rail: "PSE", protocol: "REST", estimatedTime: "~10 min", recommended: true },
1963
- { 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
+ }
1964
2169
  ],
1965
2170
  DEFAULT: MOCK_DEFAULT_QUOTES
1966
2171
  };
@@ -2051,14 +2256,193 @@ function RampWidget({ onClose }) {
2051
2256
  }
2052
2257
  ) });
2053
2258
  }
2259
+
2260
+ // src/lib/qr-code/index.tsx
2261
+ var import_ErrorCorrectLevel = __toESM(require_ErrorCorrectLevel());
2262
+ var import_QRCode = __toESM(require_QRCode());
2263
+ var QRCodeSvg = react.forwardRef(function QRCodeSvg2({ bgColor, bgD, fgD, fgColor, size, title, viewBoxSize, xmlns = "http://www.w3.org/2000/svg", ...props }, ref) {
2264
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { ...props, height: size, ref, viewBox: `0 0 ${viewBoxSize} ${viewBoxSize}`, width: size, xmlns, children: [
2265
+ title ? /* @__PURE__ */ jsxRuntime.jsx("title", { children: title }) : null,
2266
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: bgD, fill: bgColor }),
2267
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: fgD, fill: fgColor })
2268
+ ] });
2269
+ });
2270
+ QRCodeSvg.displayName = "QRCodeSvg";
2271
+ function bytesToBinaryString(bytes) {
2272
+ return bytes.map((b) => String.fromCharCode(b & 255)).join("");
2273
+ }
2274
+ function encodeStringToUtf8Bytes(input) {
2275
+ return Array.from(new TextEncoder().encode(input));
2276
+ }
2277
+ var QRCode = react.forwardRef(function QRCode2({ bgColor = "#FFFFFF", fgColor = "#000000", level = "L", size = 256, value, ...props }, ref) {
2278
+ const qrcode = new import_QRCode.default(-1, import_ErrorCorrectLevel.default[level]);
2279
+ const utf8Bytes = encodeStringToUtf8Bytes(value);
2280
+ const binaryString = bytesToBinaryString(utf8Bytes);
2281
+ qrcode.addData(binaryString, "Byte");
2282
+ qrcode.make();
2283
+ const cells = qrcode.modules;
2284
+ return /* @__PURE__ */ jsxRuntime.jsx(
2285
+ QRCodeSvg,
2286
+ {
2287
+ ...props,
2288
+ bgColor,
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(" "),
2292
+ fgColor,
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(" "),
2296
+ ref,
2297
+ size,
2298
+ viewBoxSize: cells.length
2299
+ }
2300
+ );
2301
+ });
2302
+ function ReceiveModalTemplate({
2303
+ theme,
2304
+ accentColor,
2305
+ walletAddress,
2306
+ copied,
2307
+ onCopy,
2308
+ onClose
2309
+ }) {
2310
+ const isDark = theme === "dark";
2311
+ const cssVars = {
2312
+ "--pollar-accent": accentColor,
2313
+ "--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
2314
+ "--pollar-border": isDark ? "#374151" : "#e5e7eb",
2315
+ "--pollar-text": isDark ? "#ffffff" : "#111827",
2316
+ "--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
2317
+ "--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
2318
+ "--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
2319
+ "--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
2320
+ "--pollar-error-text": isDark ? "#f87171" : "#dc2626",
2321
+ "--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
2322
+ "--pollar-buttons-border-radius": "6px",
2323
+ "--pollar-buttons-height": "44px",
2324
+ "--pollar-input-height": "44px",
2325
+ "--pollar-input-border-radius": "0.5rem",
2326
+ "--pollar-card-border-radius": "10px"
2327
+ };
2328
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2329
+ "div",
2330
+ {
2331
+ className: "pollar-modal-card pollar-receive-modal",
2332
+ "data-theme": theme,
2333
+ style: cssVars,
2334
+ onClick: (e) => e.stopPropagation(),
2335
+ children: [
2336
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
2337
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Receive" }),
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" }) }) }) })
2339
+ ] }),
2340
+ walletAddress ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2341
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-receive-qr", children: /* @__PURE__ */ jsxRuntime.jsx(QRCode, { value: walletAddress, size: 180, fgColor: isDark ? "#ffffff" : "#111827", bgColor: "transparent" }) }),
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." }),
2343
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-receive-address-row", children: [
2344
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-receive-address", children: walletAddress }),
2345
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-receive-copy-btn", onClick: onCopy, "aria-label": "Copy address", children: copied ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2346
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
2347
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
2348
+ /* @__PURE__ */ jsxRuntime.jsx(
2349
+ "path",
2350
+ {
2351
+ d: "M3.5 7l2.5 2.5 4.5-5",
2352
+ stroke: "white",
2353
+ strokeWidth: "1.5",
2354
+ strokeLinecap: "round",
2355
+ strokeLinejoin: "round"
2356
+ }
2357
+ )
2358
+ ] }),
2359
+ "Copied!"
2360
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2361
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
2362
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1.5", stroke: "currentColor", strokeWidth: "1.5" }),
2363
+ /* @__PURE__ */ jsxRuntime.jsx(
2364
+ "path",
2365
+ {
2366
+ d: "M3 9H2a1 1 0 01-1-1V2a1 1 0 011-1h6a1 1 0 011 1v1",
2367
+ stroke: "currentColor",
2368
+ strokeWidth: "1.5",
2369
+ strokeLinecap: "round"
2370
+ }
2371
+ )
2372
+ ] }),
2373
+ "Copy address"
2374
+ ] }) })
2375
+ ] })
2376
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No wallet connected." }),
2377
+ /* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
2378
+ ]
2379
+ }
2380
+ );
2381
+ }
2382
+ function ReceiveModal({ onClose }) {
2383
+ const { walletAddress, styles } = usePollar();
2384
+ const { theme = "light", accentColor = "#005DB4" } = styles;
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
+ );
2393
+ function handleCopy() {
2394
+ if (!walletAddress) return;
2395
+ navigator.clipboard.writeText(walletAddress).then(() => {
2396
+ setCopied(true);
2397
+ if (copyTimerRef.current !== null) clearTimeout(copyTimerRef.current);
2398
+ copyTimerRef.current = setTimeout(() => {
2399
+ copyTimerRef.current = null;
2400
+ setCopied(false);
2401
+ }, 2e3);
2402
+ });
2403
+ }
2404
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
2405
+ ReceiveModalTemplate,
2406
+ {
2407
+ theme,
2408
+ accentColor,
2409
+ walletAddress,
2410
+ copied,
2411
+ onCopy: handleCopy,
2412
+ onClose
2413
+ }
2414
+ ) });
2415
+ }
2054
2416
  var STATUS_MESSAGES = {
2055
2417
  idle: "",
2056
2418
  building: "Building transaction\u2026",
2057
2419
  built: "Ready to sign and send",
2058
- 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",
2059
2426
  success: "Transaction sent successfully",
2060
2427
  error: "Transaction failed"
2061
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
+ ]);
2062
2446
  function TxStatusView({
2063
2447
  transaction,
2064
2448
  showXdr,
@@ -2075,10 +2459,10 @@ function TxStatusView({
2075
2459
  const hash = transaction.step === "success" ? transaction.hash : null;
2076
2460
  const errorDetails = transaction.step === "error" ? transaction.details ?? null : null;
2077
2461
  const isBuilt = transaction.step === "built";
2078
- const isSigning = transaction.step === "signing";
2462
+ const isInFlight = IN_FLIGHT_STEPS.has(transaction.step);
2079
2463
  const isSuccess = transaction.step === "success";
2080
2464
  const isError = transaction.step === "error";
2081
- const showDetails = buildData !== null && (isBuilt || isSigning || isSuccess);
2465
+ const showDetails = buildData !== null && SHOW_DETAILS_STEPS.has(transaction.step);
2082
2466
  const walletImg = walletType === core.WalletType.FREIGHTER ? LOGO_FREIGHTER : walletType === core.WalletType.ALBEDO ? LOGO_ALBEDO : LOGO_POLLAR;
2083
2467
  const walletAlt = walletType === core.WalletType.FREIGHTER ? "Freighter" : walletType === core.WalletType.ALBEDO ? "Albedo" : "Pollar";
2084
2468
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -2121,7 +2505,7 @@ function TxStatusView({
2121
2505
  /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "pollar-tx-error-details-content", children: errorDetails })
2122
2506
  ] }),
2123
2507
  isBuilt && /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-btn-primary pollar-tx-sign-btn", onClick: onSignAndSend, children: "Sign & Send" }),
2124
- (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: [
2125
2509
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-spinner-ring", children: [
2126
2510
  /* @__PURE__ */ jsxRuntime.jsxs(
2127
2511
  "svg",
@@ -2129,7 +2513,7 @@ function TxStatusView({
2129
2513
  viewBox: "0 0 88 88",
2130
2514
  width: "88",
2131
2515
  height: "88",
2132
- className: `pollar-tx-spinner-svg${isSigning ? " pollar-tx-spinner-rotating" : ""}`,
2516
+ className: `pollar-tx-spinner-svg${isInFlight ? " pollar-tx-spinner-rotating" : ""}`,
2133
2517
  "aria-hidden": true,
2134
2518
  children: [
2135
2519
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "44", cy: "44", r: "36", fill: "none", stroke: "var(--pollar-border)", strokeWidth: "3" }),
@@ -2143,9 +2527,9 @@ function TxStatusView({
2143
2527
  stroke: isSuccess ? "var(--pollar-success-text)" : isError ? "var(--pollar-error-text)" : "var(--pollar-accent)",
2144
2528
  strokeWidth: "3",
2145
2529
  strokeLinecap: "round",
2146
- strokeDasharray: isSigning ? "169.6 56.6" : "999 0",
2530
+ strokeDasharray: isInFlight ? "169.6 56.6" : "999 0",
2147
2531
  transform: "rotate(-90 44 44)",
2148
- style: { transition: isSigning ? "none" : "stroke 400ms, stroke-dasharray 400ms" }
2532
+ style: { transition: isInFlight ? "none" : "stroke 400ms, stroke-dasharray 400ms" }
2149
2533
  }
2150
2534
  )
2151
2535
  ]
@@ -2153,7 +2537,7 @@ function TxStatusView({
2153
2537
  ),
2154
2538
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-tx-wallet-icon", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: walletImg, alt: walletAlt, className: "pollar-tx-wallet-img" }) })
2155
2539
  ] }),
2156
- 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" }),
2157
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" })
2158
2542
  ] }),
2159
2543
  isSuccess && hash && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-result", children: [
@@ -2221,7 +2605,7 @@ function TxStatusView({
2221
2605
  ModalStatusBanner,
2222
2606
  {
2223
2607
  message: STATUS_MESSAGES[transaction.step],
2224
- status: isError ? "ERROR" : isSigning || transaction.step === "building" ? "LOADING" : isSuccess ? "SUCCESS" : "NONE"
2608
+ status: isError ? "ERROR" : isInFlight ? "LOADING" : isSuccess ? "SUCCESS" : "NONE"
2225
2609
  }
2226
2610
  )
2227
2611
  ] });
@@ -2398,7 +2782,16 @@ function assetParam(record) {
2398
2782
  return { type: "credit_alphanum12", code: record.code, issuer: record.issuer };
2399
2783
  }
2400
2784
  function SendModal({ onClose }) {
2401
- 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();
2402
2795
  const { theme = "light", accentColor = "#005DB4" } = styles;
2403
2796
  const [step, setStep] = react.useState("form");
2404
2797
  const [amount, setAmount] = react.useState("");
@@ -2407,9 +2800,16 @@ function SendModal({ onClose }) {
2407
2800
  const [showXdr, setShowXdr] = react.useState(false);
2408
2801
  const [copied, setCopied] = react.useState(false);
2409
2802
  const [formError, setFormError] = react.useState("");
2803
+ const copyTimerRef = react.useRef(null);
2410
2804
  react.useEffect(() => {
2411
2805
  void refreshWalletBalance();
2412
2806
  }, [refreshWalletBalance]);
2807
+ react.useEffect(
2808
+ () => () => {
2809
+ if (copyTimerRef.current !== null) clearTimeout(copyTimerRef.current);
2810
+ },
2811
+ []
2812
+ );
2413
2813
  const balanceData = walletBalance.step === "loaded" ? walletBalance.data : null;
2414
2814
  const allAssets = balanceData?.balances ?? [];
2415
2815
  const sortedAssets = [
@@ -2420,9 +2820,17 @@ function SendModal({ onClose }) {
2420
2820
  const buildData = "buildData" in transaction ? transaction.buildData : null;
2421
2821
  const explorerNetwork = buildData?.summary.network?.toLowerCase().includes("testnet") ? "testnet" : buildData ? "public" : network === "testnet" ? "testnet" : "public";
2422
2822
  const explorerUrl = hash ? `https://stellar.expert/explorer/${explorerNetwork}/tx/${hash}` : null;
2423
- 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);
2424
2832
  const showBack = step === "tx" && (transaction.step === "error" || transaction.step === "success") && !isInProgress;
2425
- 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";
2426
2834
  async function handleSubmit() {
2427
2835
  setFormError("");
2428
2836
  if (!selectedAsset) {
@@ -2454,7 +2862,11 @@ function SendModal({ onClose }) {
2454
2862
  if (!hash) return;
2455
2863
  navigator.clipboard.writeText(hash).then(() => {
2456
2864
  setCopied(true);
2457
- 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);
2458
2870
  });
2459
2871
  }
2460
2872
  async function handleRetry() {
@@ -2604,16 +3016,7 @@ function SessionsModalTemplate({
2604
3016
  "aria-hidden": true,
2605
3017
  children: [
2606
3018
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M11.5 6.5a5 5 0 11-1.5-3.536", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }),
2607
- /* @__PURE__ */ jsxRuntime.jsx(
2608
- "path",
2609
- {
2610
- d: "M10 1v3h-3",
2611
- stroke: "currentColor",
2612
- strokeWidth: "1.5",
2613
- strokeLinecap: "round",
2614
- strokeLinejoin: "round"
2615
- }
2616
- )
3019
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 1v3h-3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
2617
3020
  ]
2618
3021
  }
2619
3022
  ),
@@ -2681,9 +3084,12 @@ function SessionsModal({ onClose }) {
2681
3084
  const [revokingFamilyId, setRevokingFamilyId] = react.useState(null);
2682
3085
  const [signingOutEverywhere, setSigningOutEverywhere] = react.useState(false);
2683
3086
  const mountedRef = react.useRef(true);
2684
- react.useEffect(() => () => {
2685
- mountedRef.current = false;
2686
- }, []);
3087
+ react.useEffect(
3088
+ () => () => {
3089
+ mountedRef.current = false;
3090
+ },
3091
+ []
3092
+ );
2687
3093
  const onCloseRef = react.useRef(onClose);
2688
3094
  onCloseRef.current = onClose;
2689
3095
  react.useEffect(() => {
@@ -2715,9 +3121,7 @@ function SessionsModal({ onClose }) {
2715
3121
  await load();
2716
3122
  } catch {
2717
3123
  if (!mountedRef.current) return;
2718
- setState(
2719
- (prev) => prev.step === "loaded" ? { step: "error", message: "Failed to revoke session" } : prev
2720
- );
3124
+ setState((prev) => prev.step === "loaded" ? { step: "error", message: "Failed to revoke session" } : prev);
2721
3125
  } finally {
2722
3126
  if (mountedRef.current) setRevokingFamilyId(null);
2723
3127
  }
@@ -2781,55 +3185,53 @@ function TransactionModalTemplate({
2781
3185
  "--pollar-input-border-radius": "0.5rem",
2782
3186
  "--pollar-card-border-radius": "10px"
2783
3187
  };
2784
- return /* @__PURE__ */ jsxRuntime.jsxs(
2785
- "div",
2786
- {
2787
- className: "pollar-modal-card pollar-tx-modal",
2788
- "data-theme": theme,
2789
- style: cssVars,
2790
- onClick: (e) => e.stopPropagation(),
2791
- children: [
2792
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-header", children: /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Transaction" }) }),
2793
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-close-btn", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsx(
2794
- "svg",
2795
- {
2796
- width: "18",
2797
- height: "18",
2798
- viewBox: "0 0 24 24",
2799
- fill: "none",
2800
- stroke: "currentColor",
2801
- strokeWidth: "2.5",
2802
- strokeLinecap: "round",
2803
- strokeLinejoin: "round",
2804
- "aria-hidden": true,
2805
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6L6 18M6 6l12 12" })
2806
- }
2807
- ) }),
2808
- /* @__PURE__ */ jsxRuntime.jsx(
2809
- TxStatusView,
2810
- {
2811
- transaction,
2812
- showXdr,
2813
- copied,
2814
- explorerUrl,
2815
- walletType,
2816
- onSignAndSend,
2817
- onToggleXdr,
2818
- onCopyHash,
2819
- onRetry,
2820
- onDone: onClose
2821
- }
2822
- ),
2823
- /* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
2824
- ]
2825
- }
2826
- );
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
+ ] });
2827
3222
  }
2828
3223
  function TransactionModal({ onClose }) {
2829
3224
  const { getClient, styles, tx: transaction, network, walletType } = usePollar();
2830
3225
  const { theme = "light", accentColor = "#005DB4" } = styles;
2831
3226
  const [showXdr, setShowXdr] = react.useState(false);
2832
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
+ );
2833
3235
  const hash = transaction.step === "success" ? transaction.hash : null;
2834
3236
  const buildData = "buildData" in transaction ? transaction.buildData : null;
2835
3237
  const explorerNetwork = buildData?.summary.network?.toLowerCase().includes("testnet") ? "testnet" : buildData ? "public" : network === "testnet" ? "testnet" : "public";
@@ -2843,7 +3245,11 @@ function TransactionModal({ onClose }) {
2843
3245
  if (!hash) return;
2844
3246
  navigator.clipboard.writeText(hash).then(() => {
2845
3247
  setCopied(true);
2846
- 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);
2847
3253
  });
2848
3254
  }
2849
3255
  async function handleRetry() {
@@ -2910,97 +3316,128 @@ function TxHistoryModalTemplate({
2910
3316
  const hasPrev = offset > 0;
2911
3317
  const hasNext = offset + PAGE_SIZE < total;
2912
3318
  const showPagination = txHistory.step === "loaded" && total > PAGE_SIZE;
2913
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-card pollar-hist-modal", "data-theme": theme, style: cssVars, onClick: (e) => e.stopPropagation(), children: [
2914
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
2915
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Transaction History" }),
2916
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
2917
- /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-modal-refresh-btn", onClick: onRefresh, disabled: isLoading, children: [
2918
- /* @__PURE__ */ jsxRuntime.jsxs(
2919
- "svg",
2920
- {
2921
- className: `pollar-modal-refresh-icon${isLoading ? " spinning" : ""}`,
2922
- width: "13",
2923
- height: "13",
2924
- viewBox: "0 0 13 13",
2925
- fill: "none",
2926
- "aria-hidden": true,
2927
- children: [
2928
- /* @__PURE__ */ jsxRuntime.jsx(
2929
- "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",
2930
3375
  {
2931
- d: "M11.5 6.5a5 5 0 11-1.5-3.536",
2932
- stroke: "currentColor",
2933
- strokeWidth: "1.5",
2934
- 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
+ ]
2935
3405
  }
2936
- ),
2937
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 1v3h-3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
2938
- ]
2939
- }
2940
- ),
2941
- "Refresh"
3406
+ )
3407
+ ] })
3408
+ ] }, record.id);
3409
+ })
2942
3410
  ] }),
2943
- /* @__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" }) }) })
2944
- ] })
2945
- ] }),
2946
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-list", children: [
2947
- txHistory.step === "idle" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "Click Refresh to load transactions." }),
2948
- isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "Loading\u2026" }),
2949
- txHistory.step === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: txHistory.message }),
2950
- txHistory.step === "loaded" && records.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No transactions yet." }),
2951
- records.map((record) => {
2952
- const explorerUrl = `https://stellar.expert/explorer/${record.network === "testnet" ? "testnet" : "public"}/tx/${record.hash}`;
2953
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-item", children: [
2954
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-hist-item-summary", children: record.summary }),
2955
- /* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: record.status }),
2956
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-hist-item-meta", children: [
2957
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: record.operation }),
2958
- record.feeXlm && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
2959
- "\xB7 ",
2960
- record.feeXlm,
2961
- " XLM"
2962
- ] }),
2963
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
2964
- "\xB7 ",
2965
- formatDate(record.createdAt)
2966
- ] }),
2967
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\xB7" }),
2968
- /* @__PURE__ */ jsxRuntime.jsxs("a", { className: "pollar-hist-item-explorer", href: explorerUrl, target: "_blank", rel: "noopener noreferrer", "aria-label": "View on Stellar Explorer", children: [
2969
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "11", height: "11", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
2970
- /* @__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" }),
2971
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 1h4m0 0v4m0-4L6 7", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
2972
- ] }),
2973
- "Explorer"
2974
- ] })
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" })
2975
3422
  ] })
2976
- ] }, record.id);
2977
- })
2978
- ] }),
2979
- showPagination && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-pagination", children: [
2980
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-hist-pagination-info", children: [
2981
- offset + 1,
2982
- "\u2013",
2983
- Math.min(offset + PAGE_SIZE, total),
2984
- " of ",
2985
- total
2986
- ] }),
2987
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-pagination-btns", children: [
2988
- /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-hist-page-btn", onClick: onPrev, disabled: !hasPrev, children: "\u2190 Prev" }),
2989
- /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-hist-page-btn", onClick: onNext, disabled: !hasNext, children: "Next \u2192" })
2990
- ] })
2991
- ] }),
2992
- /* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
2993
- ] });
3423
+ ] }),
3424
+ /* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
3425
+ ]
3426
+ }
3427
+ );
2994
3428
  }
2995
3429
  var PAGE_SIZE2 = 10;
2996
3430
  function TxHistoryModal({ onClose }) {
2997
3431
  const { getClient, styles, txHistory } = usePollar();
2998
3432
  const { theme = "light", accentColor = "#005DB4" } = styles;
2999
3433
  const [offset, setOffset] = react.useState(0);
3000
- const load = react.useCallback((nextOffset) => {
3001
- setOffset(nextOffset);
3002
- void getClient().fetchTxHistory({ limit: PAGE_SIZE2, offset: nextOffset });
3003
- }, [getClient]);
3434
+ const load = react.useCallback(
3435
+ (nextOffset) => {
3436
+ setOffset(nextOffset);
3437
+ void getClient().fetchTxHistory({ limit: PAGE_SIZE2, offset: nextOffset });
3438
+ },
3439
+ [getClient]
3440
+ );
3004
3441
  react.useEffect(() => {
3005
3442
  load(0);
3006
3443
  }, [load]);
@@ -3123,28 +3560,31 @@ function WalletBalanceModal({ onClose }) {
3123
3560
  }
3124
3561
  ) });
3125
3562
  }
3126
- var emptyResponse = {
3127
- application: {
3128
- name: ""
3129
- },
3563
+ var DEFAULT_APP_CONFIG = {
3564
+ application: { name: "" },
3130
3565
  styles: {}
3131
3566
  };
3132
- async function fetchRemoteConfig(client) {
3133
- const content = await client.getAppConfig();
3134
- 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;
3135
3571
  }
3136
3572
  var PollarContext = react.createContext(null);
3137
- function PollarProvider({ config, styles: propStyles, adapters, children }) {
3138
- 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));
3139
3582
  const [networkState, setNetworkState] = react.useState(() => pollarClient.getNetworkState());
3140
3583
  const [sessionState, setSessionState] = react.useState(null);
3141
3584
  const [transaction, setTransaction] = react.useState({ step: "idle" });
3142
3585
  const [txHistory, setTxHistory] = react.useState({ step: "idle" });
3143
3586
  const [walletBalance, setWalletBalance] = react.useState({ step: "idle" });
3144
- const [remoteConfig, setRemoteConfig] = react.useState(emptyResponse);
3145
- const [styles, setStyles] = react.useState(propStyles ?? {});
3146
- const propStylesRef = react.useRef(propStyles);
3147
- propStylesRef.current = propStyles;
3587
+ const [resolvedConfig, setResolvedConfig] = react.useState(() => appConfigProp ?? DEFAULT_APP_CONFIG);
3148
3588
  react.useEffect(() => {
3149
3589
  return pollarClient.onTransactionStateChange(setTransaction);
3150
3590
  }, [pollarClient]);
@@ -3159,28 +3599,32 @@ function PollarProvider({ config, styles: propStyles, adapters, children }) {
3159
3599
  setNetworkState(state);
3160
3600
  });
3161
3601
  }, [pollarClient]);
3602
+ react.useEffect(() => {
3603
+ if (!onStorageDegrade) return;
3604
+ return pollarClient.onStorageDegrade(onStorageDegrade);
3605
+ }, [pollarClient, onStorageDegrade]);
3162
3606
  react.useEffect(() => {
3163
3607
  return pollarClient.onAuthStateChange((authState) => {
3164
3608
  if (authState.step === "authenticated") {
3165
- setSessionState((prev) => JSON.stringify(prev) !== JSON.stringify(authState.session) ? authState.session : prev);
3609
+ setSessionState((prev) => sessionsEqual(prev, authState.session) ? prev : authState.session);
3166
3610
  } else if (authState.step === "idle") {
3167
3611
  setSessionState(null);
3168
3612
  }
3169
3613
  });
3170
3614
  }, [pollarClient]);
3171
3615
  react.useEffect(() => {
3172
- const propStyles2 = propStylesRef.current;
3173
- fetchRemoteConfig(pollarClient).then((fetched) => {
3174
- setRemoteConfig(fetched);
3175
- setStyles({
3176
- ...fetched.styles,
3177
- ...propStyles2,
3178
- providers: { ...fetched.styles?.providers, ...propStyles2?.providers }
3179
- });
3180
- }).catch(() => {
3181
- 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);
3182
3623
  });
3183
- }, [pollarClient]);
3624
+ return () => {
3625
+ cancelled = true;
3626
+ };
3627
+ }, [pollarClient, appConfigProp]);
3184
3628
  const [loginModalOpen, setLoginModalOpen] = react.useState(false);
3185
3629
  const [transactionModalOpen, setTransactionModalOpen] = react.useState(false);
3186
3630
  const [kycModalOpen, setKycModalOpen] = react.useState(false);
@@ -3191,13 +3635,14 @@ function PollarProvider({ config, styles: propStyles, adapters, children }) {
3191
3635
  const [sendModalOpen, setSendModalOpen] = react.useState(false);
3192
3636
  const [receiveModalOpen, setReceiveModalOpen] = react.useState(false);
3193
3637
  const [sessionsModalOpen, setSessionsModalOpen] = react.useState(false);
3194
- const adaptersRef = react.useRef(adapters);
3195
- adaptersRef.current = adapters;
3638
+ const [distributionRulesModalOpen, setDistributionRulesModalOpen] = react.useState(false);
3196
3639
  const walletAddress = sessionState?.wallet?.publicKey || "";
3197
3640
  const getClient = react.useCallback(() => pollarClient, [pollarClient]);
3198
3641
  const refreshWalletBalance = react.useCallback(() => pollarClient.refreshBalance(walletAddress), [pollarClient, walletAddress]);
3199
- const contextValue = react.useMemo(
3200
- () => ({
3642
+ const renderWallets = ui?.renderWallets;
3643
+ const contextValue = react.useMemo(() => {
3644
+ const styles = resolvedConfig.styles ?? {};
3645
+ return {
3201
3646
  // session
3202
3647
  walletAddress,
3203
3648
  isAuthenticated: !!walletAddress,
@@ -3212,6 +3657,10 @@ function PollarProvider({ config, styles: propStyles, adapters, children }) {
3212
3657
  tx: transaction,
3213
3658
  buildTx: (operation, params, options) => pollarClient.buildTx(operation, params, options),
3214
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),
3215
3664
  openTxModal: () => setTransactionModalOpen(true),
3216
3665
  // tx history
3217
3666
  txHistory,
@@ -3225,6 +3674,8 @@ function PollarProvider({ config, styles: propStyles, adapters, children }) {
3225
3674
  openReceiveModal: () => setReceiveModalOpen(true),
3226
3675
  // sessions
3227
3676
  openSessionsModal: () => setSessionsModalOpen(true),
3677
+ // distribution
3678
+ openDistributionRulesModal: () => setDistributionRulesModalOpen(true),
3228
3679
  // network
3229
3680
  network: networkState.step === "connected" ? networkState.network : "testnet",
3230
3681
  setNetwork: (network) => pollarClient.setNetwork(network),
@@ -3236,12 +3687,24 @@ function PollarProvider({ config, styles: propStyles, adapters, children }) {
3236
3687
  // ramp
3237
3688
  openRampModal: () => setRampModalOpen(true),
3238
3689
  // config
3239
- appConfig: remoteConfig,
3690
+ appConfig: resolvedConfig,
3240
3691
  styles,
3241
- adapters: adaptersRef.current
3242
- }),
3243
- [walletAddress, pollarClient, getClient, transaction, txHistory, walletBalance, refreshWalletBalance, networkState, remoteConfig, styles]
3244
- );
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
+ ]);
3245
3708
  return /* @__PURE__ */ jsxRuntime.jsxs(PollarContext.Provider, { value: contextValue, children: [
3246
3709
  children,
3247
3710
  loginModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setLoginModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(LoginModal, { onClose: () => setLoginModalOpen(false) }) }),
@@ -3260,7 +3723,8 @@ function PollarProvider({ config, styles: propStyles, adapters, children }) {
3260
3723
  walletBalanceModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setWalletBalanceModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(WalletBalanceModal, { onClose: () => setWalletBalanceModalOpen(false) }) }),
3261
3724
  sendModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setSendModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(SendModal, { onClose: () => setSendModalOpen(false) }) }),
3262
3725
  receiveModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setReceiveModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(ReceiveModal, { onClose: () => setReceiveModalOpen(false) }) }),
3263
- sessionsModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setSessionsModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(SessionsModal, { onClose: () => setSessionsModalOpen(false) }) })
3726
+ sessionsModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setSessionsModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(SessionsModal, { onClose: () => setSessionsModalOpen(false) }) }),
3727
+ distributionRulesModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setDistributionRulesModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(DistributionRulesModal, { onClose: () => setDistributionRulesModalOpen(false) }) })
3264
3728
  ] });
3265
3729
  }
3266
3730
  function usePollar() {
@@ -3284,7 +3748,7 @@ function createPollarAdapterHook(key) {
3284
3748
  name,
3285
3749
  async (params) => {
3286
3750
  const { unsignedTransaction } = await fn(params);
3287
- await signAndSubmitTx(unsignedTransaction);
3751
+ return signAndSubmitTx(unsignedTransaction);
3288
3752
  }
3289
3753
  ])
3290
3754
  );
@@ -3333,33 +3797,22 @@ function WalletButtonTemplate({
3333
3797
  "aria-busy": isInProgress,
3334
3798
  children: [
3335
3799
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "wallet-btn-label", children: cropWallet(walletAddress) }),
3336
- isInProgress ? /* @__PURE__ */ jsxRuntime.jsxs(
3337
- "svg",
3338
- {
3339
- className: "wallet-btn-spinner",
3340
- viewBox: "0 0 12 12",
3341
- width: "12",
3342
- height: "12",
3343
- fill: "none",
3344
- "aria-hidden": true,
3345
- children: [
3346
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "6", cy: "6", r: "4.5", stroke: "rgba(255,255,255,0.35)", strokeWidth: "1.5" }),
3347
- /* @__PURE__ */ jsxRuntime.jsx(
3348
- "circle",
3349
- {
3350
- cx: "6",
3351
- cy: "6",
3352
- r: "4.5",
3353
- stroke: "white",
3354
- strokeWidth: "1.5",
3355
- strokeLinecap: "round",
3356
- strokeDasharray: "14 9",
3357
- transform: "rotate(-90 6 6)"
3358
- }
3359
- )
3360
- ]
3361
- }
3362
- ) : /* @__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(
3363
3816
  "svg",
3364
3817
  {
3365
3818
  className: `wallet-chevron${open ? " open" : ""}`,
@@ -3377,53 +3830,131 @@ function WalletButtonTemplate({
3377
3830
  ),
3378
3831
  open && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "wallet-dropdown", style: { backgroundColor: dropdownBg, borderColor: dropdownBorder }, children: [
3379
3832
  /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "wallet-dropdown-item", style: { color: itemColor }, onClick: onSend, children: [
3380
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
3381
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "22", y1: "2", x2: "11", y2: "13" }),
3382
- /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
3383
- ] }),
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
+ ),
3384
3850
  "Send"
3385
3851
  ] }),
3386
3852
  /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "wallet-dropdown-item", style: { color: itemColor }, onClick: onReceive, children: [
3387
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
3388
- /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "8 17 12 21 16 17" }),
3389
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "12", x2: "12", y2: "21" }),
3390
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20.88 18.09A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.29" })
3391
- ] }),
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
+ ),
3392
3871
  "Receive"
3393
3872
  ] }),
3394
3873
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "wallet-dropdown-divider" }),
3395
3874
  /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "wallet-dropdown-item", style: { color: itemColor }, onClick: onCopy, children: [
3396
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
3397
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
3398
- /* @__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" })
3399
- ] }),
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
+ ),
3400
3892
  copied ? "Copied!" : "Copy address"
3401
3893
  ] }),
3402
3894
  /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "wallet-dropdown-item", style: { color: itemColor }, onClick: onWalletBalance, children: [
3403
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
3404
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "1", y: "4", width: "22", height: "16", rx: "2", ry: "2" }),
3405
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "16", cy: "12", r: "2" }),
3406
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M22 8H12" })
3407
- ] }),
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
+ ),
3408
3913
  "Wallet balance"
3409
3914
  ] }),
3410
3915
  /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "wallet-dropdown-item", style: { color: itemColor }, onClick: onTxHistory, children: [
3411
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
3412
- /* @__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" }),
3413
- /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "14,2 14,8 20,8" }),
3414
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "16", y1: "13", x2: "8", y2: "13" }),
3415
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "16", y1: "17", x2: "8", y2: "17" }),
3416
- /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "10,9 9,9 8,9" })
3417
- ] }),
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
+ ),
3418
3936
  "Transaction history"
3419
3937
  ] }),
3420
3938
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "wallet-dropdown-divider" }),
3421
3939
  /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "wallet-dropdown-item danger", onClick: onLogout, children: [
3422
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
3423
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" }),
3424
- /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "16,17 21,12 16,7" }),
3425
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "21", y1: "12", x2: "9", y2: "12" })
3426
- ] }),
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
+ ),
3427
3958
  "Log out"
3428
3959
  ] })
3429
3960
  ] })
@@ -3445,6 +3976,7 @@ function WalletButton() {
3445
3976
  const [open, setOpen] = react.useState(false);
3446
3977
  const [copied, setCopied] = react.useState(false);
3447
3978
  const wrapperRef = react.useRef(null);
3979
+ const copyTimerRef = react.useRef(null);
3448
3980
  const isInProgress = transaction.step === "building" || transaction.step === "signing";
3449
3981
  const { theme = "light", accentColor = "#005DB4" } = styles;
3450
3982
  const isDark = theme === "dark";
@@ -3460,11 +3992,21 @@ function WalletButton() {
3460
3992
  document.addEventListener("mousedown", handleClickOutside);
3461
3993
  return () => document.removeEventListener("mousedown", handleClickOutside);
3462
3994
  }, []);
3995
+ react.useEffect(
3996
+ () => () => {
3997
+ if (copyTimerRef.current !== null) clearTimeout(copyTimerRef.current);
3998
+ },
3999
+ []
4000
+ );
3463
4001
  async function handleCopy() {
3464
4002
  if (!walletAddress) return;
3465
4003
  await navigator.clipboard.writeText(walletAddress);
3466
4004
  setCopied(true);
3467
- 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);
3468
4010
  }
3469
4011
  function handleLogout() {
3470
4012
  setOpen(false);
@@ -3511,6 +4053,8 @@ function WalletButton() {
3511
4053
  );
3512
4054
  }
3513
4055
 
4056
+ exports.DistributionRulesModal = DistributionRulesModal;
4057
+ exports.DistributionRulesModalTemplate = DistributionRulesModalTemplate;
3514
4058
  exports.KycModal = KycModal;
3515
4059
  exports.KycModalTemplate = KycModalTemplate;
3516
4060
  exports.KycStatus = KycStatus;