@pollar/react 0.6.0 → 0.7.1
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/README.md +202 -20
- package/dist/index.css +257 -59
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +58 -8
- package/dist/index.d.ts +58 -8
- package/dist/index.js +650 -164
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +648 -166
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -1
package/dist/index.js
CHANGED
|
@@ -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.
|
|
1033
|
+
"0.7.1"
|
|
1034
1034
|
] })
|
|
1035
1035
|
] })
|
|
1036
1036
|
] });
|
|
@@ -1054,6 +1054,221 @@ 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(
|
|
1116
|
+
"button",
|
|
1117
|
+
{
|
|
1118
|
+
type: "button",
|
|
1119
|
+
className: "pollar-btn-primary pollar-dist-claim-btn",
|
|
1120
|
+
onClick: onClaim,
|
|
1121
|
+
disabled: isClaiming,
|
|
1122
|
+
children: isClaiming ? "Claiming\u2026" : "Claim"
|
|
1123
|
+
}
|
|
1124
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-dist-item-status", "data-kind": "unavailable", children: reasonLabel(rule.reason) }) }),
|
|
1125
|
+
errorMessage && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-dist-item-error", children: errorMessage })
|
|
1126
|
+
] });
|
|
1127
|
+
}
|
|
1128
|
+
function DistributionRulesModalTemplate({
|
|
1129
|
+
theme,
|
|
1130
|
+
accentColor,
|
|
1131
|
+
state,
|
|
1132
|
+
claimingId,
|
|
1133
|
+
claimErrors,
|
|
1134
|
+
claimedIds,
|
|
1135
|
+
onRefresh,
|
|
1136
|
+
onClaim,
|
|
1137
|
+
onClose
|
|
1138
|
+
}) {
|
|
1139
|
+
const isDark = theme === "dark";
|
|
1140
|
+
const cssVars = {
|
|
1141
|
+
"--pollar-accent": accentColor,
|
|
1142
|
+
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
1143
|
+
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
1144
|
+
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
1145
|
+
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
1146
|
+
"--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
|
|
1147
|
+
"--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
|
|
1148
|
+
"--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
|
|
1149
|
+
"--pollar-error-text": isDark ? "#f87171" : "#dc2626",
|
|
1150
|
+
"--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
|
|
1151
|
+
"--pollar-buttons-border-radius": "6px",
|
|
1152
|
+
"--pollar-buttons-height": "44px",
|
|
1153
|
+
"--pollar-input-height": "44px",
|
|
1154
|
+
"--pollar-input-border-radius": "0.5rem",
|
|
1155
|
+
"--pollar-card-border-radius": "10px"
|
|
1156
|
+
};
|
|
1157
|
+
const isLoading = state.step === "loading";
|
|
1158
|
+
const rules = state.step === "loaded" ? state.rules : [];
|
|
1159
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1160
|
+
"div",
|
|
1161
|
+
{
|
|
1162
|
+
className: "pollar-modal-card pollar-dist-modal",
|
|
1163
|
+
"data-theme": theme,
|
|
1164
|
+
style: cssVars,
|
|
1165
|
+
onClick: (e) => e.stopPropagation(),
|
|
1166
|
+
children: [
|
|
1167
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
|
|
1168
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Distribution Rules" }),
|
|
1169
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
|
|
1170
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-modal-refresh-btn", onClick: onRefresh, disabled: isLoading, children: [
|
|
1171
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1172
|
+
"svg",
|
|
1173
|
+
{
|
|
1174
|
+
className: `pollar-modal-refresh-icon${isLoading ? " spinning" : ""}`,
|
|
1175
|
+
width: "13",
|
|
1176
|
+
height: "13",
|
|
1177
|
+
viewBox: "0 0 13 13",
|
|
1178
|
+
fill: "none",
|
|
1179
|
+
"aria-hidden": true,
|
|
1180
|
+
children: [
|
|
1181
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M11.5 6.5a5 5 0 11-1.5-3.536", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }),
|
|
1182
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 1v3h-3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
1183
|
+
]
|
|
1184
|
+
}
|
|
1185
|
+
),
|
|
1186
|
+
"Refresh"
|
|
1187
|
+
] }),
|
|
1188
|
+
/* @__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" }) }) })
|
|
1189
|
+
] })
|
|
1190
|
+
] }),
|
|
1191
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-dist-list", children: [
|
|
1192
|
+
isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "Loading\u2026" }),
|
|
1193
|
+
state.step === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: state.message }),
|
|
1194
|
+
state.step === "loaded" && rules.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No distribution rules available." }),
|
|
1195
|
+
rules.map((rule) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1196
|
+
RuleCard,
|
|
1197
|
+
{
|
|
1198
|
+
rule,
|
|
1199
|
+
isClaiming: claimingId === rule.id,
|
|
1200
|
+
isClaimed: claimedIds.has(rule.id),
|
|
1201
|
+
...claimErrors[rule.id] && { errorMessage: claimErrors[rule.id] },
|
|
1202
|
+
onClaim: () => onClaim(rule)
|
|
1203
|
+
},
|
|
1204
|
+
rule.id
|
|
1205
|
+
))
|
|
1206
|
+
] }),
|
|
1207
|
+
/* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
|
|
1208
|
+
]
|
|
1209
|
+
}
|
|
1210
|
+
);
|
|
1211
|
+
}
|
|
1212
|
+
function DistributionRulesModal({ onClose }) {
|
|
1213
|
+
const { getClient, styles } = usePollar();
|
|
1214
|
+
const { theme = "light", accentColor = "#005DB4" } = styles;
|
|
1215
|
+
const [state, setState] = react.useState({ step: "idle" });
|
|
1216
|
+
const [claimingId, setClaimingId] = react.useState(null);
|
|
1217
|
+
const [claimErrors, setClaimErrors] = react.useState({});
|
|
1218
|
+
const [claimedIds, setClaimedIds] = react.useState(() => /* @__PURE__ */ new Set());
|
|
1219
|
+
const load = react.useCallback(async () => {
|
|
1220
|
+
setState({ step: "loading" });
|
|
1221
|
+
try {
|
|
1222
|
+
const rules = await getClient().listDistributionRules();
|
|
1223
|
+
setState({ step: "loaded", rules });
|
|
1224
|
+
} catch (err) {
|
|
1225
|
+
const message = err instanceof Error ? err.message : "Failed to load distribution rules";
|
|
1226
|
+
setState({ step: "error", message });
|
|
1227
|
+
}
|
|
1228
|
+
}, [getClient]);
|
|
1229
|
+
react.useEffect(() => {
|
|
1230
|
+
void load();
|
|
1231
|
+
}, [load]);
|
|
1232
|
+
const handleClaim = react.useCallback(
|
|
1233
|
+
async (rule) => {
|
|
1234
|
+
setClaimingId(rule.id);
|
|
1235
|
+
setClaimErrors((prev) => {
|
|
1236
|
+
if (!prev[rule.id]) return prev;
|
|
1237
|
+
const next = { ...prev };
|
|
1238
|
+
delete next[rule.id];
|
|
1239
|
+
return next;
|
|
1240
|
+
});
|
|
1241
|
+
try {
|
|
1242
|
+
await getClient().claimDistributionRule({ ruleId: rule.id });
|
|
1243
|
+
setClaimedIds((prev) => {
|
|
1244
|
+
const next = new Set(prev);
|
|
1245
|
+
next.add(rule.id);
|
|
1246
|
+
return next;
|
|
1247
|
+
});
|
|
1248
|
+
} catch (err) {
|
|
1249
|
+
const message = err instanceof Error ? err.message : "Claim failed";
|
|
1250
|
+
setClaimErrors((prev) => ({ ...prev, [rule.id]: message }));
|
|
1251
|
+
} finally {
|
|
1252
|
+
setClaimingId(null);
|
|
1253
|
+
}
|
|
1254
|
+
},
|
|
1255
|
+
[getClient]
|
|
1256
|
+
);
|
|
1257
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1258
|
+
DistributionRulesModalTemplate,
|
|
1259
|
+
{
|
|
1260
|
+
theme,
|
|
1261
|
+
accentColor,
|
|
1262
|
+
state,
|
|
1263
|
+
claimingId,
|
|
1264
|
+
claimErrors,
|
|
1265
|
+
claimedIds,
|
|
1266
|
+
onRefresh: () => void load(),
|
|
1267
|
+
onClaim: handleClaim,
|
|
1268
|
+
onClose
|
|
1269
|
+
}
|
|
1270
|
+
) });
|
|
1271
|
+
}
|
|
1057
1272
|
var STATUS_CONFIG = {
|
|
1058
1273
|
none: { label: "Not started", color: "#6b7280", dot: false },
|
|
1059
1274
|
pending: { label: "Pending review", color: "#f59e0b", dot: true },
|
|
@@ -1577,166 +1792,6 @@ function LoginModal({ onClose }) {
|
|
|
1577
1792
|
}
|
|
1578
1793
|
) });
|
|
1579
1794
|
}
|
|
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
1795
|
var RAIL_LABELS = {
|
|
1741
1796
|
SPEI: "SPEI (Mexico)",
|
|
1742
1797
|
PIX: "PIX (Brazil)",
|
|
@@ -2051,6 +2106,166 @@ function RampWidget({ onClose }) {
|
|
|
2051
2106
|
}
|
|
2052
2107
|
) });
|
|
2053
2108
|
}
|
|
2109
|
+
|
|
2110
|
+
// src/lib/qr-code/index.tsx
|
|
2111
|
+
var import_ErrorCorrectLevel = __toESM(require_ErrorCorrectLevel());
|
|
2112
|
+
var import_QRCode = __toESM(require_QRCode());
|
|
2113
|
+
var QRCodeSvg = react.forwardRef(function QRCodeSvg2({
|
|
2114
|
+
bgColor,
|
|
2115
|
+
bgD,
|
|
2116
|
+
fgD,
|
|
2117
|
+
fgColor,
|
|
2118
|
+
size,
|
|
2119
|
+
title,
|
|
2120
|
+
viewBoxSize,
|
|
2121
|
+
xmlns = "http://www.w3.org/2000/svg",
|
|
2122
|
+
...props
|
|
2123
|
+
}, ref) {
|
|
2124
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { ...props, height: size, ref, viewBox: `0 0 ${viewBoxSize} ${viewBoxSize}`, width: size, xmlns, children: [
|
|
2125
|
+
title ? /* @__PURE__ */ jsxRuntime.jsx("title", { children: title }) : null,
|
|
2126
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: bgD, fill: bgColor }),
|
|
2127
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: fgD, fill: fgColor })
|
|
2128
|
+
] });
|
|
2129
|
+
});
|
|
2130
|
+
QRCodeSvg.displayName = "QRCodeSvg";
|
|
2131
|
+
function bytesToBinaryString(bytes) {
|
|
2132
|
+
return bytes.map((b) => String.fromCharCode(b & 255)).join("");
|
|
2133
|
+
}
|
|
2134
|
+
function encodeStringToUtf8Bytes(input) {
|
|
2135
|
+
return Array.from(new TextEncoder().encode(input));
|
|
2136
|
+
}
|
|
2137
|
+
var QRCode = react.forwardRef(function QRCode2({ bgColor = "#FFFFFF", fgColor = "#000000", level = "L", size = 256, value, ...props }, ref) {
|
|
2138
|
+
const qrcode = new import_QRCode.default(-1, import_ErrorCorrectLevel.default[level]);
|
|
2139
|
+
const utf8Bytes = encodeStringToUtf8Bytes(value);
|
|
2140
|
+
const binaryString = bytesToBinaryString(utf8Bytes);
|
|
2141
|
+
qrcode.addData(binaryString, "Byte");
|
|
2142
|
+
qrcode.make();
|
|
2143
|
+
const cells = qrcode.modules;
|
|
2144
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2145
|
+
QRCodeSvg,
|
|
2146
|
+
{
|
|
2147
|
+
...props,
|
|
2148
|
+
bgColor,
|
|
2149
|
+
bgD: cells.map((row, rowIndex) => row.map((cell, cellIndex) => !cell ? `M ${cellIndex} ${rowIndex} l 1 0 0 1 -1 0 Z` : "").join(" ")).join(" "),
|
|
2150
|
+
fgColor,
|
|
2151
|
+
fgD: cells.map((row, rowIndex) => row.map((cell, cellIndex) => cell ? `M ${cellIndex} ${rowIndex} l 1 0 0 1 -1 0 Z` : "").join(" ")).join(" "),
|
|
2152
|
+
ref,
|
|
2153
|
+
size,
|
|
2154
|
+
viewBoxSize: cells.length
|
|
2155
|
+
}
|
|
2156
|
+
);
|
|
2157
|
+
});
|
|
2158
|
+
function ReceiveModalTemplate({
|
|
2159
|
+
theme,
|
|
2160
|
+
accentColor,
|
|
2161
|
+
walletAddress,
|
|
2162
|
+
copied,
|
|
2163
|
+
onCopy,
|
|
2164
|
+
onClose
|
|
2165
|
+
}) {
|
|
2166
|
+
const isDark = theme === "dark";
|
|
2167
|
+
const cssVars = {
|
|
2168
|
+
"--pollar-accent": accentColor,
|
|
2169
|
+
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
2170
|
+
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
2171
|
+
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
2172
|
+
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
2173
|
+
"--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
|
|
2174
|
+
"--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
|
|
2175
|
+
"--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
|
|
2176
|
+
"--pollar-error-text": isDark ? "#f87171" : "#dc2626",
|
|
2177
|
+
"--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
|
|
2178
|
+
"--pollar-buttons-border-radius": "6px",
|
|
2179
|
+
"--pollar-buttons-height": "44px",
|
|
2180
|
+
"--pollar-input-height": "44px",
|
|
2181
|
+
"--pollar-input-border-radius": "0.5rem",
|
|
2182
|
+
"--pollar-card-border-radius": "10px"
|
|
2183
|
+
};
|
|
2184
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2185
|
+
"div",
|
|
2186
|
+
{
|
|
2187
|
+
className: "pollar-modal-card pollar-receive-modal",
|
|
2188
|
+
"data-theme": theme,
|
|
2189
|
+
style: cssVars,
|
|
2190
|
+
onClick: (e) => e.stopPropagation(),
|
|
2191
|
+
children: [
|
|
2192
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
|
|
2193
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Receive" }),
|
|
2194
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-header-actions", children: /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-modal-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2 2l12 12M14 2L2 14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) }) })
|
|
2195
|
+
] }),
|
|
2196
|
+
walletAddress ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2197
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-receive-qr", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2198
|
+
QRCode,
|
|
2199
|
+
{
|
|
2200
|
+
value: walletAddress,
|
|
2201
|
+
size: 180,
|
|
2202
|
+
fgColor: isDark ? "#ffffff" : "#111827",
|
|
2203
|
+
bgColor: "transparent"
|
|
2204
|
+
}
|
|
2205
|
+
) }),
|
|
2206
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "pollar-receive-instructions", children: "Share your Stellar address to receive any asset. Only send Stellar assets to this address." }),
|
|
2207
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-receive-address-row", children: [
|
|
2208
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-receive-address", children: walletAddress }),
|
|
2209
|
+
/* @__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: [
|
|
2210
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
|
|
2211
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
|
|
2212
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2213
|
+
"path",
|
|
2214
|
+
{
|
|
2215
|
+
d: "M3.5 7l2.5 2.5 4.5-5",
|
|
2216
|
+
stroke: "white",
|
|
2217
|
+
strokeWidth: "1.5",
|
|
2218
|
+
strokeLinecap: "round",
|
|
2219
|
+
strokeLinejoin: "round"
|
|
2220
|
+
}
|
|
2221
|
+
)
|
|
2222
|
+
] }),
|
|
2223
|
+
"Copied!"
|
|
2224
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2225
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
|
|
2226
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1.5", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
2227
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2228
|
+
"path",
|
|
2229
|
+
{
|
|
2230
|
+
d: "M3 9H2a1 1 0 01-1-1V2a1 1 0 011-1h6a1 1 0 011 1v1",
|
|
2231
|
+
stroke: "currentColor",
|
|
2232
|
+
strokeWidth: "1.5",
|
|
2233
|
+
strokeLinecap: "round"
|
|
2234
|
+
}
|
|
2235
|
+
)
|
|
2236
|
+
] }),
|
|
2237
|
+
"Copy address"
|
|
2238
|
+
] }) })
|
|
2239
|
+
] })
|
|
2240
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No wallet connected." }),
|
|
2241
|
+
/* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
|
|
2242
|
+
]
|
|
2243
|
+
}
|
|
2244
|
+
);
|
|
2245
|
+
}
|
|
2246
|
+
function ReceiveModal({ onClose }) {
|
|
2247
|
+
const { walletAddress, styles } = usePollar();
|
|
2248
|
+
const { theme = "light", accentColor = "#005DB4" } = styles;
|
|
2249
|
+
const [copied, setCopied] = react.useState(false);
|
|
2250
|
+
function handleCopy() {
|
|
2251
|
+
if (!walletAddress) return;
|
|
2252
|
+
navigator.clipboard.writeText(walletAddress).then(() => {
|
|
2253
|
+
setCopied(true);
|
|
2254
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
2255
|
+
});
|
|
2256
|
+
}
|
|
2257
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2258
|
+
ReceiveModalTemplate,
|
|
2259
|
+
{
|
|
2260
|
+
theme,
|
|
2261
|
+
accentColor,
|
|
2262
|
+
walletAddress,
|
|
2263
|
+
copied,
|
|
2264
|
+
onCopy: handleCopy,
|
|
2265
|
+
onClose
|
|
2266
|
+
}
|
|
2267
|
+
) });
|
|
2268
|
+
}
|
|
2054
2269
|
var STATUS_MESSAGES = {
|
|
2055
2270
|
idle: "",
|
|
2056
2271
|
building: "Building transaction\u2026",
|
|
@@ -2501,6 +2716,254 @@ function SendModal({ onClose }) {
|
|
|
2501
2716
|
}
|
|
2502
2717
|
) });
|
|
2503
2718
|
}
|
|
2719
|
+
function describeDevice(s) {
|
|
2720
|
+
if (s.deviceLabel) return s.deviceLabel;
|
|
2721
|
+
if (!s.userAgent) return "Unknown device";
|
|
2722
|
+
return parseUserAgent(s.userAgent);
|
|
2723
|
+
}
|
|
2724
|
+
function detectBrowser(ua) {
|
|
2725
|
+
if (/Edg\//.test(ua)) return "Edge";
|
|
2726
|
+
if (/OPR\//.test(ua)) return "Opera";
|
|
2727
|
+
if (/(Chrome|CriOS)\//.test(ua)) return "Chrome";
|
|
2728
|
+
if (/(Firefox|FxiOS)\//.test(ua)) return "Firefox";
|
|
2729
|
+
if (/Safari\//.test(ua)) return "Safari";
|
|
2730
|
+
return null;
|
|
2731
|
+
}
|
|
2732
|
+
function detectOS(ua) {
|
|
2733
|
+
if (/iPhone|iPad|iPod/.test(ua)) return "iOS";
|
|
2734
|
+
if (/Android/.test(ua)) return "Android";
|
|
2735
|
+
if (/Mac OS X/.test(ua)) return "macOS";
|
|
2736
|
+
if (/Windows NT/.test(ua)) return "Windows";
|
|
2737
|
+
if (/Linux/.test(ua)) return "Linux";
|
|
2738
|
+
return null;
|
|
2739
|
+
}
|
|
2740
|
+
function parseUserAgent(ua) {
|
|
2741
|
+
const browser = detectBrowser(ua);
|
|
2742
|
+
const os = detectOS(ua);
|
|
2743
|
+
if (browser && os) return `${os} \u2014 ${browser}`;
|
|
2744
|
+
if (os) return os;
|
|
2745
|
+
if (browser) return browser;
|
|
2746
|
+
return ua.slice(0, 48);
|
|
2747
|
+
}
|
|
2748
|
+
function formatRelative(iso) {
|
|
2749
|
+
if (!iso) return "\u2014";
|
|
2750
|
+
const ts = new Date(iso).getTime();
|
|
2751
|
+
if (!Number.isFinite(ts)) return "\u2014";
|
|
2752
|
+
const diffSec = Math.round((Date.now() - ts) / 1e3);
|
|
2753
|
+
if (diffSec < 0) return "just now";
|
|
2754
|
+
if (diffSec < 60) return `${diffSec}s ago`;
|
|
2755
|
+
const diffMin = Math.round(diffSec / 60);
|
|
2756
|
+
if (diffMin < 60) return `${diffMin}m ago`;
|
|
2757
|
+
const diffHr = Math.round(diffMin / 60);
|
|
2758
|
+
if (diffHr < 24) return `${diffHr}h ago`;
|
|
2759
|
+
const diffDay = Math.round(diffHr / 24);
|
|
2760
|
+
if (diffDay < 30) return `${diffDay}d ago`;
|
|
2761
|
+
return new Date(iso).toLocaleDateString(void 0, { month: "short", day: "numeric", year: "numeric" });
|
|
2762
|
+
}
|
|
2763
|
+
function shortIp(hash) {
|
|
2764
|
+
if (!hash) return "";
|
|
2765
|
+
return hash.slice(0, 8);
|
|
2766
|
+
}
|
|
2767
|
+
function SessionsModalTemplate({
|
|
2768
|
+
theme,
|
|
2769
|
+
accentColor,
|
|
2770
|
+
state,
|
|
2771
|
+
revokingFamilyId,
|
|
2772
|
+
signingOutEverywhere,
|
|
2773
|
+
onRefresh,
|
|
2774
|
+
onRevoke,
|
|
2775
|
+
onLogoutEverywhere,
|
|
2776
|
+
onClose
|
|
2777
|
+
}) {
|
|
2778
|
+
const isDark = theme === "dark";
|
|
2779
|
+
const cssVars = {
|
|
2780
|
+
"--pollar-accent": accentColor,
|
|
2781
|
+
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
2782
|
+
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
2783
|
+
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
2784
|
+
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
2785
|
+
"--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
|
|
2786
|
+
"--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
|
|
2787
|
+
"--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
|
|
2788
|
+
"--pollar-error-text": isDark ? "#f87171" : "#dc2626",
|
|
2789
|
+
"--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
|
|
2790
|
+
"--pollar-buttons-border-radius": "6px",
|
|
2791
|
+
"--pollar-buttons-height": "44px",
|
|
2792
|
+
"--pollar-input-height": "44px",
|
|
2793
|
+
"--pollar-input-border-radius": "0.5rem",
|
|
2794
|
+
"--pollar-card-border-radius": "10px"
|
|
2795
|
+
};
|
|
2796
|
+
const isLoading = state.step === "loading";
|
|
2797
|
+
const sessions = state.step === "loaded" ? state.sessions : [];
|
|
2798
|
+
const otherCount = sessions.filter((s) => !s.current).length;
|
|
2799
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2800
|
+
"div",
|
|
2801
|
+
{
|
|
2802
|
+
className: "pollar-modal-card pollar-sessions-modal",
|
|
2803
|
+
"data-theme": theme,
|
|
2804
|
+
style: cssVars,
|
|
2805
|
+
onClick: (e) => e.stopPropagation(),
|
|
2806
|
+
children: [
|
|
2807
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
|
|
2808
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Active sessions" }),
|
|
2809
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
|
|
2810
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-modal-refresh-btn", onClick: onRefresh, disabled: isLoading, children: [
|
|
2811
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2812
|
+
"svg",
|
|
2813
|
+
{
|
|
2814
|
+
className: `pollar-modal-refresh-icon${isLoading ? " spinning" : ""}`,
|
|
2815
|
+
width: "13",
|
|
2816
|
+
height: "13",
|
|
2817
|
+
viewBox: "0 0 13 13",
|
|
2818
|
+
fill: "none",
|
|
2819
|
+
"aria-hidden": true,
|
|
2820
|
+
children: [
|
|
2821
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M11.5 6.5a5 5 0 11-1.5-3.536", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }),
|
|
2822
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2823
|
+
"path",
|
|
2824
|
+
{
|
|
2825
|
+
d: "M10 1v3h-3",
|
|
2826
|
+
stroke: "currentColor",
|
|
2827
|
+
strokeWidth: "1.5",
|
|
2828
|
+
strokeLinecap: "round",
|
|
2829
|
+
strokeLinejoin: "round"
|
|
2830
|
+
}
|
|
2831
|
+
)
|
|
2832
|
+
]
|
|
2833
|
+
}
|
|
2834
|
+
),
|
|
2835
|
+
"Refresh"
|
|
2836
|
+
] }),
|
|
2837
|
+
/* @__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" }) }) })
|
|
2838
|
+
] })
|
|
2839
|
+
] }),
|
|
2840
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-sessions-list", children: [
|
|
2841
|
+
state.step === "idle" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "Loading\u2026" }),
|
|
2842
|
+
isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "Loading\u2026" }),
|
|
2843
|
+
state.step === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: state.message }),
|
|
2844
|
+
state.step === "loaded" && sessions.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No active sessions." }),
|
|
2845
|
+
sessions.map((s) => {
|
|
2846
|
+
const isRevoking = revokingFamilyId === s.familyId;
|
|
2847
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-sessions-item", "data-current": s.current || void 0, children: [
|
|
2848
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-sessions-item-main", children: [
|
|
2849
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-sessions-item-device", children: describeDevice(s) }),
|
|
2850
|
+
s.current && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-sessions-item-badge", children: "This device" })
|
|
2851
|
+
] }),
|
|
2852
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-sessions-item-meta", children: [
|
|
2853
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
2854
|
+
"Last used ",
|
|
2855
|
+
formatRelative(s.lastUsedAt ?? s.createdAt)
|
|
2856
|
+
] }),
|
|
2857
|
+
s.ipHash && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2858
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "\xB7" }),
|
|
2859
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { title: `ip-hash ${s.ipHash}`, children: [
|
|
2860
|
+
"ip ",
|
|
2861
|
+
shortIp(s.ipHash)
|
|
2862
|
+
] })
|
|
2863
|
+
] })
|
|
2864
|
+
] }),
|
|
2865
|
+
!s.current && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2866
|
+
"button",
|
|
2867
|
+
{
|
|
2868
|
+
className: "pollar-sessions-item-revoke",
|
|
2869
|
+
onClick: () => onRevoke(s.familyId),
|
|
2870
|
+
disabled: isRevoking || signingOutEverywhere,
|
|
2871
|
+
children: isRevoking ? "Revoking\u2026" : "Revoke"
|
|
2872
|
+
}
|
|
2873
|
+
)
|
|
2874
|
+
] }, s.familyId);
|
|
2875
|
+
})
|
|
2876
|
+
] }),
|
|
2877
|
+
state.step === "loaded" && sessions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-sessions-actions", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2878
|
+
"button",
|
|
2879
|
+
{
|
|
2880
|
+
className: "pollar-sessions-logout-all",
|
|
2881
|
+
onClick: onLogoutEverywhere,
|
|
2882
|
+
disabled: signingOutEverywhere || otherCount === 0,
|
|
2883
|
+
title: otherCount === 0 ? "No other devices to sign out" : void 0,
|
|
2884
|
+
children: signingOutEverywhere ? "Signing out\u2026" : "Sign out everywhere"
|
|
2885
|
+
}
|
|
2886
|
+
) }),
|
|
2887
|
+
/* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
|
|
2888
|
+
]
|
|
2889
|
+
}
|
|
2890
|
+
);
|
|
2891
|
+
}
|
|
2892
|
+
function SessionsModal({ onClose }) {
|
|
2893
|
+
const { getClient, styles } = usePollar();
|
|
2894
|
+
const { theme = "light", accentColor = "#005DB4" } = styles;
|
|
2895
|
+
const [state, setState] = react.useState({ step: "idle" });
|
|
2896
|
+
const [revokingFamilyId, setRevokingFamilyId] = react.useState(null);
|
|
2897
|
+
const [signingOutEverywhere, setSigningOutEverywhere] = react.useState(false);
|
|
2898
|
+
const mountedRef = react.useRef(true);
|
|
2899
|
+
react.useEffect(() => () => {
|
|
2900
|
+
mountedRef.current = false;
|
|
2901
|
+
}, []);
|
|
2902
|
+
const onCloseRef = react.useRef(onClose);
|
|
2903
|
+
onCloseRef.current = onClose;
|
|
2904
|
+
react.useEffect(() => {
|
|
2905
|
+
return getClient().onAuthStateChange((authState) => {
|
|
2906
|
+
if (authState.step === "idle") onCloseRef.current();
|
|
2907
|
+
});
|
|
2908
|
+
}, [getClient]);
|
|
2909
|
+
const load = react.useCallback(async () => {
|
|
2910
|
+
setState({ step: "loading" });
|
|
2911
|
+
try {
|
|
2912
|
+
const sessions = await getClient().listSessions();
|
|
2913
|
+
if (!mountedRef.current) return;
|
|
2914
|
+
setState({ step: "loaded", sessions });
|
|
2915
|
+
} catch (err) {
|
|
2916
|
+
if (!mountedRef.current) return;
|
|
2917
|
+
const message = err instanceof Error ? err.message : "Failed to load sessions";
|
|
2918
|
+
setState({ step: "error", message });
|
|
2919
|
+
}
|
|
2920
|
+
}, [getClient]);
|
|
2921
|
+
react.useEffect(() => {
|
|
2922
|
+
void load();
|
|
2923
|
+
}, [load]);
|
|
2924
|
+
const handleRevoke = react.useCallback(
|
|
2925
|
+
async (familyId) => {
|
|
2926
|
+
setRevokingFamilyId(familyId);
|
|
2927
|
+
try {
|
|
2928
|
+
await getClient().revokeSession(familyId);
|
|
2929
|
+
if (!mountedRef.current) return;
|
|
2930
|
+
await load();
|
|
2931
|
+
} catch {
|
|
2932
|
+
if (!mountedRef.current) return;
|
|
2933
|
+
setState(
|
|
2934
|
+
(prev) => prev.step === "loaded" ? { step: "error", message: "Failed to revoke session" } : prev
|
|
2935
|
+
);
|
|
2936
|
+
} finally {
|
|
2937
|
+
if (mountedRef.current) setRevokingFamilyId(null);
|
|
2938
|
+
}
|
|
2939
|
+
},
|
|
2940
|
+
[getClient, load]
|
|
2941
|
+
);
|
|
2942
|
+
const handleLogoutEverywhere = react.useCallback(async () => {
|
|
2943
|
+
setSigningOutEverywhere(true);
|
|
2944
|
+
try {
|
|
2945
|
+
await getClient().logoutEverywhere();
|
|
2946
|
+
onClose();
|
|
2947
|
+
} catch {
|
|
2948
|
+
if (!mountedRef.current) return;
|
|
2949
|
+
setSigningOutEverywhere(false);
|
|
2950
|
+
}
|
|
2951
|
+
}, [getClient, onClose]);
|
|
2952
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2953
|
+
SessionsModalTemplate,
|
|
2954
|
+
{
|
|
2955
|
+
theme,
|
|
2956
|
+
accentColor,
|
|
2957
|
+
state,
|
|
2958
|
+
revokingFamilyId,
|
|
2959
|
+
signingOutEverywhere,
|
|
2960
|
+
onRefresh: () => void load(),
|
|
2961
|
+
onRevoke: (familyId) => void handleRevoke(familyId),
|
|
2962
|
+
onLogoutEverywhere: () => void handleLogoutEverywhere(),
|
|
2963
|
+
onClose
|
|
2964
|
+
}
|
|
2965
|
+
) });
|
|
2966
|
+
}
|
|
2504
2967
|
function TransactionModalTemplate({
|
|
2505
2968
|
theme,
|
|
2506
2969
|
accentColor,
|
|
@@ -2942,9 +3405,11 @@ function PollarProvider({ config, styles: propStyles, adapters, children }) {
|
|
|
2942
3405
|
const [walletBalanceModalOpen, setWalletBalanceModalOpen] = react.useState(false);
|
|
2943
3406
|
const [sendModalOpen, setSendModalOpen] = react.useState(false);
|
|
2944
3407
|
const [receiveModalOpen, setReceiveModalOpen] = react.useState(false);
|
|
3408
|
+
const [sessionsModalOpen, setSessionsModalOpen] = react.useState(false);
|
|
3409
|
+
const [distributionRulesModalOpen, setDistributionRulesModalOpen] = react.useState(false);
|
|
2945
3410
|
const adaptersRef = react.useRef(adapters);
|
|
2946
3411
|
adaptersRef.current = adapters;
|
|
2947
|
-
const walletAddress = sessionState?.
|
|
3412
|
+
const walletAddress = sessionState?.wallet?.publicKey || "";
|
|
2948
3413
|
const getClient = react.useCallback(() => pollarClient, [pollarClient]);
|
|
2949
3414
|
const refreshWalletBalance = react.useCallback(() => pollarClient.refreshBalance(walletAddress), [pollarClient, walletAddress]);
|
|
2950
3415
|
const contextValue = react.useMemo(
|
|
@@ -2974,6 +3439,10 @@ function PollarProvider({ config, styles: propStyles, adapters, children }) {
|
|
|
2974
3439
|
// send / receive
|
|
2975
3440
|
openSendModal: () => setSendModalOpen(true),
|
|
2976
3441
|
openReceiveModal: () => setReceiveModalOpen(true),
|
|
3442
|
+
// sessions
|
|
3443
|
+
openSessionsModal: () => setSessionsModalOpen(true),
|
|
3444
|
+
// distribution
|
|
3445
|
+
openDistributionRulesModal: () => setDistributionRulesModalOpen(true),
|
|
2977
3446
|
// network
|
|
2978
3447
|
network: networkState.step === "connected" ? networkState.network : "testnet",
|
|
2979
3448
|
setNetwork: (network) => pollarClient.setNetwork(network),
|
|
@@ -2989,7 +3458,18 @@ function PollarProvider({ config, styles: propStyles, adapters, children }) {
|
|
|
2989
3458
|
styles,
|
|
2990
3459
|
adapters: adaptersRef.current
|
|
2991
3460
|
}),
|
|
2992
|
-
[
|
|
3461
|
+
[
|
|
3462
|
+
walletAddress,
|
|
3463
|
+
pollarClient,
|
|
3464
|
+
getClient,
|
|
3465
|
+
transaction,
|
|
3466
|
+
txHistory,
|
|
3467
|
+
walletBalance,
|
|
3468
|
+
refreshWalletBalance,
|
|
3469
|
+
networkState,
|
|
3470
|
+
remoteConfig,
|
|
3471
|
+
styles
|
|
3472
|
+
]
|
|
2993
3473
|
);
|
|
2994
3474
|
return /* @__PURE__ */ jsxRuntime.jsxs(PollarContext.Provider, { value: contextValue, children: [
|
|
2995
3475
|
children,
|
|
@@ -3008,7 +3488,9 @@ function PollarProvider({ config, styles: propStyles, adapters, children }) {
|
|
|
3008
3488
|
txHistoryModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setTxHistoryModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(TxHistoryModal, { onClose: () => setTxHistoryModalOpen(false) }) }),
|
|
3009
3489
|
walletBalanceModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setWalletBalanceModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(WalletBalanceModal, { onClose: () => setWalletBalanceModalOpen(false) }) }),
|
|
3010
3490
|
sendModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setSendModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(SendModal, { onClose: () => setSendModalOpen(false) }) }),
|
|
3011
|
-
receiveModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setReceiveModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(ReceiveModal, { onClose: () => setReceiveModalOpen(false) }) })
|
|
3491
|
+
receiveModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setReceiveModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(ReceiveModal, { onClose: () => setReceiveModalOpen(false) }) }),
|
|
3492
|
+
sessionsModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setSessionsModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(SessionsModal, { onClose: () => setSessionsModalOpen(false) }) }),
|
|
3493
|
+
distributionRulesModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setDistributionRulesModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(DistributionRulesModal, { onClose: () => setDistributionRulesModalOpen(false) }) })
|
|
3012
3494
|
] });
|
|
3013
3495
|
}
|
|
3014
3496
|
function usePollar() {
|
|
@@ -3259,6 +3741,8 @@ function WalletButton() {
|
|
|
3259
3741
|
);
|
|
3260
3742
|
}
|
|
3261
3743
|
|
|
3744
|
+
exports.DistributionRulesModal = DistributionRulesModal;
|
|
3745
|
+
exports.DistributionRulesModalTemplate = DistributionRulesModalTemplate;
|
|
3262
3746
|
exports.KycModal = KycModal;
|
|
3263
3747
|
exports.KycModalTemplate = KycModalTemplate;
|
|
3264
3748
|
exports.KycStatus = KycStatus;
|
|
@@ -3271,6 +3755,8 @@ exports.ReceiveModalTemplate = ReceiveModalTemplate;
|
|
|
3271
3755
|
exports.RouteDisplay = RouteDisplay;
|
|
3272
3756
|
exports.SendModal = SendModal;
|
|
3273
3757
|
exports.SendModalTemplate = SendModalTemplate;
|
|
3758
|
+
exports.SessionsModal = SessionsModal;
|
|
3759
|
+
exports.SessionsModalTemplate = SessionsModalTemplate;
|
|
3274
3760
|
exports.TransactionModalTemplate = TransactionModalTemplate;
|
|
3275
3761
|
exports.TxHistoryModalTemplate = TxHistoryModalTemplate;
|
|
3276
3762
|
exports.TxStatusView = TxStatusView;
|