@pollar/react 0.11.1 → 0.11.3-rc.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 +20 -14
- package/dist/index.css +76 -18
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +158 -17
- package/dist/index.d.ts +158 -17
- package/dist/index.js +446 -398
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +442 -399
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1035,7 +1035,7 @@ var PollarModalFooter = () => {
|
|
|
1035
1035
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-footer-name", children: "Pollar" }),
|
|
1036
1036
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-footer-version", children: [
|
|
1037
1037
|
"v",
|
|
1038
|
-
"0.11.1"
|
|
1038
|
+
"0.11.3-rc.1"
|
|
1039
1039
|
] })
|
|
1040
1040
|
] })
|
|
1041
1041
|
] });
|
|
@@ -1131,6 +1131,81 @@ function Toggle({ checked, onChange, disabled = false, busy = false, label }) {
|
|
|
1131
1131
|
}
|
|
1132
1132
|
);
|
|
1133
1133
|
}
|
|
1134
|
+
|
|
1135
|
+
// src/components/modal-theme.ts
|
|
1136
|
+
var DEFAULT_MODAL_BORDER_RADIUS = 16;
|
|
1137
|
+
var DEFAULT_BUTTON_BORDER_RADIUS = 6;
|
|
1138
|
+
var DEFAULT_OVERLAY_Z_INDEX = 50;
|
|
1139
|
+
function px(value, fallback) {
|
|
1140
|
+
return `${typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : fallback}px`;
|
|
1141
|
+
}
|
|
1142
|
+
function color(value, fallback) {
|
|
1143
|
+
return typeof value === "string" && value.trim() !== "" ? value : fallback;
|
|
1144
|
+
}
|
|
1145
|
+
function parseHex(value) {
|
|
1146
|
+
const hex = value.trim().replace(/^#/, "");
|
|
1147
|
+
const full = hex.length === 3 ? [...hex].map((c) => c + c).join("") : hex;
|
|
1148
|
+
if (!/^[0-9a-f]{6}$/i.test(full)) return null;
|
|
1149
|
+
return [Number.parseInt(full.slice(0, 2), 16), Number.parseInt(full.slice(2, 4), 16), Number.parseInt(full.slice(4, 6), 16)];
|
|
1150
|
+
}
|
|
1151
|
+
function readableTextOn(background) {
|
|
1152
|
+
const rgb = parseHex(background);
|
|
1153
|
+
if (!rgb) return "#ffffff";
|
|
1154
|
+
const [r, g, b] = rgb;
|
|
1155
|
+
return (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255 > 0.6 ? "#111827" : "#ffffff";
|
|
1156
|
+
}
|
|
1157
|
+
function buildModalCssVars(theme, accentColor, overrides = {}, variant = "compact") {
|
|
1158
|
+
const isDark = theme === "dark";
|
|
1159
|
+
const textColor = color(overrides.textColor, isDark ? "#ffffff" : "#111827");
|
|
1160
|
+
const secondaryBg = color(overrides.buttonColor, "");
|
|
1161
|
+
return {
|
|
1162
|
+
"--pollar-accent": accentColor,
|
|
1163
|
+
"--pollar-bg": color(overrides.backgroundColor, isDark ? "#1a1a1a" : "#ffffff"),
|
|
1164
|
+
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
1165
|
+
"--pollar-text": textColor,
|
|
1166
|
+
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
1167
|
+
// The primary button is the accent's, straight up; its label follows the
|
|
1168
|
+
// accent's luminance so a pale accent doesn't render white-on-white.
|
|
1169
|
+
"--pollar-btn-primary-fg": readableTextOn(accentColor),
|
|
1170
|
+
...secondaryBg ? {
|
|
1171
|
+
"--pollar-btn-secondary-bg": secondaryBg,
|
|
1172
|
+
"--pollar-btn-secondary-fg": readableTextOn(secondaryBg)
|
|
1173
|
+
} : {},
|
|
1174
|
+
"--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
|
|
1175
|
+
"--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
|
|
1176
|
+
"--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
|
|
1177
|
+
"--pollar-error-text": isDark ? "#f87171" : "#dc2626",
|
|
1178
|
+
"--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
|
|
1179
|
+
"--pollar-modal-border-radius": px(overrides.modalBorderRadius, DEFAULT_MODAL_BORDER_RADIUS),
|
|
1180
|
+
"--pollar-buttons-border-radius": px(overrides.buttonBorderRadius, DEFAULT_BUTTON_BORDER_RADIUS),
|
|
1181
|
+
"--pollar-buttons-height": "44px",
|
|
1182
|
+
"--pollar-input-height": "44px",
|
|
1183
|
+
"--pollar-input-border-radius": "0.5rem",
|
|
1184
|
+
"--pollar-card-border-radius": "10px",
|
|
1185
|
+
...variant === "hero" ? {
|
|
1186
|
+
"--pollar-modal-padding": "2rem",
|
|
1187
|
+
"--pollar-modal-heading-size": "1.375rem",
|
|
1188
|
+
"--pollar-modal-subtitle-size": "0.9rem"
|
|
1189
|
+
} : {}
|
|
1190
|
+
};
|
|
1191
|
+
}
|
|
1192
|
+
function modalChrome(styles) {
|
|
1193
|
+
const zIndex = styles.modalZIndex;
|
|
1194
|
+
return {
|
|
1195
|
+
theme: styles.theme ?? "light",
|
|
1196
|
+
accentColor: styles.accentColor ?? "#005DB4",
|
|
1197
|
+
styleOverrides: {
|
|
1198
|
+
backgroundColor: styles.backgroundColor,
|
|
1199
|
+
textColor: styles.textColor,
|
|
1200
|
+
buttonColor: styles.buttonColor,
|
|
1201
|
+
modalBorderRadius: styles.modalBorderRadius,
|
|
1202
|
+
buttonBorderRadius: styles.buttonBorderRadius
|
|
1203
|
+
},
|
|
1204
|
+
overlayStyle: {
|
|
1205
|
+
"--pollar-overlay-z-index": typeof zIndex === "number" && Number.isFinite(zIndex) ? zIndex : DEFAULT_OVERLAY_Z_INDEX
|
|
1206
|
+
}
|
|
1207
|
+
};
|
|
1208
|
+
}
|
|
1134
1209
|
var PERIOD_LABEL = {
|
|
1135
1210
|
DAY: "every 24h",
|
|
1136
1211
|
DAY_CALENDAR: "daily",
|
|
@@ -1200,6 +1275,7 @@ function RuleCard({
|
|
|
1200
1275
|
function DistributionRulesModalTemplate({
|
|
1201
1276
|
theme,
|
|
1202
1277
|
accentColor,
|
|
1278
|
+
styleOverrides,
|
|
1203
1279
|
state,
|
|
1204
1280
|
claimingId,
|
|
1205
1281
|
claimErrors,
|
|
@@ -1208,24 +1284,7 @@ function DistributionRulesModalTemplate({
|
|
|
1208
1284
|
onClaim,
|
|
1209
1285
|
onClose
|
|
1210
1286
|
}) {
|
|
1211
|
-
const
|
|
1212
|
-
const cssVars = {
|
|
1213
|
-
"--pollar-accent": accentColor,
|
|
1214
|
-
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
1215
|
-
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
1216
|
-
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
1217
|
-
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
1218
|
-
"--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
|
|
1219
|
-
"--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
|
|
1220
|
-
"--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
|
|
1221
|
-
"--pollar-error-text": isDark ? "#f87171" : "#dc2626",
|
|
1222
|
-
"--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
|
|
1223
|
-
"--pollar-buttons-border-radius": "6px",
|
|
1224
|
-
"--pollar-buttons-height": "44px",
|
|
1225
|
-
"--pollar-input-height": "44px",
|
|
1226
|
-
"--pollar-input-border-radius": "0.5rem",
|
|
1227
|
-
"--pollar-card-border-radius": "10px"
|
|
1228
|
-
};
|
|
1287
|
+
const cssVars = buildModalCssVars(theme, accentColor, styleOverrides);
|
|
1229
1288
|
const isLoading = state.step === "loading";
|
|
1230
1289
|
const rules = state.step === "loaded" ? state.rules : [];
|
|
1231
1290
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -1300,7 +1359,7 @@ function DistributionRulesModalTemplate({
|
|
|
1300
1359
|
}
|
|
1301
1360
|
function DistributionRulesModal({ onClose }) {
|
|
1302
1361
|
const { getClient, styles } = usePollar();
|
|
1303
|
-
const { theme
|
|
1362
|
+
const { theme, accentColor, styleOverrides, overlayStyle } = modalChrome(styles);
|
|
1304
1363
|
const [state, setState] = react.useState({ step: "idle" });
|
|
1305
1364
|
const [claimingId, setClaimingId] = react.useState(null);
|
|
1306
1365
|
const [claimErrors, setClaimErrors] = react.useState({});
|
|
@@ -1343,11 +1402,12 @@ function DistributionRulesModal({ onClose }) {
|
|
|
1343
1402
|
},
|
|
1344
1403
|
[getClient]
|
|
1345
1404
|
);
|
|
1346
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1405
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", style: overlayStyle, onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1347
1406
|
DistributionRulesModalTemplate,
|
|
1348
1407
|
{
|
|
1349
1408
|
theme,
|
|
1350
1409
|
accentColor,
|
|
1410
|
+
styleOverrides,
|
|
1351
1411
|
state,
|
|
1352
1412
|
claimingId,
|
|
1353
1413
|
claimErrors,
|
|
@@ -1419,26 +1479,6 @@ function useChains() {
|
|
|
1419
1479
|
return { chains, primaryChain, primaryAddress: addressForChain(wallets, primaryChain), ready: true };
|
|
1420
1480
|
}, [wallets, configured, ready]);
|
|
1421
1481
|
}
|
|
1422
|
-
function cssVarsFor(theme, accentColor) {
|
|
1423
|
-
const isDark = theme === "dark";
|
|
1424
|
-
return {
|
|
1425
|
-
"--pollar-accent": accentColor,
|
|
1426
|
-
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
1427
|
-
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
1428
|
-
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
1429
|
-
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
1430
|
-
"--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
|
|
1431
|
-
"--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
|
|
1432
|
-
"--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
|
|
1433
|
-
"--pollar-error-text": isDark ? "#f87171" : "#dc2626",
|
|
1434
|
-
"--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
|
|
1435
|
-
"--pollar-buttons-border-radius": "6px",
|
|
1436
|
-
"--pollar-buttons-height": "44px",
|
|
1437
|
-
"--pollar-input-height": "44px",
|
|
1438
|
-
"--pollar-input-border-radius": "0.5rem",
|
|
1439
|
-
"--pollar-card-border-radius": "10px"
|
|
1440
|
-
};
|
|
1441
|
-
}
|
|
1442
1482
|
function assetKey(record) {
|
|
1443
1483
|
return record.code + (record.issuer ?? "");
|
|
1444
1484
|
}
|
|
@@ -1485,6 +1525,7 @@ function AssetItem({
|
|
|
1485
1525
|
function EnabledAssetsModalTemplate({
|
|
1486
1526
|
theme,
|
|
1487
1527
|
accentColor,
|
|
1528
|
+
styleOverrides,
|
|
1488
1529
|
enabledAssets,
|
|
1489
1530
|
walletAddress,
|
|
1490
1531
|
chains,
|
|
@@ -1497,7 +1538,7 @@ function EnabledAssetsModalTemplate({
|
|
|
1497
1538
|
onToggleTrustline,
|
|
1498
1539
|
onAddCustom
|
|
1499
1540
|
}) {
|
|
1500
|
-
const cssVars =
|
|
1541
|
+
const cssVars = buildModalCssVars(theme, accentColor, styleOverrides);
|
|
1501
1542
|
const isLoading = enabledAssets.step === "loading";
|
|
1502
1543
|
const data = useStickyData(enabledAssets.step === "loaded" ? enabledAssets.data : null);
|
|
1503
1544
|
const busy = busyKey !== null;
|
|
@@ -1589,13 +1630,14 @@ function isValidIssuer(issuer) {
|
|
|
1589
1630
|
function CustomTrustlineModalTemplate({
|
|
1590
1631
|
theme,
|
|
1591
1632
|
accentColor,
|
|
1633
|
+
styleOverrides,
|
|
1592
1634
|
busy,
|
|
1593
1635
|
actionError,
|
|
1594
1636
|
onBack,
|
|
1595
1637
|
onClose,
|
|
1596
1638
|
onSubmit
|
|
1597
1639
|
}) {
|
|
1598
|
-
const cssVars =
|
|
1640
|
+
const cssVars = buildModalCssVars(theme, accentColor, styleOverrides);
|
|
1599
1641
|
const [code, setCode] = react.useState("");
|
|
1600
1642
|
const [issuer, setIssuer] = react.useState("");
|
|
1601
1643
|
const [limit, setLimit] = react.useState("");
|
|
@@ -1692,7 +1734,7 @@ function assetKey2(record) {
|
|
|
1692
1734
|
}
|
|
1693
1735
|
function EnabledAssetsModal({ onClose }) {
|
|
1694
1736
|
const { enabledAssets, refreshAssets, setTrustline, wallets, styles } = usePollar();
|
|
1695
|
-
const { theme
|
|
1737
|
+
const { theme, accentColor, styleOverrides, overlayStyle } = modalChrome(styles);
|
|
1696
1738
|
const { chains } = useChains();
|
|
1697
1739
|
const [selectedChain, setSelectedChain] = react.useState(null);
|
|
1698
1740
|
react.useEffect(() => {
|
|
@@ -1743,11 +1785,12 @@ function EnabledAssetsModal({ onClose }) {
|
|
|
1743
1785
|
},
|
|
1744
1786
|
[runAction]
|
|
1745
1787
|
);
|
|
1746
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: view === "list" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1788
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", style: overlayStyle, onClick: onClose, children: view === "list" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1747
1789
|
EnabledAssetsModalTemplate,
|
|
1748
1790
|
{
|
|
1749
1791
|
theme,
|
|
1750
1792
|
accentColor,
|
|
1793
|
+
styleOverrides,
|
|
1751
1794
|
enabledAssets,
|
|
1752
1795
|
walletAddress,
|
|
1753
1796
|
chains,
|
|
@@ -1768,6 +1811,7 @@ function EnabledAssetsModal({ onClose }) {
|
|
|
1768
1811
|
{
|
|
1769
1812
|
theme,
|
|
1770
1813
|
accentColor,
|
|
1814
|
+
styleOverrides,
|
|
1771
1815
|
busy: busyKey === "custom",
|
|
1772
1816
|
actionError,
|
|
1773
1817
|
onBack: () => {
|
|
@@ -1802,6 +1846,7 @@ function KycStatus({ status, className }) {
|
|
|
1802
1846
|
function KycModalTemplate({
|
|
1803
1847
|
theme,
|
|
1804
1848
|
accentColor,
|
|
1849
|
+
styleOverrides,
|
|
1805
1850
|
step,
|
|
1806
1851
|
providers,
|
|
1807
1852
|
selectedProvider,
|
|
@@ -1813,27 +1858,7 @@ function KycModalTemplate({
|
|
|
1813
1858
|
onRefresh,
|
|
1814
1859
|
onClose
|
|
1815
1860
|
}) {
|
|
1816
|
-
const
|
|
1817
|
-
const cssVars = {
|
|
1818
|
-
"--pollar-accent": accentColor,
|
|
1819
|
-
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
1820
|
-
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
1821
|
-
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
1822
|
-
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
1823
|
-
"--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
|
|
1824
|
-
"--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
|
|
1825
|
-
"--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
|
|
1826
|
-
"--pollar-error-text": isDark ? "#f87171" : "#dc2626",
|
|
1827
|
-
"--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
|
|
1828
|
-
"--pollar-buttons-border-radius": "6px",
|
|
1829
|
-
"--pollar-buttons-height": "44px",
|
|
1830
|
-
"--pollar-input-height": "44px",
|
|
1831
|
-
"--pollar-input-border-radius": "0.5rem",
|
|
1832
|
-
"--pollar-card-border-radius": "10px",
|
|
1833
|
-
"--pollar-modal-padding": "2rem",
|
|
1834
|
-
"--pollar-modal-heading-size": "1.375rem",
|
|
1835
|
-
"--pollar-modal-subtitle-size": "0.9rem"
|
|
1836
|
-
};
|
|
1861
|
+
const cssVars = buildModalCssVars(theme, accentColor, styleOverrides, "hero");
|
|
1837
1862
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-card pollar-kyc-modal", style: cssVars, onClick: (e) => e.stopPropagation(), children: [
|
|
1838
1863
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
|
|
1839
1864
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-kyc-header-text", children: [
|
|
@@ -1932,7 +1957,7 @@ function KycModal({ onClose, country = "MX", level = "basic", onApproved }) {
|
|
|
1932
1957
|
const [kycStatus, setKycStatus] = react.useState("none");
|
|
1933
1958
|
const [isLoading, setIsLoading] = react.useState(false);
|
|
1934
1959
|
const client = getClient();
|
|
1935
|
-
const { theme
|
|
1960
|
+
const { theme, accentColor, styleOverrides, overlayStyle } = modalChrome(styles);
|
|
1936
1961
|
const loadProviders = react.useCallback(() => {
|
|
1937
1962
|
setIsLoading(true);
|
|
1938
1963
|
return getClient().getKycProviders(country).then((result) => setProviders(result.providers)).catch(() => setProviders([])).finally(() => setIsLoading(false));
|
|
@@ -1972,11 +1997,12 @@ function KycModal({ onClose, country = "MX", level = "basic", onApproved }) {
|
|
|
1972
1997
|
setStep("done");
|
|
1973
1998
|
}
|
|
1974
1999
|
}
|
|
1975
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2000
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", style: overlayStyle, onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1976
2001
|
KycModalTemplate,
|
|
1977
2002
|
{
|
|
1978
2003
|
theme,
|
|
1979
2004
|
accentColor,
|
|
2005
|
+
styleOverrides,
|
|
1980
2006
|
step,
|
|
1981
2007
|
providers,
|
|
1982
2008
|
selectedProvider,
|
|
@@ -2168,32 +2194,10 @@ function authStateToStatus(step) {
|
|
|
2168
2194
|
if (error.includes(step)) return "ERROR";
|
|
2169
2195
|
return "NONE";
|
|
2170
2196
|
}
|
|
2171
|
-
function buildModalCssVars(theme, accentColor) {
|
|
2172
|
-
const isDark = theme === "dark";
|
|
2173
|
-
return {
|
|
2174
|
-
"--pollar-accent": accentColor,
|
|
2175
|
-
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
2176
|
-
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
2177
|
-
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
2178
|
-
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
2179
|
-
"--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
|
|
2180
|
-
"--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
|
|
2181
|
-
"--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
|
|
2182
|
-
"--pollar-error-text": isDark ? "#f87171" : "#dc2626",
|
|
2183
|
-
"--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
|
|
2184
|
-
"--pollar-buttons-border-radius": "6px",
|
|
2185
|
-
"--pollar-buttons-height": "44px",
|
|
2186
|
-
"--pollar-input-height": "44px",
|
|
2187
|
-
"--pollar-input-border-radius": "0.5rem",
|
|
2188
|
-
"--pollar-card-border-radius": "10px",
|
|
2189
|
-
"--pollar-modal-padding": "2rem",
|
|
2190
|
-
"--pollar-modal-heading-size": "1.375rem",
|
|
2191
|
-
"--pollar-modal-subtitle-size": "0.9rem"
|
|
2192
|
-
};
|
|
2193
|
-
}
|
|
2194
2197
|
function LoginModalTemplate({
|
|
2195
2198
|
theme,
|
|
2196
2199
|
accentColor,
|
|
2200
|
+
styleOverrides,
|
|
2197
2201
|
logoUrl,
|
|
2198
2202
|
emailEnabled,
|
|
2199
2203
|
embeddedWallets,
|
|
@@ -2227,7 +2231,7 @@ function LoginModalTemplate({
|
|
|
2227
2231
|
return acc;
|
|
2228
2232
|
}, []);
|
|
2229
2233
|
const activeGroupAdapters = walletGroups.find((g) => g.label === activeGroup)?.adapters ?? [];
|
|
2230
|
-
const cssVars = buildModalCssVars(theme, accentColor);
|
|
2234
|
+
const cssVars = buildModalCssVars(theme, accentColor, styleOverrides, "hero");
|
|
2231
2235
|
const status = authStateToStatus(authState.step);
|
|
2232
2236
|
const isLoading = status === "LOADING";
|
|
2233
2237
|
const isEmailCodeError = authState.step === "error" && (authState.errorCode === core.AUTH_ERROR_CODES.EMAIL_CODE_EXPIRED || authState.errorCode === core.AUTH_ERROR_CODES.EMAIL_CODE_INVALID);
|
|
@@ -2406,12 +2410,13 @@ function LoginModalStatus({
|
|
|
2406
2410
|
status,
|
|
2407
2411
|
theme,
|
|
2408
2412
|
accentColor,
|
|
2413
|
+
styleOverrides,
|
|
2409
2414
|
logoUrl,
|
|
2410
2415
|
appName,
|
|
2411
2416
|
onRetry,
|
|
2412
2417
|
onCancel
|
|
2413
2418
|
}) {
|
|
2414
|
-
const cssVars = buildModalCssVars(theme, accentColor);
|
|
2419
|
+
const cssVars = buildModalCssVars(theme, accentColor, styleOverrides, "hero");
|
|
2415
2420
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-card pollar-modal", style: cssVars, onClick: (e) => e.stopPropagation(), children: [
|
|
2416
2421
|
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-close-btn", onClick: onCancel, "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2417
2422
|
"svg",
|
|
@@ -2446,6 +2451,7 @@ function PrivyLoginSubmodal({
|
|
|
2446
2451
|
adapter,
|
|
2447
2452
|
theme,
|
|
2448
2453
|
accentColor,
|
|
2454
|
+
styleOverrides,
|
|
2449
2455
|
logoUrl,
|
|
2450
2456
|
appName,
|
|
2451
2457
|
onBack,
|
|
@@ -2457,28 +2463,8 @@ function PrivyLoginSubmodal({
|
|
|
2457
2463
|
const [view, setView] = react.useState("root");
|
|
2458
2464
|
const [status, setStatus] = react.useState("NONE");
|
|
2459
2465
|
const [message, setMessage] = react.useState("");
|
|
2460
|
-
const isDark = theme === "dark";
|
|
2461
2466
|
const isLoading = status === "LOADING";
|
|
2462
|
-
const cssVars =
|
|
2463
|
-
"--pollar-accent": accentColor,
|
|
2464
|
-
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
2465
|
-
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
2466
|
-
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
2467
|
-
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
2468
|
-
"--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
|
|
2469
|
-
"--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
|
|
2470
|
-
"--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
|
|
2471
|
-
"--pollar-error-text": isDark ? "#f87171" : "#dc2626",
|
|
2472
|
-
"--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
|
|
2473
|
-
"--pollar-buttons-border-radius": "6px",
|
|
2474
|
-
"--pollar-buttons-height": "44px",
|
|
2475
|
-
"--pollar-input-height": "44px",
|
|
2476
|
-
"--pollar-input-border-radius": "0.5rem",
|
|
2477
|
-
"--pollar-card-border-radius": "10px",
|
|
2478
|
-
"--pollar-modal-padding": "2rem",
|
|
2479
|
-
"--pollar-modal-heading-size": "1.375rem",
|
|
2480
|
-
"--pollar-modal-subtitle-size": "0.9rem"
|
|
2481
|
-
};
|
|
2467
|
+
const cssVars = buildModalCssVars(theme, accentColor, styleOverrides, "hero");
|
|
2482
2468
|
function fail(error) {
|
|
2483
2469
|
setStatus("ERROR");
|
|
2484
2470
|
setMessage(error instanceof Error ? error.message : "Something went wrong. Please try again.");
|
|
@@ -2635,8 +2621,10 @@ function LoginModal({ onClose }) {
|
|
|
2635
2621
|
}
|
|
2636
2622
|
};
|
|
2637
2623
|
}, [getClient]);
|
|
2638
|
-
const {
|
|
2624
|
+
const { logoUrl, emailEnabled, embeddedWallets, smartWallet, providers } = styles;
|
|
2625
|
+
const { theme, accentColor, styleOverrides, overlayStyle } = modalChrome(styles);
|
|
2639
2626
|
const smartWalletEnabled = smartWallet ?? false;
|
|
2627
|
+
const modalTitle = styles.modalTitle?.trim() || config.application?.name || "Pollar";
|
|
2640
2628
|
function handleClose() {
|
|
2641
2629
|
setEmail("");
|
|
2642
2630
|
getClient().cancelLogin();
|
|
@@ -2684,14 +2672,15 @@ function LoginModal({ onClose }) {
|
|
|
2684
2672
|
getClient().login({ provider });
|
|
2685
2673
|
}
|
|
2686
2674
|
}
|
|
2687
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: handleClose, children: configStatus !== "ready" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2675
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", style: overlayStyle, onClick: handleClose, children: configStatus !== "ready" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2688
2676
|
LoginModalStatus,
|
|
2689
2677
|
{
|
|
2690
2678
|
status: configStatus === "error" ? "error" : "loading",
|
|
2691
2679
|
theme,
|
|
2692
2680
|
accentColor,
|
|
2681
|
+
styleOverrides,
|
|
2693
2682
|
logoUrl: logoUrl ?? null,
|
|
2694
|
-
appName:
|
|
2683
|
+
appName: modalTitle,
|
|
2695
2684
|
onRetry: retryConfig,
|
|
2696
2685
|
onCancel: handleClose
|
|
2697
2686
|
}
|
|
@@ -2701,8 +2690,9 @@ function LoginModal({ onClose }) {
|
|
|
2701
2690
|
adapter: interactiveAdapter,
|
|
2702
2691
|
theme,
|
|
2703
2692
|
accentColor,
|
|
2693
|
+
styleOverrides,
|
|
2704
2694
|
logoUrl: logoUrl ?? null,
|
|
2705
|
-
appName:
|
|
2695
|
+
appName: modalTitle,
|
|
2706
2696
|
onBack: () => setInteractiveAdapter(null),
|
|
2707
2697
|
onCancel: handleClose,
|
|
2708
2698
|
onAuthenticated: handleInteractiveAuthenticated
|
|
@@ -2712,6 +2702,7 @@ function LoginModal({ onClose }) {
|
|
|
2712
2702
|
{
|
|
2713
2703
|
theme,
|
|
2714
2704
|
accentColor,
|
|
2705
|
+
styleOverrides,
|
|
2715
2706
|
logoUrl: logoUrl ?? null,
|
|
2716
2707
|
emailEnabled: !!emailEnabled,
|
|
2717
2708
|
embeddedWallets: !!embeddedWallets,
|
|
@@ -2724,7 +2715,7 @@ function LoginModal({ onClose }) {
|
|
|
2724
2715
|
apple: !!providers?.apple
|
|
2725
2716
|
},
|
|
2726
2717
|
walletAdapters,
|
|
2727
|
-
appName:
|
|
2718
|
+
appName: modalTitle,
|
|
2728
2719
|
email,
|
|
2729
2720
|
onEmailChange: setEmail,
|
|
2730
2721
|
onEmailSubmit: handleEmailSubmit,
|
|
@@ -2747,34 +2738,36 @@ var RAIL_LABELS = {
|
|
|
2747
2738
|
PSE: "PSE (Colombia)",
|
|
2748
2739
|
ACH: "ACH (US)"
|
|
2749
2740
|
};
|
|
2750
|
-
function RouteDisplay({ quote, onSelect }) {
|
|
2741
|
+
function RouteDisplay({ quote, busy = false, disabled = false, onSelect }) {
|
|
2742
|
+
const inert = busy || disabled;
|
|
2743
|
+
const select = () => {
|
|
2744
|
+
if (!inert) onSelect(quote);
|
|
2745
|
+
};
|
|
2751
2746
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2752
2747
|
"div",
|
|
2753
2748
|
{
|
|
2754
2749
|
className: "pollar-ramp-route-card",
|
|
2755
2750
|
"data-recommended": quote.recommended,
|
|
2751
|
+
"data-busy": busy || void 0,
|
|
2752
|
+
"data-disabled": disabled || void 0,
|
|
2756
2753
|
role: "button",
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2754
|
+
"aria-busy": busy,
|
|
2755
|
+
"aria-disabled": inert,
|
|
2756
|
+
tabIndex: inert ? -1 : 0,
|
|
2757
|
+
onClick: select,
|
|
2758
|
+
onKeyDown: (e) => e.key === "Enter" && select(),
|
|
2760
2759
|
children: [
|
|
2761
2760
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-route-left", children: [
|
|
2762
2761
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-ramp-route-provider", children: quote.provider }),
|
|
2763
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2764
|
-
RAIL_LABELS[quote.rail] ?? quote.rail,
|
|
2765
|
-
" \xB7 ",
|
|
2766
|
-
quote.protocol,
|
|
2767
|
-
" \xB7 ",
|
|
2768
|
-
quote.estimatedTime
|
|
2769
|
-
] })
|
|
2762
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-ramp-route-meta", children: busy ? "Starting\u2026" : `${RAIL_LABELS[quote.rail] ?? quote.rail} \xB7 ${quote.protocol} \xB7 ${quote.estimatedTime}` })
|
|
2770
2763
|
] }),
|
|
2771
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2764
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-ramp-route-right", children: busy ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-spinner pollar-spinner-sm" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2772
2765
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-ramp-route-fee", children: [
|
|
2773
2766
|
quote.fee,
|
|
2774
2767
|
"% fee"
|
|
2775
2768
|
] }),
|
|
2776
2769
|
quote.recommended && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-ramp-route-badge", children: "Best rate" })
|
|
2777
|
-
] })
|
|
2770
|
+
] }) })
|
|
2778
2771
|
]
|
|
2779
2772
|
}
|
|
2780
2773
|
);
|
|
@@ -2782,10 +2775,24 @@ function RouteDisplay({ quote, onSelect }) {
|
|
|
2782
2775
|
var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2783
2776
|
function isFieldValid(spec, raw) {
|
|
2784
2777
|
const value = (raw ?? "").trim();
|
|
2785
|
-
if (!value) return
|
|
2778
|
+
if (!value) return spec.optional === true;
|
|
2786
2779
|
if (spec.type === "email") return EMAIL_RE.test(value);
|
|
2787
2780
|
return true;
|
|
2788
2781
|
}
|
|
2782
|
+
function listOf(items) {
|
|
2783
|
+
const last = items[items.length - 1];
|
|
2784
|
+
if (last === void 0) return "a few details";
|
|
2785
|
+
if (items.length === 1) return last;
|
|
2786
|
+
return `${items.slice(0, -1).join(", ")} and ${last}`;
|
|
2787
|
+
}
|
|
2788
|
+
function placeholderFor(field, fields, values) {
|
|
2789
|
+
if (field.placeholderFrom) {
|
|
2790
|
+
const source = fields.find((f) => f.key === field.placeholderFrom);
|
|
2791
|
+
const chosen = source?.options?.find((o) => o.value === values[field.placeholderFrom]);
|
|
2792
|
+
if (chosen?.placeholder) return chosen.placeholder;
|
|
2793
|
+
}
|
|
2794
|
+
return field.placeholder;
|
|
2795
|
+
}
|
|
2789
2796
|
var LOADING_STEPS = ["Detecting your country\u2026", "Consulting providers\u2026", "Route found!"];
|
|
2790
2797
|
function flagEmoji(code) {
|
|
2791
2798
|
const cc = code.trim().toUpperCase();
|
|
@@ -2799,47 +2806,19 @@ var STATUS_LABEL = {
|
|
|
2799
2806
|
completed: "Completed",
|
|
2800
2807
|
failed: "Failed"
|
|
2801
2808
|
};
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
bank_address: "Bank address",
|
|
2807
|
-
bank_account_number: "Account number",
|
|
2808
|
-
bank_routing_number: "Routing number",
|
|
2809
|
-
iban: "IBAN",
|
|
2810
|
-
bic: "BIC",
|
|
2811
|
-
clabe: "CLABE",
|
|
2812
|
-
amount: "Amount",
|
|
2813
|
-
currency: "Currency",
|
|
2814
|
-
payment_rails: "Rails"
|
|
2815
|
-
};
|
|
2816
|
-
function flattenInstructions(instr) {
|
|
2817
|
-
const out = [];
|
|
2818
|
-
for (const [k, v] of Object.entries(instr)) {
|
|
2819
|
-
if (k === "qrBase64") {
|
|
2820
|
-
if (typeof v === "string" && v) out.push({ key: k, label: INSTRUCTION_LABELS[k] ?? "Payment QR", value: v, kind: "qr" });
|
|
2821
|
-
continue;
|
|
2822
|
-
}
|
|
2823
|
-
if ((k === "expiresAt" || k === "expires_at") && (typeof v === "number" || typeof v === "string")) {
|
|
2824
|
-
const ms = Number(v);
|
|
2825
|
-
if (Number.isFinite(ms) && ms > 0) {
|
|
2826
|
-
out.push({ key: k, label: INSTRUCTION_LABELS[k] ?? "Expires", value: new Date(ms).toLocaleString(), kind: "datetime" });
|
|
2827
|
-
}
|
|
2828
|
-
continue;
|
|
2829
|
-
}
|
|
2830
|
-
let value;
|
|
2831
|
-
if (typeof v === "string" || typeof v === "number") value = String(v);
|
|
2832
|
-
else if (Array.isArray(v)) value = v.filter((x) => typeof x === "string" || typeof x === "number").join(", ");
|
|
2833
|
-
else continue;
|
|
2834
|
-
if (!value) continue;
|
|
2835
|
-
out.push({ key: k, label: INSTRUCTION_LABELS[k] ?? k, value, kind: "text" });
|
|
2836
|
-
}
|
|
2837
|
-
return out;
|
|
2809
|
+
function displayValue(field) {
|
|
2810
|
+
if (field.type !== "datetime") return field.value;
|
|
2811
|
+
const at = new Date(field.value);
|
|
2812
|
+
return Number.isNaN(at.getTime()) ? field.value : at.toLocaleString();
|
|
2838
2813
|
}
|
|
2839
2814
|
function RampWidgetTemplate({
|
|
2840
2815
|
theme,
|
|
2841
2816
|
accentColor,
|
|
2817
|
+
styleOverrides,
|
|
2842
2818
|
step,
|
|
2819
|
+
flowSteps,
|
|
2820
|
+
flowStepIndex,
|
|
2821
|
+
startingQuoteId,
|
|
2843
2822
|
direction,
|
|
2844
2823
|
amount,
|
|
2845
2824
|
currency,
|
|
@@ -2855,6 +2834,8 @@ function RampWidgetTemplate({
|
|
|
2855
2834
|
txStatus,
|
|
2856
2835
|
kycUrl,
|
|
2857
2836
|
tosUrl,
|
|
2837
|
+
kycBlocking,
|
|
2838
|
+
kycJustApproved,
|
|
2858
2839
|
stellarTxHash,
|
|
2859
2840
|
explorerUrl,
|
|
2860
2841
|
depositInstructions,
|
|
@@ -2871,31 +2852,12 @@ function RampWidgetTemplate({
|
|
|
2871
2852
|
onOpenKyc,
|
|
2872
2853
|
onOpenTos,
|
|
2873
2854
|
onCompleteWithdraw,
|
|
2855
|
+
onBack,
|
|
2874
2856
|
onRetry,
|
|
2875
2857
|
onRefresh,
|
|
2876
2858
|
onClose
|
|
2877
2859
|
}) {
|
|
2878
|
-
const
|
|
2879
|
-
const cssVars = {
|
|
2880
|
-
"--pollar-accent": accentColor,
|
|
2881
|
-
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
2882
|
-
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
2883
|
-
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
2884
|
-
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
2885
|
-
"--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
|
|
2886
|
-
"--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
|
|
2887
|
-
"--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
|
|
2888
|
-
"--pollar-error-text": isDark ? "#f87171" : "#dc2626",
|
|
2889
|
-
"--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
|
|
2890
|
-
"--pollar-buttons-border-radius": "6px",
|
|
2891
|
-
"--pollar-buttons-height": "44px",
|
|
2892
|
-
"--pollar-input-height": "44px",
|
|
2893
|
-
"--pollar-input-border-radius": "0.5rem",
|
|
2894
|
-
"--pollar-card-border-radius": "10px",
|
|
2895
|
-
"--pollar-modal-padding": "2rem",
|
|
2896
|
-
"--pollar-modal-heading-size": "1.375rem",
|
|
2897
|
-
"--pollar-modal-subtitle-size": "0.9rem"
|
|
2898
|
-
};
|
|
2860
|
+
const cssVars = buildModalCssVars(theme, accentColor, styleOverrides, "hero");
|
|
2899
2861
|
const stepTitle = {
|
|
2900
2862
|
input: direction === "onramp" ? "Buy crypto" : "Sell crypto",
|
|
2901
2863
|
loading_quote: "Finding best route",
|
|
@@ -2908,7 +2870,11 @@ function RampWidgetTemplate({
|
|
|
2908
2870
|
input: direction === "onramp" ? "Enter the amount you want to deposit" : "Enter the amount you want to withdraw",
|
|
2909
2871
|
loading_quote: "Comparing providers in real time\u2026",
|
|
2910
2872
|
select_route: "All prices include fees",
|
|
2911
|
-
|
|
2873
|
+
// What this step actually asks for is whatever the route declared, and that
|
|
2874
|
+
// is rarely a name and an email: an Abroad off-ramp asks where to send the
|
|
2875
|
+
// money, not who you are. Say which, rather than asserting the Bridge case
|
|
2876
|
+
// over every provider.
|
|
2877
|
+
contact: `${provider || "This provider"} needs ${listOf(requiredFields.filter((f) => !f.optional).map((f) => f.label.toLowerCase()))} to continue`,
|
|
2912
2878
|
status: `Finish the flow at ${provider || "the provider"} to continue`,
|
|
2913
2879
|
error: "Please try again"
|
|
2914
2880
|
};
|
|
@@ -2943,6 +2909,26 @@ function RampWidgetTemplate({
|
|
|
2943
2909
|
/* @__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" }) }) })
|
|
2944
2910
|
] })
|
|
2945
2911
|
] }),
|
|
2912
|
+
flowStepIndex >= 0 && flowSteps.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-steps", children: [
|
|
2913
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-ramp-steps-label", children: [
|
|
2914
|
+
"Step ",
|
|
2915
|
+
flowStepIndex + 1,
|
|
2916
|
+
" of ",
|
|
2917
|
+
flowSteps.length
|
|
2918
|
+
] }),
|
|
2919
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2920
|
+
"div",
|
|
2921
|
+
{
|
|
2922
|
+
className: "pollar-ramp-steps-track",
|
|
2923
|
+
role: "progressbar",
|
|
2924
|
+
"aria-valuenow": flowStepIndex + 1,
|
|
2925
|
+
"aria-valuemin": 1,
|
|
2926
|
+
"aria-valuemax": flowSteps.length,
|
|
2927
|
+
"aria-label": flowSteps[flowStepIndex],
|
|
2928
|
+
children: flowSteps.map((label, i) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-ramp-steps-segment", "data-done": i <= flowStepIndex || void 0 }, label))
|
|
2929
|
+
}
|
|
2930
|
+
)
|
|
2931
|
+
] }),
|
|
2946
2932
|
step === "input" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2947
2933
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tabs", children: [
|
|
2948
2934
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2993,7 +2979,8 @@ function RampWidgetTemplate({
|
|
|
2993
2979
|
min: "0",
|
|
2994
2980
|
onChange: (e) => onAmountChange(e.target.value)
|
|
2995
2981
|
}
|
|
2996
|
-
)
|
|
2982
|
+
),
|
|
2983
|
+
errorMsg && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-ramp-field-error", children: errorMsg })
|
|
2997
2984
|
] }),
|
|
2998
2985
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-actions", children: [
|
|
2999
2986
|
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-secondary", onClick: onClose, children: "Cancel" }),
|
|
@@ -3017,12 +3004,25 @@ function RampWidgetTemplate({
|
|
|
3017
3004
|
] }, i))
|
|
3018
3005
|
] }),
|
|
3019
3006
|
step === "select_route" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3020
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-ramp-route-list", children: quotes.map((q, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3021
|
-
|
|
3007
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-ramp-route-list", children: quotes.map((q, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3008
|
+
RouteDisplay,
|
|
3009
|
+
{
|
|
3010
|
+
quote: q,
|
|
3011
|
+
busy: startingQuoteId != null && q.quoteId === startingQuoteId,
|
|
3012
|
+
disabled: startingQuoteId != null && q.quoteId !== startingQuoteId,
|
|
3013
|
+
onSelect: onSelectQuote
|
|
3014
|
+
},
|
|
3015
|
+
i
|
|
3016
|
+
)) }),
|
|
3017
|
+
errorMsg && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "pollar-ramp-payment-note", style: { color: "var(--pollar-error-text)" }, children: errorMsg }),
|
|
3018
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: errorMsg ? "pollar-btn-primary" : "pollar-btn-secondary", onClick: onBack, children: "Back" })
|
|
3022
3019
|
] }),
|
|
3023
3020
|
step === "contact" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3024
3021
|
requiredFields.map((f) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-field", children: [
|
|
3025
|
-
/* @__PURE__ */ jsxRuntime.
|
|
3022
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "pollar-ramp-label", children: [
|
|
3023
|
+
f.label,
|
|
3024
|
+
f.optional && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-ramp-field-optional", children: " (optional)" })
|
|
3025
|
+
] }),
|
|
3026
3026
|
f.type === "select" ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3027
3027
|
"select",
|
|
3028
3028
|
{
|
|
@@ -3040,14 +3040,16 @@ function RampWidgetTemplate({
|
|
|
3040
3040
|
type: f.type,
|
|
3041
3041
|
className: "pollar-ramp-input",
|
|
3042
3042
|
value: fieldValues[f.key] ?? "",
|
|
3043
|
+
placeholder: placeholderFor(f, requiredFields, fieldValues),
|
|
3043
3044
|
autoComplete: f.type === "email" ? "email" : "off",
|
|
3044
3045
|
onChange: (e) => onFieldChange(f.key, e.target.value)
|
|
3045
3046
|
}
|
|
3046
3047
|
),
|
|
3048
|
+
f.hint && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-ramp-field-hint", children: f.hint }),
|
|
3047
3049
|
f.type === "email" && (fieldValues[f.key] ?? "").trim() !== "" && !isFieldValid(f, fieldValues[f.key]) && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-ramp-field-error", children: "Enter a valid email address." })
|
|
3048
3050
|
] }, f.key)),
|
|
3049
3051
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-actions", children: [
|
|
3050
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-secondary", onClick:
|
|
3052
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-secondary", onClick: onBack, children: "Back" }),
|
|
3051
3053
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3052
3054
|
"button",
|
|
3053
3055
|
{
|
|
@@ -3119,20 +3121,44 @@ function RampWidgetTemplate({
|
|
|
3119
3121
|
)
|
|
3120
3122
|
] })
|
|
3121
3123
|
] }),
|
|
3122
|
-
depositInstructions && txStatus !== "completed" &&
|
|
3123
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-ramp-payment-label", children:
|
|
3124
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-ramp-payment-value", children:
|
|
3124
|
+
depositInstructions?.scannable && txStatus !== "completed" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-payment-field", children: [
|
|
3125
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-ramp-payment-label", children: "Payment QR" }),
|
|
3126
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-ramp-payment-value", children: depositInstructions.scannable.image.inlineSafe ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3127
|
+
"div",
|
|
3128
|
+
{
|
|
3129
|
+
className: "pollar-ramp-qr",
|
|
3130
|
+
"aria-label": "Payment QR",
|
|
3131
|
+
dangerouslySetInnerHTML: { __html: depositInstructions.scannable.image.data }
|
|
3132
|
+
}
|
|
3133
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
3125
3134
|
"img",
|
|
3126
3135
|
{
|
|
3127
|
-
src:
|
|
3128
|
-
alt:
|
|
3136
|
+
src: `data:${depositInstructions.scannable.image.mediaType};base64,${depositInstructions.scannable.image.data}`,
|
|
3137
|
+
alt: "Payment QR",
|
|
3129
3138
|
style: { width: "100%", maxWidth: 220, height: "auto", display: "block", margin: "0 auto" }
|
|
3130
3139
|
}
|
|
3131
|
-
)
|
|
3132
|
-
|
|
3133
|
-
|
|
3140
|
+
) })
|
|
3141
|
+
] }),
|
|
3142
|
+
depositInstructions?.scannable?.payload && depositInstructions.scannable.payloadLabel && txStatus !== "completed" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-payment-field", children: [
|
|
3143
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-ramp-payment-label", children: depositInstructions.scannable.payloadLabel }),
|
|
3144
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-ramp-payment-value", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
|
|
3145
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { style: { flex: 1, wordBreak: "break-all" }, children: depositInstructions.scannable.payload }),
|
|
3146
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3147
|
+
CopyButton,
|
|
3148
|
+
{
|
|
3149
|
+
value: depositInstructions.scannable.payload,
|
|
3150
|
+
label: `Copy ${depositInstructions.scannable.payloadLabel}`
|
|
3151
|
+
}
|
|
3152
|
+
)
|
|
3134
3153
|
] }) })
|
|
3135
|
-
] }
|
|
3154
|
+
] }),
|
|
3155
|
+
depositInstructions && txStatus !== "completed" && depositInstructions.fields.map((f) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-payment-field", children: [
|
|
3156
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-ramp-payment-label", children: f.label }),
|
|
3157
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-ramp-payment-value", children: f.copyable ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
|
|
3158
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { style: { flex: 1, wordBreak: "break-all" }, children: f.value }),
|
|
3159
|
+
/* @__PURE__ */ jsxRuntime.jsx(CopyButton, { value: f.value, label: `Copy ${f.label}` })
|
|
3160
|
+
] }) : f.type === "url" ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: f.value, target: "_blank", rel: "noopener noreferrer", children: f.value }) : /* @__PURE__ */ jsxRuntime.jsx("span", { children: displayValue(f) }) })
|
|
3161
|
+
] }, f.key)),
|
|
3136
3162
|
tosUrl && !depositInstructions && txStatus !== "completed" && /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "pollar-btn-primary", onClick: onOpenTos, children: [
|
|
3137
3163
|
"Accept terms at ",
|
|
3138
3164
|
provider
|
|
@@ -3141,6 +3167,16 @@ function RampWidgetTemplate({
|
|
|
3141
3167
|
"Continue at ",
|
|
3142
3168
|
provider
|
|
3143
3169
|
] }),
|
|
3170
|
+
kycBlocking && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "pollar-ramp-payment-note", children: [
|
|
3171
|
+
provider,
|
|
3172
|
+
" needs to verify your identity before this payout. Nothing has been sent yet \u2014 complete verification with ",
|
|
3173
|
+
provider,
|
|
3174
|
+
", and this will update on its own."
|
|
3175
|
+
] }),
|
|
3176
|
+
kycJustApproved && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "pollar-ramp-payment-note", children: [
|
|
3177
|
+
provider,
|
|
3178
|
+
" approved your verification. Request a new quote to continue \u2014 the previous one was consumed."
|
|
3179
|
+
] }),
|
|
3144
3180
|
canComplete && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-primary", disabled: completing, onClick: onCompleteWithdraw, children: completing ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3145
3181
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-spinner pollar-spinner-sm" }),
|
|
3146
3182
|
"Submitting\u2026"
|
|
@@ -3161,11 +3197,53 @@ var TERMINAL = ["completed", "failed"];
|
|
|
3161
3197
|
function requiredFieldsOf(quote) {
|
|
3162
3198
|
return quote.requiredFields ?? [];
|
|
3163
3199
|
}
|
|
3200
|
+
function flowStepsOf(quotes, selected) {
|
|
3201
|
+
const needsDetails = selected != null ? requiredFieldsOf(selected).length > 0 : quotes.some((q) => requiredFieldsOf(q).length > 0);
|
|
3202
|
+
return needsDetails ? ["Amount", "Provider", "Details", "Complete"] : ["Amount", "Provider", "Complete"];
|
|
3203
|
+
}
|
|
3204
|
+
var STEP_LABEL = {
|
|
3205
|
+
input: "Amount",
|
|
3206
|
+
loading_quote: "Amount",
|
|
3207
|
+
select_route: "Provider",
|
|
3208
|
+
contact: "Details",
|
|
3209
|
+
status: "Complete"
|
|
3210
|
+
};
|
|
3211
|
+
function brokenLimitOf(amount, quote) {
|
|
3212
|
+
const { minAmount, maxAmount } = quote;
|
|
3213
|
+
if (!Number.isFinite(amount)) return null;
|
|
3214
|
+
if (minAmount != null && amount < minAmount) return { limit: "min", value: minAmount };
|
|
3215
|
+
if (maxAmount != null && amount > maxAmount) return { limit: "max", value: maxAmount };
|
|
3216
|
+
return null;
|
|
3217
|
+
}
|
|
3218
|
+
function limitMessage(limit, value, currency) {
|
|
3219
|
+
return `The ${limit === "min" ? "minimum" : "maximum"} amount for this route is ${value} ${currency}.`;
|
|
3220
|
+
}
|
|
3221
|
+
var RAMP_ERROR_MESSAGES = {
|
|
3222
|
+
SDK_RAMPS_QUOTE_EXPIRED: "This quote expired. Request a new one and try again.",
|
|
3223
|
+
SDK_RAMPS_ASSET_NOT_ENABLED: "This currency is not available for that route right now.",
|
|
3224
|
+
SDK_RAMPS_KYC_REQUIRED: "The provider needs to verify your identity before continuing.",
|
|
3225
|
+
SDK_RAMPS_WALLET_UNSUPPORTED: "This wallet type cannot be used for this ramp.",
|
|
3226
|
+
SDK_RAMPS_PROVIDER_NOT_CONFIGURED: "This ramp provider is not configured for this app yet.",
|
|
3227
|
+
SDK_RAMPS_ANCHOR_ERROR: "The provider rejected the request. Please try again in a moment.",
|
|
3228
|
+
SDK_RAMPS_BRIDGE_ERROR: "The provider rejected the request. Please try again in a moment."
|
|
3229
|
+
};
|
|
3230
|
+
function rampErrorMessage(e, fallback) {
|
|
3231
|
+
const body = e?.body;
|
|
3232
|
+
const code = e?.code;
|
|
3233
|
+
if (typeof code !== "string") return e instanceof Error ? e.message : fallback;
|
|
3234
|
+
const limit = body?.limit;
|
|
3235
|
+
const value = body?.limitAmount;
|
|
3236
|
+
const currency = body?.limitCurrency;
|
|
3237
|
+
if ((limit === "min" || limit === "max") && typeof value === "number" && typeof currency === "string") {
|
|
3238
|
+
return limitMessage(limit, value, currency);
|
|
3239
|
+
}
|
|
3240
|
+
return RAMP_ERROR_MESSAGES[code] ?? (e instanceof Error ? e.message : fallback);
|
|
3241
|
+
}
|
|
3164
3242
|
function RampWidget({ onClose }) {
|
|
3165
3243
|
const { getClient, signTx, wallet, styles, network } = usePollar();
|
|
3166
3244
|
const walletAddress = wallet?.address ?? "";
|
|
3167
3245
|
const client = getClient();
|
|
3168
|
-
const { theme
|
|
3246
|
+
const { theme, accentColor, styleOverrides, overlayStyle } = modalChrome(styles);
|
|
3169
3247
|
const [step, setStep] = react.useState("input");
|
|
3170
3248
|
const [direction, setDirection] = react.useState("onramp");
|
|
3171
3249
|
const [amount, setAmount] = react.useState("");
|
|
@@ -3183,6 +3261,8 @@ function RampWidget({ onClose }) {
|
|
|
3183
3261
|
const [provider, setProvider] = react.useState("");
|
|
3184
3262
|
const [kycUrl, setKycUrl] = react.useState(null);
|
|
3185
3263
|
const [tosUrl, setTosUrl] = react.useState(null);
|
|
3264
|
+
const [kycPending, setKycPending] = react.useState(false);
|
|
3265
|
+
const [kycApproved, setKycApproved] = react.useState(false);
|
|
3186
3266
|
const [txStatus, setTxStatus] = react.useState(null);
|
|
3187
3267
|
const [stellarTxHash, setStellarTxHash] = react.useState(null);
|
|
3188
3268
|
const [depositInstructions, setDepositInstructions] = react.useState(null);
|
|
@@ -3211,6 +3291,23 @@ function RampWidget({ onClose }) {
|
|
|
3211
3291
|
clearInterval(id);
|
|
3212
3292
|
};
|
|
3213
3293
|
}, [step, txId, txStatus, client]);
|
|
3294
|
+
react.useEffect(() => {
|
|
3295
|
+
if (step !== "status" || !kycPending || kycApproved) return;
|
|
3296
|
+
let active = true;
|
|
3297
|
+
const check = async () => {
|
|
3298
|
+
try {
|
|
3299
|
+
const { hasApproved } = await client.getRampKycStatus();
|
|
3300
|
+
if (active && hasApproved) setKycApproved(true);
|
|
3301
|
+
} catch {
|
|
3302
|
+
}
|
|
3303
|
+
};
|
|
3304
|
+
void check();
|
|
3305
|
+
const id = setInterval(check, 1e4);
|
|
3306
|
+
return () => {
|
|
3307
|
+
active = false;
|
|
3308
|
+
clearInterval(id);
|
|
3309
|
+
};
|
|
3310
|
+
}, [step, kycPending, kycApproved, client]);
|
|
3214
3311
|
async function loadCountries(resetSelection) {
|
|
3215
3312
|
setCountriesLoading(true);
|
|
3216
3313
|
try {
|
|
@@ -3256,7 +3353,7 @@ function RampWidget({ onClose }) {
|
|
|
3256
3353
|
setRefreshing(false);
|
|
3257
3354
|
}
|
|
3258
3355
|
}
|
|
3259
|
-
function resetToInput() {
|
|
3356
|
+
function resetToInput({ keepMessage = false } = {}) {
|
|
3260
3357
|
setStep("input");
|
|
3261
3358
|
setQuotes([]);
|
|
3262
3359
|
setSelectedQuote(null);
|
|
@@ -3268,7 +3365,7 @@ function RampWidget({ onClose }) {
|
|
|
3268
3365
|
setTxStatus(null);
|
|
3269
3366
|
setStellarTxHash(null);
|
|
3270
3367
|
setDepositInstructions(null);
|
|
3271
|
-
setErrorMsg(null);
|
|
3368
|
+
if (!keepMessage) setErrorMsg(null);
|
|
3272
3369
|
}
|
|
3273
3370
|
async function resumeWithSignature(id, ps) {
|
|
3274
3371
|
const outcome = await signTx(ps.unsignedXdr);
|
|
@@ -3292,6 +3389,8 @@ function RampWidget({ onClose }) {
|
|
|
3292
3389
|
}
|
|
3293
3390
|
setKycUrl(result.kycUrl ?? null);
|
|
3294
3391
|
setTosUrl(result.tosUrl ?? null);
|
|
3392
|
+
setKycPending(result.kycRequired === true);
|
|
3393
|
+
if (result.kycRequired) setKycApproved(false);
|
|
3295
3394
|
setTxStatus(result.status);
|
|
3296
3395
|
setStellarTxHash(result.stellarTxHash ?? null);
|
|
3297
3396
|
setDepositInstructions(result.depositInstructions ?? null);
|
|
@@ -3312,7 +3411,7 @@ function RampWidget({ onClose }) {
|
|
|
3312
3411
|
setQuotes(list);
|
|
3313
3412
|
setStep("select_route");
|
|
3314
3413
|
} catch (e) {
|
|
3315
|
-
setErrorMsg(e
|
|
3414
|
+
setErrorMsg(rampErrorMessage(e, "Failed to fetch quotes."));
|
|
3316
3415
|
setStep("error");
|
|
3317
3416
|
} finally {
|
|
3318
3417
|
setIsLoading(false);
|
|
@@ -3321,8 +3420,13 @@ function RampWidget({ onClose }) {
|
|
|
3321
3420
|
function handleSelectQuote(quote) {
|
|
3322
3421
|
setSelectedQuote(quote);
|
|
3323
3422
|
setErrorMsg(null);
|
|
3423
|
+
const broken = brokenLimitOf(Number(amount), quote);
|
|
3424
|
+
if (broken) {
|
|
3425
|
+
setErrorMsg(limitMessage(broken.limit, broken.value, currency));
|
|
3426
|
+
return;
|
|
3427
|
+
}
|
|
3324
3428
|
const fields = requiredFieldsOf(quote);
|
|
3325
|
-
const missing = fields.some((f) => !(fieldValues[f.key] ?? "").trim());
|
|
3429
|
+
const missing = fields.some((f) => !f.optional && !(fieldValues[f.key] ?? "").trim());
|
|
3326
3430
|
if (fields.length > 0 && missing) {
|
|
3327
3431
|
setStep("contact");
|
|
3328
3432
|
return;
|
|
@@ -3351,7 +3455,7 @@ function RampWidget({ onClose }) {
|
|
|
3351
3455
|
const result = direction === "onramp" ? await client.createOnRamp(base) : await client.createOffRamp(base);
|
|
3352
3456
|
await applyResult(result);
|
|
3353
3457
|
} catch (e) {
|
|
3354
|
-
setErrorMsg(e
|
|
3458
|
+
setErrorMsg(rampErrorMessage(e, "Failed to start the ramp."));
|
|
3355
3459
|
setStep("error");
|
|
3356
3460
|
} finally {
|
|
3357
3461
|
setIsLoading(false);
|
|
@@ -3384,13 +3488,20 @@ function RampWidget({ onClose }) {
|
|
|
3384
3488
|
setCompleting(false);
|
|
3385
3489
|
}
|
|
3386
3490
|
}
|
|
3387
|
-
const
|
|
3388
|
-
|
|
3491
|
+
const kycBlocking = kycPending && !kycApproved;
|
|
3492
|
+
const canComplete = direction === "offramp" && step === "status" && txStatus !== "completed" && !stellarTxHash && !kycBlocking;
|
|
3493
|
+
const flowSteps = flowStepsOf(quotes, selectedQuote);
|
|
3494
|
+
const flowStepIndex = flowSteps.indexOf(STEP_LABEL[step] ?? "");
|
|
3495
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", style: overlayStyle, onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3389
3496
|
RampWidgetTemplate,
|
|
3390
3497
|
{
|
|
3391
3498
|
theme,
|
|
3392
3499
|
accentColor,
|
|
3500
|
+
styleOverrides,
|
|
3393
3501
|
step,
|
|
3502
|
+
flowSteps,
|
|
3503
|
+
flowStepIndex,
|
|
3504
|
+
startingQuoteId: isLoading && selectedQuote ? selectedQuote.quoteId : null,
|
|
3394
3505
|
direction,
|
|
3395
3506
|
amount,
|
|
3396
3507
|
currency,
|
|
@@ -3406,6 +3517,8 @@ function RampWidget({ onClose }) {
|
|
|
3406
3517
|
txStatus,
|
|
3407
3518
|
kycUrl,
|
|
3408
3519
|
tosUrl,
|
|
3520
|
+
kycBlocking,
|
|
3521
|
+
kycJustApproved: kycPending && kycApproved,
|
|
3409
3522
|
stellarTxHash,
|
|
3410
3523
|
explorerUrl: stellarTxHash ? `https://stellar.expert/explorer/${network === "mainnet" ? "public" : "testnet"}/tx/${stellarTxHash}` : null,
|
|
3411
3524
|
depositInstructions,
|
|
@@ -3413,7 +3526,10 @@ function RampWidget({ onClose }) {
|
|
|
3413
3526
|
completing,
|
|
3414
3527
|
errorMsg,
|
|
3415
3528
|
onDirectionChange: setDirection,
|
|
3416
|
-
onAmountChange:
|
|
3529
|
+
onAmountChange: (next) => {
|
|
3530
|
+
setAmount(next);
|
|
3531
|
+
setErrorMsg(null);
|
|
3532
|
+
},
|
|
3417
3533
|
onFieldChange: setFieldValue,
|
|
3418
3534
|
onCountryChange: handleCountryChange,
|
|
3419
3535
|
onFindRoute: handleFindRoute,
|
|
@@ -3422,7 +3538,8 @@ function RampWidget({ onClose }) {
|
|
|
3422
3538
|
onOpenKyc: handleOpenKyc,
|
|
3423
3539
|
onOpenTos: handleOpenTos,
|
|
3424
3540
|
onCompleteWithdraw: handleCompleteWithdraw,
|
|
3425
|
-
|
|
3541
|
+
onBack: () => resetToInput({ keepMessage: true }),
|
|
3542
|
+
onRetry: () => resetToInput(),
|
|
3426
3543
|
onRefresh: handleRefresh,
|
|
3427
3544
|
onClose
|
|
3428
3545
|
}
|
|
@@ -3479,6 +3596,7 @@ var CHAIN_NAME = {
|
|
|
3479
3596
|
function ReceiveModalTemplate({
|
|
3480
3597
|
theme,
|
|
3481
3598
|
accentColor,
|
|
3599
|
+
styleOverrides,
|
|
3482
3600
|
walletAddress,
|
|
3483
3601
|
chains,
|
|
3484
3602
|
selectedChain,
|
|
@@ -3488,23 +3606,7 @@ function ReceiveModalTemplate({
|
|
|
3488
3606
|
onClose
|
|
3489
3607
|
}) {
|
|
3490
3608
|
const isDark = theme === "dark";
|
|
3491
|
-
const cssVars =
|
|
3492
|
-
"--pollar-accent": accentColor,
|
|
3493
|
-
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
3494
|
-
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
3495
|
-
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
3496
|
-
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
3497
|
-
"--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
|
|
3498
|
-
"--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
|
|
3499
|
-
"--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
|
|
3500
|
-
"--pollar-error-text": isDark ? "#f87171" : "#dc2626",
|
|
3501
|
-
"--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
|
|
3502
|
-
"--pollar-buttons-border-radius": "6px",
|
|
3503
|
-
"--pollar-buttons-height": "44px",
|
|
3504
|
-
"--pollar-input-height": "44px",
|
|
3505
|
-
"--pollar-input-border-radius": "0.5rem",
|
|
3506
|
-
"--pollar-card-border-radius": "10px"
|
|
3507
|
-
};
|
|
3609
|
+
const cssVars = buildModalCssVars(theme, accentColor, styleOverrides);
|
|
3508
3610
|
const chainName = selectedChain ? CHAIN_NAME[selectedChain] ?? selectedChain : "wallet";
|
|
3509
3611
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3510
3612
|
"div",
|
|
@@ -3569,7 +3671,7 @@ function ReceiveModalTemplate({
|
|
|
3569
3671
|
}
|
|
3570
3672
|
function ReceiveModal({ onClose }) {
|
|
3571
3673
|
const { wallets, styles } = usePollar();
|
|
3572
|
-
const { theme
|
|
3674
|
+
const { theme, accentColor, styleOverrides, overlayStyle } = modalChrome(styles);
|
|
3573
3675
|
const [copied, setCopied] = react.useState(false);
|
|
3574
3676
|
const copyTimerRef = react.useRef(null);
|
|
3575
3677
|
const { chains } = useChains();
|
|
@@ -3595,11 +3697,12 @@ function ReceiveModal({ onClose }) {
|
|
|
3595
3697
|
}, 2e3);
|
|
3596
3698
|
});
|
|
3597
3699
|
}
|
|
3598
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3700
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", style: overlayStyle, onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3599
3701
|
ReceiveModalTemplate,
|
|
3600
3702
|
{
|
|
3601
3703
|
theme,
|
|
3602
3704
|
accentColor,
|
|
3705
|
+
styleOverrides,
|
|
3603
3706
|
walletAddress,
|
|
3604
3707
|
chains,
|
|
3605
3708
|
selectedChain,
|
|
@@ -3862,6 +3965,7 @@ function assetKey3(record) {
|
|
|
3862
3965
|
function SendModalTemplate({
|
|
3863
3966
|
theme,
|
|
3864
3967
|
accentColor,
|
|
3968
|
+
styleOverrides,
|
|
3865
3969
|
step,
|
|
3866
3970
|
txTitle,
|
|
3867
3971
|
assets,
|
|
@@ -3895,24 +3999,7 @@ function SendModalTemplate({
|
|
|
3895
3999
|
onRetry,
|
|
3896
4000
|
onDone
|
|
3897
4001
|
}) {
|
|
3898
|
-
const
|
|
3899
|
-
const cssVars = {
|
|
3900
|
-
"--pollar-accent": accentColor,
|
|
3901
|
-
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
3902
|
-
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
3903
|
-
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
3904
|
-
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
3905
|
-
"--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
|
|
3906
|
-
"--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
|
|
3907
|
-
"--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
|
|
3908
|
-
"--pollar-error-text": isDark ? "#f87171" : "#dc2626",
|
|
3909
|
-
"--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
|
|
3910
|
-
"--pollar-buttons-border-radius": "6px",
|
|
3911
|
-
"--pollar-buttons-height": "44px",
|
|
3912
|
-
"--pollar-input-height": "44px",
|
|
3913
|
-
"--pollar-input-border-radius": "0.5rem",
|
|
3914
|
-
"--pollar-card-border-radius": "10px"
|
|
3915
|
-
};
|
|
4002
|
+
const cssVars = buildModalCssVars(theme, accentColor, styleOverrides);
|
|
3916
4003
|
const selectedKey = selectedAsset ? assetKey3(selectedAsset) : "";
|
|
3917
4004
|
const canSubmit = canSendOnChain && !!selectedAsset && !!amount && !!destination.trim() && !isLoadingBalance;
|
|
3918
4005
|
const title = step === "form" ? "Send" : txTitle;
|
|
@@ -4072,7 +4159,7 @@ function SendModal({ onClose }) {
|
|
|
4072
4159
|
styles
|
|
4073
4160
|
} = usePollar();
|
|
4074
4161
|
const walletType = wallet?.custody === "external" ? wallet.provider : null;
|
|
4075
|
-
const { theme
|
|
4162
|
+
const { theme, accentColor, styleOverrides, overlayStyle } = modalChrome(styles);
|
|
4076
4163
|
const [step, setStep] = react.useState("form");
|
|
4077
4164
|
const [amount, setAmount] = react.useState("");
|
|
4078
4165
|
const [destination, setDestination] = react.useState("");
|
|
@@ -4151,6 +4238,11 @@ function SendModal({ onClose }) {
|
|
|
4151
4238
|
setFormError("Enter a destination address");
|
|
4152
4239
|
return;
|
|
4153
4240
|
}
|
|
4241
|
+
const isNativeAsset = selectedAsset.type === "native";
|
|
4242
|
+
if (isBaseUnitChain && !isNativeAsset && (!selectedAsset.issuer || selectedAsset.decimals === void 0)) {
|
|
4243
|
+
setFormError("This token is missing its mint or decimals and cannot be sent.");
|
|
4244
|
+
return;
|
|
4245
|
+
}
|
|
4154
4246
|
let sendAmount = amount;
|
|
4155
4247
|
if (isBaseUnitChain) {
|
|
4156
4248
|
try {
|
|
@@ -4166,8 +4258,9 @@ function SendModal({ onClose }) {
|
|
|
4166
4258
|
chain: "SOLANA",
|
|
4167
4259
|
destination: destination.trim(),
|
|
4168
4260
|
amount: sendAmount,
|
|
4169
|
-
// Native SOL carries no mint; an SPL token's mint rides in `issuer
|
|
4170
|
-
|
|
4261
|
+
// Native SOL carries no mint; an SPL token's mint rides in `issuer`,
|
|
4262
|
+
// which the guard above proved is present.
|
|
4263
|
+
...isNativeAsset ? {} : { mint: selectedAsset.issuer }
|
|
4171
4264
|
});
|
|
4172
4265
|
return;
|
|
4173
4266
|
}
|
|
@@ -4199,11 +4292,12 @@ function SendModal({ onClose }) {
|
|
|
4199
4292
|
setShowXdr(false);
|
|
4200
4293
|
setCopied(false);
|
|
4201
4294
|
}
|
|
4202
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: !isInProgress ? onClose : void 0, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4295
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", style: overlayStyle, onClick: !isInProgress ? onClose : void 0, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4203
4296
|
SendModalTemplate,
|
|
4204
4297
|
{
|
|
4205
4298
|
theme,
|
|
4206
4299
|
accentColor,
|
|
4300
|
+
styleOverrides,
|
|
4207
4301
|
step,
|
|
4208
4302
|
txTitle,
|
|
4209
4303
|
assets: sortedAssets,
|
|
@@ -4255,6 +4349,7 @@ function formatAmount3(value) {
|
|
|
4255
4349
|
function SwapModalTemplate({
|
|
4256
4350
|
theme,
|
|
4257
4351
|
accentColor,
|
|
4352
|
+
styleOverrides,
|
|
4258
4353
|
step,
|
|
4259
4354
|
txTitle,
|
|
4260
4355
|
sellOptions,
|
|
@@ -4294,7 +4389,6 @@ function SwapModalTemplate({
|
|
|
4294
4389
|
onRetry,
|
|
4295
4390
|
onDone
|
|
4296
4391
|
}) {
|
|
4297
|
-
const isDark = theme === "dark";
|
|
4298
4392
|
const [customOpen, setCustomOpen] = react.useState(false);
|
|
4299
4393
|
const [customCode, setCustomCode] = react.useState("");
|
|
4300
4394
|
const [customIssuer, setCustomIssuer] = react.useState("");
|
|
@@ -4310,23 +4404,7 @@ function SwapModalTemplate({
|
|
|
4310
4404
|
setCustomError("");
|
|
4311
4405
|
setCustomOpen(false);
|
|
4312
4406
|
};
|
|
4313
|
-
const cssVars =
|
|
4314
|
-
"--pollar-accent": accentColor,
|
|
4315
|
-
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
4316
|
-
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
4317
|
-
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
4318
|
-
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
4319
|
-
"--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
|
|
4320
|
-
"--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
|
|
4321
|
-
"--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
|
|
4322
|
-
"--pollar-error-text": isDark ? "#f87171" : "#dc2626",
|
|
4323
|
-
"--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
|
|
4324
|
-
"--pollar-buttons-border-radius": "6px",
|
|
4325
|
-
"--pollar-buttons-height": "44px",
|
|
4326
|
-
"--pollar-input-height": "44px",
|
|
4327
|
-
"--pollar-input-border-radius": "0.5rem",
|
|
4328
|
-
"--pollar-card-border-radius": "10px"
|
|
4329
|
-
};
|
|
4407
|
+
const cssVars = buildModalCssVars(theme, accentColor, styleOverrides);
|
|
4330
4408
|
const sellKey = selectedSell ? assetOptionKey(selectedSell) : "";
|
|
4331
4409
|
const buyKey = selectedBuy ? assetOptionKey(selectedBuy) : "";
|
|
4332
4410
|
const canSwap = !smartUnsupported && !!selectedSell && !!selectedBuy && !!amount && !!quote && !quoteLoading && !isLoadingData;
|
|
@@ -4588,7 +4666,7 @@ function SwapModal({ onClose }) {
|
|
|
4588
4666
|
} = usePollar();
|
|
4589
4667
|
const walletType = wallet?.custody === "external" ? wallet.provider : null;
|
|
4590
4668
|
const smartUnsupported = wallet?.custody === "smart";
|
|
4591
|
-
const { theme
|
|
4669
|
+
const { theme, accentColor, styleOverrides, overlayStyle } = modalChrome(styles);
|
|
4592
4670
|
const [step, setStep] = react.useState("form");
|
|
4593
4671
|
const [selectedSell, setSelectedSell] = react.useState(null);
|
|
4594
4672
|
const [selectedBuy, setSelectedBuy] = react.useState(null);
|
|
@@ -4639,7 +4717,7 @@ function SwapModal({ onClose }) {
|
|
|
4639
4717
|
const assetRecords = enabledAssets.step === "loaded" ? enabledAssets.data.assets : [];
|
|
4640
4718
|
const isLoadingData = walletBalance.step === "loading" || enabledAssets.step === "loading";
|
|
4641
4719
|
const sellOptions = balances.filter(
|
|
4642
|
-
(b) => b.
|
|
4720
|
+
(b) => (b.chain === void 0 || b.chain === "STELLAR") && (b.type === "native" || (b.type === "credit_alphanum4" || b.type === "credit_alphanum12") && !b.trustlineRemoved)
|
|
4643
4721
|
).map((b) => ({
|
|
4644
4722
|
ref: toRef(b),
|
|
4645
4723
|
code: b.code,
|
|
@@ -4793,11 +4871,12 @@ function SwapModal({ onClose }) {
|
|
|
4793
4871
|
setShowXdr(false);
|
|
4794
4872
|
setCopied(false);
|
|
4795
4873
|
}
|
|
4796
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: !isInProgress ? onClose : void 0, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4874
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", style: overlayStyle, onClick: !isInProgress ? onClose : void 0, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4797
4875
|
SwapModalTemplate,
|
|
4798
4876
|
{
|
|
4799
4877
|
theme,
|
|
4800
4878
|
accentColor,
|
|
4879
|
+
styleOverrides,
|
|
4801
4880
|
step,
|
|
4802
4881
|
txTitle,
|
|
4803
4882
|
sellOptions,
|
|
@@ -4875,8 +4954,7 @@ function EarnModal({ onClose }) {
|
|
|
4875
4954
|
} = usePollar();
|
|
4876
4955
|
const walletType = wallet?.custody === "external" ? wallet.provider : null;
|
|
4877
4956
|
const smartUnsupported = wallet?.custody === "smart";
|
|
4878
|
-
const { theme
|
|
4879
|
-
const isDark = theme === "dark";
|
|
4957
|
+
const { theme, accentColor, styleOverrides, overlayStyle } = modalChrome(styles);
|
|
4880
4958
|
const [step, setStep] = react.useState("form");
|
|
4881
4959
|
const [tab, setTab] = react.useState("deposit");
|
|
4882
4960
|
const [providers, setProviders] = react.useState(null);
|
|
@@ -4952,9 +5030,7 @@ function EarnModal({ onClose }) {
|
|
|
4952
5030
|
if (!selectedOpportunity) return null;
|
|
4953
5031
|
const balances = walletBalance.step === "loaded" ? walletBalance.data.balances : [];
|
|
4954
5032
|
const issuer = selectedOpportunity.asset.issuer;
|
|
4955
|
-
const rec = balances.find(
|
|
4956
|
-
(b) => issuer === null ? b.type === "native" : b.code === assetCode && b.issuer === issuer
|
|
4957
|
-
);
|
|
5033
|
+
const rec = balances.find((b) => issuer === null ? b.type === "native" : b.code === assetCode && b.issuer === issuer);
|
|
4958
5034
|
return rec ? rec.available : null;
|
|
4959
5035
|
})();
|
|
4960
5036
|
const depositAssetRecord = (() => {
|
|
@@ -4974,23 +5050,7 @@ function EarnModal({ onClose }) {
|
|
|
4974
5050
|
const parsedAmount = parseFloat(amount);
|
|
4975
5051
|
const exceedsAvailable = tab === "deposit" ? walletAvailable != null && parsedAmount > parseFloat(walletAvailable) : position != null && parsedAmount > parseFloat(position.withdrawable);
|
|
4976
5052
|
const canSubmit = !smartUnsupported && !!provider && !!opportunityId && !!amount && parsedAmount > 0 && !exceedsAvailable && !providersLoading && !loadingOpps;
|
|
4977
|
-
const cssVars =
|
|
4978
|
-
"--pollar-accent": accentColor,
|
|
4979
|
-
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
4980
|
-
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
4981
|
-
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
4982
|
-
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
4983
|
-
"--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
|
|
4984
|
-
"--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
|
|
4985
|
-
"--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
|
|
4986
|
-
"--pollar-error-text": isDark ? "#f87171" : "#dc2626",
|
|
4987
|
-
"--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
|
|
4988
|
-
"--pollar-buttons-border-radius": "6px",
|
|
4989
|
-
"--pollar-buttons-height": "44px",
|
|
4990
|
-
"--pollar-input-height": "44px",
|
|
4991
|
-
"--pollar-input-border-radius": "0.5rem",
|
|
4992
|
-
"--pollar-card-border-radius": "10px"
|
|
4993
|
-
};
|
|
5053
|
+
const cssVars = buildModalCssVars(theme, accentColor, styleOverrides);
|
|
4994
5054
|
async function handleSubmit() {
|
|
4995
5055
|
setFormError("");
|
|
4996
5056
|
if (smartUnsupported) {
|
|
@@ -5069,7 +5129,7 @@ function EarnModal({ onClose }) {
|
|
|
5069
5129
|
}
|
|
5070
5130
|
}
|
|
5071
5131
|
const title = step === "form" ? "Earn" : txTitle;
|
|
5072
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: !isInProgress ? onClose : void 0, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5132
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", style: overlayStyle, onClick: !isInProgress ? onClose : void 0, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5073
5133
|
"div",
|
|
5074
5134
|
{
|
|
5075
5135
|
className: "pollar-modal-card pollar-send-modal",
|
|
@@ -5317,6 +5377,7 @@ function shortIp(hash) {
|
|
|
5317
5377
|
function SessionsModalTemplate({
|
|
5318
5378
|
theme,
|
|
5319
5379
|
accentColor,
|
|
5380
|
+
styleOverrides,
|
|
5320
5381
|
state,
|
|
5321
5382
|
revokingFamilyId,
|
|
5322
5383
|
signingOutEverywhere,
|
|
@@ -5325,24 +5386,7 @@ function SessionsModalTemplate({
|
|
|
5325
5386
|
onLogoutEverywhere,
|
|
5326
5387
|
onClose
|
|
5327
5388
|
}) {
|
|
5328
|
-
const
|
|
5329
|
-
const cssVars = {
|
|
5330
|
-
"--pollar-accent": accentColor,
|
|
5331
|
-
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
5332
|
-
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
5333
|
-
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
5334
|
-
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
5335
|
-
"--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
|
|
5336
|
-
"--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
|
|
5337
|
-
"--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
|
|
5338
|
-
"--pollar-error-text": isDark ? "#f87171" : "#dc2626",
|
|
5339
|
-
"--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
|
|
5340
|
-
"--pollar-buttons-border-radius": "6px",
|
|
5341
|
-
"--pollar-buttons-height": "44px",
|
|
5342
|
-
"--pollar-input-height": "44px",
|
|
5343
|
-
"--pollar-input-border-radius": "0.5rem",
|
|
5344
|
-
"--pollar-card-border-radius": "10px"
|
|
5345
|
-
};
|
|
5389
|
+
const cssVars = buildModalCssVars(theme, accentColor, styleOverrides);
|
|
5346
5390
|
const isLoading = state.step === "loading";
|
|
5347
5391
|
const sessions = state.step === "loaded" ? state.sessions : [];
|
|
5348
5392
|
const otherCount = sessions.filter((s) => !s.current).length;
|
|
@@ -5454,7 +5498,7 @@ function SessionsModalTemplate({
|
|
|
5454
5498
|
}
|
|
5455
5499
|
function SessionsModal({ onClose }) {
|
|
5456
5500
|
const { getClient, styles, sessions } = usePollar();
|
|
5457
|
-
const { theme
|
|
5501
|
+
const { theme, accentColor, styleOverrides, overlayStyle } = modalChrome(styles);
|
|
5458
5502
|
const [revokingFamilyId, setRevokingFamilyId] = react.useState(null);
|
|
5459
5503
|
const [signingOutEverywhere, setSigningOutEverywhere] = react.useState(false);
|
|
5460
5504
|
const load = react.useCallback(() => {
|
|
@@ -5492,11 +5536,12 @@ function SessionsModal({ onClose }) {
|
|
|
5492
5536
|
setSigningOutEverywhere(false);
|
|
5493
5537
|
}
|
|
5494
5538
|
}, [getClient, onClose]);
|
|
5495
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5539
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", style: overlayStyle, onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5496
5540
|
SessionsModalTemplate,
|
|
5497
5541
|
{
|
|
5498
5542
|
theme,
|
|
5499
5543
|
accentColor,
|
|
5544
|
+
styleOverrides,
|
|
5500
5545
|
state: sessions,
|
|
5501
5546
|
revokingFamilyId,
|
|
5502
5547
|
signingOutEverywhere,
|
|
@@ -5510,6 +5555,7 @@ function SessionsModal({ onClose }) {
|
|
|
5510
5555
|
function TransactionModalTemplate({
|
|
5511
5556
|
theme,
|
|
5512
5557
|
accentColor,
|
|
5558
|
+
styleOverrides,
|
|
5513
5559
|
transaction,
|
|
5514
5560
|
showXdr,
|
|
5515
5561
|
copied,
|
|
@@ -5521,24 +5567,7 @@ function TransactionModalTemplate({
|
|
|
5521
5567
|
onCopyHash,
|
|
5522
5568
|
onRetry
|
|
5523
5569
|
}) {
|
|
5524
|
-
const
|
|
5525
|
-
const cssVars = {
|
|
5526
|
-
"--pollar-accent": accentColor,
|
|
5527
|
-
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
5528
|
-
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
5529
|
-
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
5530
|
-
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
5531
|
-
"--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
|
|
5532
|
-
"--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
|
|
5533
|
-
"--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
|
|
5534
|
-
"--pollar-error-text": isDark ? "#f87171" : "#dc2626",
|
|
5535
|
-
"--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
|
|
5536
|
-
"--pollar-buttons-border-radius": "6px",
|
|
5537
|
-
"--pollar-buttons-height": "44px",
|
|
5538
|
-
"--pollar-input-height": "44px",
|
|
5539
|
-
"--pollar-input-border-radius": "0.5rem",
|
|
5540
|
-
"--pollar-card-border-radius": "10px"
|
|
5541
|
-
};
|
|
5570
|
+
const cssVars = buildModalCssVars(theme, accentColor, styleOverrides);
|
|
5542
5571
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-card pollar-tx-modal", "data-theme": theme, style: cssVars, onClick: (e) => e.stopPropagation(), children: [
|
|
5543
5572
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-header", children: /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Transaction" }) }),
|
|
5544
5573
|
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-close-btn", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -5577,7 +5606,7 @@ function TransactionModalTemplate({
|
|
|
5577
5606
|
function TransactionModal({ onClose }) {
|
|
5578
5607
|
const { getClient, styles, tx: transaction, network, wallet } = usePollar();
|
|
5579
5608
|
const walletType = wallet?.custody === "external" ? wallet.provider : null;
|
|
5580
|
-
const { theme
|
|
5609
|
+
const { theme, accentColor, styleOverrides, overlayStyle } = modalChrome(styles);
|
|
5581
5610
|
const [showXdr, setShowXdr] = react.useState(false);
|
|
5582
5611
|
const [copied, setCopied] = react.useState(false);
|
|
5583
5612
|
const copyTimerRef = react.useRef(null);
|
|
@@ -5612,11 +5641,12 @@ function TransactionModal({ onClose }) {
|
|
|
5612
5641
|
await getClient().signAndSubmitTx(transaction.buildData.unsignedXdr);
|
|
5613
5642
|
}
|
|
5614
5643
|
}
|
|
5615
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5644
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", style: overlayStyle, onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5616
5645
|
TransactionModalTemplate,
|
|
5617
5646
|
{
|
|
5618
5647
|
theme,
|
|
5619
5648
|
accentColor,
|
|
5649
|
+
styleOverrides,
|
|
5620
5650
|
transaction,
|
|
5621
5651
|
showXdr,
|
|
5622
5652
|
copied,
|
|
@@ -5631,6 +5661,12 @@ function TransactionModal({ onClose }) {
|
|
|
5631
5661
|
) });
|
|
5632
5662
|
}
|
|
5633
5663
|
var PAGE_SIZE = 10;
|
|
5664
|
+
function explorerUrlFor(chain, hash, network) {
|
|
5665
|
+
if (chain === "SOLANA") {
|
|
5666
|
+
return `https://explorer.solana.com/tx/${hash}${network === "testnet" ? "?cluster=devnet" : ""}`;
|
|
5667
|
+
}
|
|
5668
|
+
return `https://stellar.expert/explorer/${network === "testnet" ? "testnet" : "public"}/tx/${hash}`;
|
|
5669
|
+
}
|
|
5634
5670
|
function StatusBadge({ status }) {
|
|
5635
5671
|
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-hist-item-badge", "data-status": status, children: status });
|
|
5636
5672
|
}
|
|
@@ -5667,31 +5703,19 @@ function renderSummary(summary) {
|
|
|
5667
5703
|
function TxHistoryModalTemplate({
|
|
5668
5704
|
theme,
|
|
5669
5705
|
accentColor,
|
|
5706
|
+
styleOverrides,
|
|
5670
5707
|
txHistory,
|
|
5671
5708
|
offset,
|
|
5709
|
+
chains,
|
|
5710
|
+
selectedChain,
|
|
5711
|
+
walletAddress,
|
|
5712
|
+
onSelectChain,
|
|
5672
5713
|
onRefresh,
|
|
5673
5714
|
onPrev,
|
|
5674
5715
|
onNext,
|
|
5675
5716
|
onClose
|
|
5676
5717
|
}) {
|
|
5677
|
-
const
|
|
5678
|
-
const cssVars = {
|
|
5679
|
-
"--pollar-accent": accentColor,
|
|
5680
|
-
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
5681
|
-
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
5682
|
-
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
5683
|
-
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
5684
|
-
"--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
|
|
5685
|
-
"--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
|
|
5686
|
-
"--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
|
|
5687
|
-
"--pollar-error-text": isDark ? "#f87171" : "#dc2626",
|
|
5688
|
-
"--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
|
|
5689
|
-
"--pollar-buttons-border-radius": "6px",
|
|
5690
|
-
"--pollar-buttons-height": "44px",
|
|
5691
|
-
"--pollar-input-height": "44px",
|
|
5692
|
-
"--pollar-input-border-radius": "0.5rem",
|
|
5693
|
-
"--pollar-card-border-radius": "10px"
|
|
5694
|
-
};
|
|
5718
|
+
const cssVars = buildModalCssVars(theme, accentColor, styleOverrides);
|
|
5695
5719
|
const isLoading = txHistory.step === "loading";
|
|
5696
5720
|
const records = txHistory.step === "loaded" ? txHistory.data.records : [];
|
|
5697
5721
|
const total = txHistory.step === "loaded" ? txHistory.data.total : 0;
|
|
@@ -5744,6 +5768,11 @@ function TxHistoryModalTemplate({
|
|
|
5744
5768
|
/* @__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" }) }) })
|
|
5745
5769
|
] })
|
|
5746
5770
|
] }),
|
|
5771
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChainSelect, { value: selectedChain, options: chains, onChange: onSelectChain, disabled: isLoading }),
|
|
5772
|
+
walletAddress && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-address-row", children: [
|
|
5773
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-address", children: cropAddress(walletAddress) }),
|
|
5774
|
+
/* @__PURE__ */ jsxRuntime.jsx(CopyButton, { value: walletAddress, label: "Copy wallet address" })
|
|
5775
|
+
] }),
|
|
5747
5776
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-list", children: [
|
|
5748
5777
|
txHistory.step === "idle" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "Click Refresh to load transactions." }),
|
|
5749
5778
|
isLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-loading-block", children: [
|
|
@@ -5754,7 +5783,7 @@ function TxHistoryModalTemplate({
|
|
|
5754
5783
|
txHistory.step === "loaded" && records.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No transactions yet." }),
|
|
5755
5784
|
records.map((record) => {
|
|
5756
5785
|
const hash = typeof record.hash === "string" && record.hash.length > 0 ? record.hash : void 0;
|
|
5757
|
-
const explorerUrl = hash ?
|
|
5786
|
+
const explorerUrl = hash ? explorerUrlFor(record.chain, hash, record.network) : void 0;
|
|
5758
5787
|
const asset = typeof record.details?.asset === "string" ? record.details.asset : void 0;
|
|
5759
5788
|
const colon = asset ? asset.indexOf(":") : -1;
|
|
5760
5789
|
const trustline = record.operation === "change_trust" && asset && colon > 0 ? {
|
|
@@ -5788,10 +5817,11 @@ function TxHistoryModalTemplate({
|
|
|
5788
5817
|
"\xB7 ",
|
|
5789
5818
|
record.details.sponsored ? "Sponsored" : "Self-paid"
|
|
5790
5819
|
] }),
|
|
5791
|
-
record.
|
|
5820
|
+
record.fee && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
5792
5821
|
"\xB7 ",
|
|
5793
|
-
record.
|
|
5794
|
-
"
|
|
5822
|
+
record.fee.amount,
|
|
5823
|
+
" ",
|
|
5824
|
+
record.fee.unit
|
|
5795
5825
|
] })
|
|
5796
5826
|
] }),
|
|
5797
5827
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-item-footer", children: [
|
|
@@ -5807,7 +5837,7 @@ function TxHistoryModalTemplate({
|
|
|
5807
5837
|
href: explorerUrl,
|
|
5808
5838
|
target: "_blank",
|
|
5809
5839
|
rel: "noopener noreferrer",
|
|
5810
|
-
"aria-label": "View on
|
|
5840
|
+
"aria-label": "View on block explorer",
|
|
5811
5841
|
children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "12", height: "12", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
|
|
5812
5842
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5813
5843
|
"path",
|
|
@@ -5856,29 +5886,44 @@ function TxHistoryModalTemplate({
|
|
|
5856
5886
|
}
|
|
5857
5887
|
var PAGE_SIZE2 = 10;
|
|
5858
5888
|
function TxHistoryModal({ onClose }) {
|
|
5859
|
-
const { getClient, styles, txHistory } = usePollar();
|
|
5860
|
-
const { theme
|
|
5889
|
+
const { getClient, styles, txHistory, wallets } = usePollar();
|
|
5890
|
+
const { theme, accentColor, styleOverrides, overlayStyle } = modalChrome(styles);
|
|
5861
5891
|
const [offset, setOffset] = react.useState(0);
|
|
5892
|
+
const { chains } = useChains();
|
|
5893
|
+
const [selectedChain, setSelectedChain] = react.useState(null);
|
|
5894
|
+
react.useEffect(() => {
|
|
5895
|
+
if (selectedChain === null && chains.length > 0) setSelectedChain(chains[0]);
|
|
5896
|
+
}, [chains, selectedChain]);
|
|
5897
|
+
const walletAddress = addressForChain(wallets, selectedChain);
|
|
5862
5898
|
const load = react.useCallback(
|
|
5863
|
-
(nextOffset) => {
|
|
5899
|
+
(nextOffset, chain) => {
|
|
5864
5900
|
setOffset(nextOffset);
|
|
5865
|
-
void getClient().fetchTxHistory({ limit: PAGE_SIZE2, offset: nextOffset });
|
|
5901
|
+
void getClient().fetchTxHistory({ limit: PAGE_SIZE2, offset: nextOffset, chain });
|
|
5866
5902
|
},
|
|
5867
5903
|
[getClient]
|
|
5868
5904
|
);
|
|
5869
5905
|
react.useEffect(() => {
|
|
5870
|
-
load(0);
|
|
5871
|
-
}, [load]);
|
|
5872
|
-
|
|
5906
|
+
if (selectedChain) load(0, selectedChain);
|
|
5907
|
+
}, [selectedChain, load]);
|
|
5908
|
+
const onSelectChain = (chain) => setSelectedChain(chain);
|
|
5909
|
+
const paged = (nextOffset) => {
|
|
5910
|
+
if (selectedChain) load(nextOffset, selectedChain);
|
|
5911
|
+
};
|
|
5912
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", style: overlayStyle, onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5873
5913
|
TxHistoryModalTemplate,
|
|
5874
5914
|
{
|
|
5875
5915
|
theme,
|
|
5876
5916
|
accentColor,
|
|
5917
|
+
styleOverrides,
|
|
5877
5918
|
txHistory,
|
|
5878
5919
|
offset,
|
|
5879
|
-
|
|
5880
|
-
|
|
5881
|
-
|
|
5920
|
+
chains,
|
|
5921
|
+
selectedChain,
|
|
5922
|
+
walletAddress,
|
|
5923
|
+
onSelectChain,
|
|
5924
|
+
onRefresh: () => paged(offset),
|
|
5925
|
+
onPrev: () => paged(Math.max(0, offset - PAGE_SIZE2)),
|
|
5926
|
+
onNext: () => paged(offset + PAGE_SIZE2),
|
|
5882
5927
|
onClose
|
|
5883
5928
|
}
|
|
5884
5929
|
) });
|
|
@@ -5922,6 +5967,7 @@ function BalanceItem({ record, faucet }) {
|
|
|
5922
5967
|
function WalletBalanceModalTemplate({
|
|
5923
5968
|
theme,
|
|
5924
5969
|
accentColor,
|
|
5970
|
+
styleOverrides,
|
|
5925
5971
|
walletBalance,
|
|
5926
5972
|
walletAddress,
|
|
5927
5973
|
chains,
|
|
@@ -5931,24 +5977,7 @@ function WalletBalanceModalTemplate({
|
|
|
5931
5977
|
onRefresh,
|
|
5932
5978
|
onClose
|
|
5933
5979
|
}) {
|
|
5934
|
-
const
|
|
5935
|
-
const cssVars = {
|
|
5936
|
-
"--pollar-accent": accentColor,
|
|
5937
|
-
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
5938
|
-
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
5939
|
-
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
5940
|
-
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
5941
|
-
"--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
|
|
5942
|
-
"--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
|
|
5943
|
-
"--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
|
|
5944
|
-
"--pollar-error-text": isDark ? "#f87171" : "#dc2626",
|
|
5945
|
-
"--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
|
|
5946
|
-
"--pollar-buttons-border-radius": "6px",
|
|
5947
|
-
"--pollar-buttons-height": "44px",
|
|
5948
|
-
"--pollar-input-height": "44px",
|
|
5949
|
-
"--pollar-input-border-radius": "0.5rem",
|
|
5950
|
-
"--pollar-card-border-radius": "10px"
|
|
5951
|
-
};
|
|
5980
|
+
const cssVars = buildModalCssVars(theme, accentColor, styleOverrides);
|
|
5952
5981
|
const isLoading = walletBalance.step === "loading";
|
|
5953
5982
|
const data = useStickyData(walletBalance.step === "loaded" ? walletBalance.data : null);
|
|
5954
5983
|
const balances = (data?.balances ?? []).filter((b) => resolveChain(b.chain) === selectedChain);
|
|
@@ -6022,7 +6051,7 @@ function WalletBalanceModalTemplate({
|
|
|
6022
6051
|
}
|
|
6023
6052
|
function WalletBalanceModal({ onClose }) {
|
|
6024
6053
|
const { walletBalance, refreshWalletBalance, wallets, network, styles } = usePollar();
|
|
6025
|
-
const { theme
|
|
6054
|
+
const { theme, accentColor, styleOverrides, overlayStyle } = modalChrome(styles);
|
|
6026
6055
|
const { chains } = useChains();
|
|
6027
6056
|
const [selectedChain, setSelectedChain] = react.useState(null);
|
|
6028
6057
|
react.useEffect(() => {
|
|
@@ -6032,11 +6061,12 @@ function WalletBalanceModal({ onClose }) {
|
|
|
6032
6061
|
react.useEffect(() => {
|
|
6033
6062
|
void refreshWalletBalance();
|
|
6034
6063
|
}, [refreshWalletBalance]);
|
|
6035
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6064
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", style: overlayStyle, onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6036
6065
|
WalletBalanceModalTemplate,
|
|
6037
6066
|
{
|
|
6038
6067
|
theme,
|
|
6039
6068
|
accentColor,
|
|
6069
|
+
styleOverrides,
|
|
6040
6070
|
walletBalance,
|
|
6041
6071
|
walletAddress,
|
|
6042
6072
|
chains,
|
|
@@ -6118,9 +6148,17 @@ function PollarProvider({
|
|
|
6118
6148
|
onStorageDegrade,
|
|
6119
6149
|
children
|
|
6120
6150
|
}) {
|
|
6121
|
-
const [pollarClient] = react.useState(
|
|
6122
|
-
(
|
|
6123
|
-
|
|
6151
|
+
const [pollarClient] = react.useState(() => {
|
|
6152
|
+
if (client instanceof core.PollarClient) {
|
|
6153
|
+
client.setPasskeyDefaults({ passkey: browserPasskeyCeremony, passkeySign: browserPasskeySigner });
|
|
6154
|
+
return client;
|
|
6155
|
+
}
|
|
6156
|
+
return new core.PollarClient({
|
|
6157
|
+
...client,
|
|
6158
|
+
passkey: client.passkey ?? browserPasskeyCeremony,
|
|
6159
|
+
passkeySign: client.passkeySign ?? browserPasskeySigner
|
|
6160
|
+
});
|
|
6161
|
+
});
|
|
6124
6162
|
const ownsClientRef = react.useRef(!(client instanceof core.PollarClient));
|
|
6125
6163
|
const destroyTimerRef = react.useRef(null);
|
|
6126
6164
|
react.useEffect(() => {
|
|
@@ -6147,6 +6185,9 @@ function PollarProvider({
|
|
|
6147
6185
|
);
|
|
6148
6186
|
const [configRetry, setConfigRetry] = react.useState(0);
|
|
6149
6187
|
const retryConfig = react.useCallback(() => setConfigRetry((n) => n + 1), []);
|
|
6188
|
+
const appConfigKey = appConfigProp === void 0 ? "" : JSON.stringify(appConfigProp);
|
|
6189
|
+
const appConfigPropRef = react.useRef(appConfigProp);
|
|
6190
|
+
appConfigPropRef.current = appConfigProp;
|
|
6150
6191
|
react.useEffect(() => {
|
|
6151
6192
|
return pollarClient.onTransactionStateChange(setTransaction);
|
|
6152
6193
|
}, [pollarClient]);
|
|
@@ -6210,7 +6251,9 @@ function PollarProvider({
|
|
|
6210
6251
|
setModalErrorLogger(pollarClient.getLogger());
|
|
6211
6252
|
}, [pollarClient]);
|
|
6212
6253
|
react.useEffect(() => {
|
|
6213
|
-
|
|
6254
|
+
const localConfig = appConfigPropRef.current;
|
|
6255
|
+
if (localConfig !== void 0) {
|
|
6256
|
+
setResolvedConfig(localConfig ?? DEFAULT_APP_CONFIG);
|
|
6214
6257
|
setConfigStatus("ready");
|
|
6215
6258
|
return;
|
|
6216
6259
|
}
|
|
@@ -6232,7 +6275,7 @@ function PollarProvider({
|
|
|
6232
6275
|
return () => {
|
|
6233
6276
|
cancelled = true;
|
|
6234
6277
|
};
|
|
6235
|
-
}, [pollarClient,
|
|
6278
|
+
}, [pollarClient, appConfigKey, configRetry]);
|
|
6236
6279
|
const [loginModalOpen, setLoginModalOpen] = react.useState(false);
|
|
6237
6280
|
const [transactionModalOpen, setTransactionModalOpen] = react.useState(false);
|
|
6238
6281
|
const [kycModalOpen, setKycModalOpen] = react.useState(false);
|
|
@@ -6914,8 +6957,13 @@ exports.WalletBalanceModalTemplate = WalletBalanceModalTemplate;
|
|
|
6914
6957
|
exports.WalletButton = WalletButton;
|
|
6915
6958
|
exports.WalletButtonTemplate = WalletButtonTemplate;
|
|
6916
6959
|
exports.addressForChain = addressForChain;
|
|
6960
|
+
exports.browserPasskeyCeremony = browserPasskeyCeremony;
|
|
6961
|
+
exports.browserPasskeySigner = browserPasskeySigner;
|
|
6962
|
+
exports.buildModalCssVars = buildModalCssVars;
|
|
6917
6963
|
exports.chainsOf = chainsOf;
|
|
6918
6964
|
exports.createPollarAdapterHook = createPollarAdapterHook;
|
|
6965
|
+
exports.modalChrome = modalChrome;
|
|
6966
|
+
exports.readableTextOn = readableTextOn;
|
|
6919
6967
|
exports.resolveChain = resolveChain;
|
|
6920
6968
|
exports.useChains = useChains;
|
|
6921
6969
|
exports.usePollar = usePollar;
|