@pollar/react 0.10.1-rc.0 → 0.10.1-rc.10
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 +27 -27
- package/dist/index.css +278 -182
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +73 -9
- package/dist/index.d.ts +73 -9
- package/dist/index.js +1659 -516
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1659 -517
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1035,11 +1035,53 @@ 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.10.1-rc.
|
|
1038
|
+
"0.10.1-rc.10"
|
|
1039
1039
|
] })
|
|
1040
1040
|
] })
|
|
1041
1041
|
] });
|
|
1042
1042
|
};
|
|
1043
|
+
function CopyButton({ value, label = "Copy", className }) {
|
|
1044
|
+
const [copied, setCopied] = react.useState(false);
|
|
1045
|
+
const timerRef = react.useRef(null);
|
|
1046
|
+
react.useEffect(() => {
|
|
1047
|
+
return () => {
|
|
1048
|
+
if (timerRef.current !== null) clearTimeout(timerRef.current);
|
|
1049
|
+
};
|
|
1050
|
+
}, []);
|
|
1051
|
+
function handleCopy(e) {
|
|
1052
|
+
e.stopPropagation();
|
|
1053
|
+
if (!value || !navigator.clipboard) return;
|
|
1054
|
+
void navigator.clipboard.writeText(value).then(() => {
|
|
1055
|
+
setCopied(true);
|
|
1056
|
+
if (timerRef.current !== null) clearTimeout(timerRef.current);
|
|
1057
|
+
timerRef.current = setTimeout(() => {
|
|
1058
|
+
setCopied(false);
|
|
1059
|
+
timerRef.current = null;
|
|
1060
|
+
}, 1500);
|
|
1061
|
+
});
|
|
1062
|
+
}
|
|
1063
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1064
|
+
"button",
|
|
1065
|
+
{
|
|
1066
|
+
type: "button",
|
|
1067
|
+
className: `pollar-copy-btn${className ? ` ${className}` : ""}`,
|
|
1068
|
+
onClick: handleCopy,
|
|
1069
|
+
"aria-label": copied ? "Copied" : label,
|
|
1070
|
+
children: copied ? /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "13", height: "13", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3.5 7l2.5 2.5 4.5-5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) : /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
|
|
1071
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1.5", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
1072
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1073
|
+
"path",
|
|
1074
|
+
{
|
|
1075
|
+
d: "M3 9H2a1 1 0 01-1-1V2a1 1 0 011-1h6a1 1 0 011 1v1",
|
|
1076
|
+
stroke: "currentColor",
|
|
1077
|
+
strokeWidth: "1.5",
|
|
1078
|
+
strokeLinecap: "round"
|
|
1079
|
+
}
|
|
1080
|
+
)
|
|
1081
|
+
] })
|
|
1082
|
+
}
|
|
1083
|
+
);
|
|
1084
|
+
}
|
|
1043
1085
|
function ModalStatusBanner({ message, status, onCancel, onRetry }) {
|
|
1044
1086
|
if (!message && status === "NONE") {
|
|
1045
1087
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-status" });
|
|
@@ -1118,7 +1160,10 @@ function RuleCard({
|
|
|
1118
1160
|
validity
|
|
1119
1161
|
] })
|
|
1120
1162
|
] }),
|
|
1121
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-dist-item-action", children: isClaimed ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-dist-item-status", "data-kind": "claimed", children: "Claimed" }) : effectivelyClaimable ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-primary pollar-dist-claim-btn", onClick: onClaim, disabled: isClaiming, children: isClaiming ?
|
|
1163
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-dist-item-action", children: isClaimed ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-dist-item-status", "data-kind": "claimed", children: "Claimed" }) : effectivelyClaimable ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-primary pollar-dist-claim-btn", onClick: onClaim, disabled: isClaiming, children: isClaiming ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1164
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-spinner pollar-spinner-sm" }),
|
|
1165
|
+
"Claiming\u2026"
|
|
1166
|
+
] }) : "Claim" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-dist-item-status", "data-kind": "unavailable", children: reasonLabel(rule.reason) }) }),
|
|
1122
1167
|
errorMessage && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-dist-item-error", children: errorMessage })
|
|
1123
1168
|
] });
|
|
1124
1169
|
}
|
|
@@ -1164,29 +1209,46 @@ function DistributionRulesModalTemplate({
|
|
|
1164
1209
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
|
|
1165
1210
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Distribution Rules" }),
|
|
1166
1211
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
|
|
1167
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1212
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1213
|
+
"button",
|
|
1214
|
+
{
|
|
1215
|
+
type: "button",
|
|
1216
|
+
className: "pollar-modal-close",
|
|
1217
|
+
onClick: onRefresh,
|
|
1218
|
+
disabled: isLoading,
|
|
1219
|
+
"aria-label": "Refresh",
|
|
1220
|
+
title: "Refresh",
|
|
1221
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1222
|
+
"svg",
|
|
1223
|
+
{
|
|
1224
|
+
className: isLoading ? "pollar-modal-refresh-icon pollar-spinning" : "pollar-modal-refresh-icon",
|
|
1225
|
+
width: "16",
|
|
1226
|
+
height: "16",
|
|
1227
|
+
viewBox: "0 0 16 16",
|
|
1228
|
+
fill: "none",
|
|
1229
|
+
"aria-hidden": true,
|
|
1230
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1231
|
+
"path",
|
|
1232
|
+
{
|
|
1233
|
+
d: "M13.5 8a5.5 5.5 0 1 1-1.6-3.9M13.5 2v3h-3",
|
|
1234
|
+
stroke: "currentColor",
|
|
1235
|
+
strokeWidth: "1.6",
|
|
1236
|
+
strokeLinecap: "round",
|
|
1237
|
+
strokeLinejoin: "round"
|
|
1238
|
+
}
|
|
1239
|
+
)
|
|
1240
|
+
}
|
|
1241
|
+
)
|
|
1242
|
+
}
|
|
1243
|
+
),
|
|
1185
1244
|
/* @__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" }) }) })
|
|
1186
1245
|
] })
|
|
1187
1246
|
] }),
|
|
1188
1247
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-dist-list", children: [
|
|
1189
|
-
isLoading && /* @__PURE__ */ jsxRuntime.
|
|
1248
|
+
isLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-loading-block", children: [
|
|
1249
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-spinner" }),
|
|
1250
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Loading\u2026" })
|
|
1251
|
+
] }),
|
|
1190
1252
|
state.step === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: state.message }),
|
|
1191
1253
|
state.step === "loaded" && rules.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No distribution rules available." }),
|
|
1192
1254
|
rules.map((rule) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1311,14 +1373,14 @@ function AssetItem({
|
|
|
1311
1373
|
!isNative && record.enabledInApp && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-asset-sponsor", children: record.sponsored ? "Reserve sponsored by the app" : "You pay the reserve (~0.5 XLM)" })
|
|
1312
1374
|
] }),
|
|
1313
1375
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-asset-actions", children: [
|
|
1314
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `pollar-asset-trustline${established ? " established" : ""}`, children: established ? "Trustline active" : "Needs trustline" }),
|
|
1376
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `pollar-asset-trustline${established ? " pollar-established" : ""}`, children: established ? "Trustline active" : "Needs trustline" }),
|
|
1315
1377
|
!isNative && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1316
1378
|
"button",
|
|
1317
1379
|
{
|
|
1318
|
-
className: `pollar-asset-btn${established ? " danger" : ""}`,
|
|
1380
|
+
className: `pollar-asset-btn${established ? " pollar-danger" : ""}`,
|
|
1319
1381
|
onClick: () => onToggle(record),
|
|
1320
1382
|
disabled: busy || disabled,
|
|
1321
|
-
children: busy ? "
|
|
1383
|
+
children: busy ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-spinner pollar-spinner-sm pollar-spinner-current" }) : established ? "Disable" : "Enable"
|
|
1322
1384
|
}
|
|
1323
1385
|
)
|
|
1324
1386
|
] })
|
|
@@ -1351,29 +1413,46 @@ function EnabledAssetsModalTemplate({
|
|
|
1351
1413
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
|
|
1352
1414
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Trustlines" }),
|
|
1353
1415
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
|
|
1354
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1416
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1417
|
+
"button",
|
|
1418
|
+
{
|
|
1419
|
+
type: "button",
|
|
1420
|
+
className: "pollar-modal-close",
|
|
1421
|
+
onClick: onRefresh,
|
|
1422
|
+
disabled: isLoading || busy,
|
|
1423
|
+
"aria-label": "Refresh",
|
|
1424
|
+
title: "Refresh",
|
|
1425
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1426
|
+
"svg",
|
|
1427
|
+
{
|
|
1428
|
+
className: isLoading ? "pollar-modal-refresh-icon pollar-spinning" : "pollar-modal-refresh-icon",
|
|
1429
|
+
width: "16",
|
|
1430
|
+
height: "16",
|
|
1431
|
+
viewBox: "0 0 16 16",
|
|
1432
|
+
fill: "none",
|
|
1433
|
+
"aria-hidden": true,
|
|
1434
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1435
|
+
"path",
|
|
1436
|
+
{
|
|
1437
|
+
d: "M13.5 8a5.5 5.5 0 1 1-1.6-3.9M13.5 2v3h-3",
|
|
1438
|
+
stroke: "currentColor",
|
|
1439
|
+
strokeWidth: "1.6",
|
|
1440
|
+
strokeLinecap: "round",
|
|
1441
|
+
strokeLinejoin: "round"
|
|
1442
|
+
}
|
|
1443
|
+
)
|
|
1444
|
+
}
|
|
1445
|
+
)
|
|
1446
|
+
}
|
|
1447
|
+
),
|
|
1372
1448
|
/* @__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" }) }) })
|
|
1373
1449
|
] })
|
|
1374
1450
|
] }),
|
|
1375
1451
|
walletAddress && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-asset-address", children: cropAddress(walletAddress) }),
|
|
1376
|
-
isLoading && /* @__PURE__ */ jsxRuntime.
|
|
1452
|
+
isLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-loading-block", children: [
|
|
1453
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-spinner" }),
|
|
1454
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Loading\u2026" })
|
|
1455
|
+
] }),
|
|
1377
1456
|
enabledAssets.step === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: enabledAssets.message }),
|
|
1378
1457
|
actionError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-action-error", children: actionError }),
|
|
1379
1458
|
data && !data.exists && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-empty", children: [
|
|
@@ -1432,7 +1511,7 @@ function CustomTrustlineModalTemplate({
|
|
|
1432
1511
|
children: [
|
|
1433
1512
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
|
|
1434
1513
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
|
|
1435
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-modal-
|
|
1514
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-modal-close", onClick: onBack, disabled: busy, "aria-label": "Back", 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: "M10 3L5 8l5 5", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }),
|
|
1436
1515
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Add custom trustline" })
|
|
1437
1516
|
] }),
|
|
1438
1517
|
/* @__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" }) }) })
|
|
@@ -1493,7 +1572,10 @@ function CustomTrustlineModalTemplate({
|
|
|
1493
1572
|
)
|
|
1494
1573
|
] }),
|
|
1495
1574
|
actionError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-action-error", children: actionError }),
|
|
1496
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-
|
|
1575
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-actions", children: /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-primary", onClick: submit, disabled: !canSubmit, children: busy ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1576
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-spinner pollar-spinner-sm" }),
|
|
1577
|
+
"Enabling\u2026"
|
|
1578
|
+
] }) : "Enable trustline" }) }),
|
|
1497
1579
|
/* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
|
|
1498
1580
|
]
|
|
1499
1581
|
}
|
|
@@ -1614,6 +1696,7 @@ function KycModalTemplate({
|
|
|
1614
1696
|
isLoading,
|
|
1615
1697
|
onSelectProvider,
|
|
1616
1698
|
onDoneVerifying,
|
|
1699
|
+
onRefresh,
|
|
1617
1700
|
onClose
|
|
1618
1701
|
}) {
|
|
1619
1702
|
const isDark = theme === "dark";
|
|
@@ -1638,16 +1721,56 @@ function KycModalTemplate({
|
|
|
1638
1721
|
"--pollar-modal-subtitle-size": "0.9rem"
|
|
1639
1722
|
};
|
|
1640
1723
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-card pollar-kyc-modal", style: cssVars, onClick: (e) => e.stopPropagation(), children: [
|
|
1641
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-
|
|
1642
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1724
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
|
|
1725
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-kyc-header-text", children: [
|
|
1726
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Identity verification" }),
|
|
1727
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "pollar-kyc-subtitle", children: [
|
|
1728
|
+
step === "select_provider" && "Choose your verification provider",
|
|
1729
|
+
step === "verifying" && `Verifying with ${selectedProvider?.name}`,
|
|
1730
|
+
step === "polling" && "Waiting for verification result",
|
|
1731
|
+
step === "done" && "Verification complete"
|
|
1732
|
+
] })
|
|
1733
|
+
] }),
|
|
1734
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
|
|
1735
|
+
step === "select_provider" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1736
|
+
"button",
|
|
1737
|
+
{
|
|
1738
|
+
type: "button",
|
|
1739
|
+
className: "pollar-modal-close",
|
|
1740
|
+
onClick: onRefresh,
|
|
1741
|
+
disabled: isLoading,
|
|
1742
|
+
"aria-label": "Refresh",
|
|
1743
|
+
title: "Refresh providers",
|
|
1744
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1745
|
+
"svg",
|
|
1746
|
+
{
|
|
1747
|
+
className: isLoading ? "pollar-modal-refresh-icon pollar-spinning" : "pollar-modal-refresh-icon",
|
|
1748
|
+
width: "16",
|
|
1749
|
+
height: "16",
|
|
1750
|
+
viewBox: "0 0 16 16",
|
|
1751
|
+
fill: "none",
|
|
1752
|
+
"aria-hidden": true,
|
|
1753
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1754
|
+
"path",
|
|
1755
|
+
{
|
|
1756
|
+
d: "M13.5 8a5.5 5.5 0 1 1-1.6-3.9M13.5 2v3h-3",
|
|
1757
|
+
stroke: "currentColor",
|
|
1758
|
+
strokeWidth: "1.6",
|
|
1759
|
+
strokeLinecap: "round",
|
|
1760
|
+
strokeLinejoin: "round"
|
|
1761
|
+
}
|
|
1762
|
+
)
|
|
1763
|
+
}
|
|
1764
|
+
)
|
|
1765
|
+
}
|
|
1766
|
+
),
|
|
1767
|
+
/* @__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" }) }) })
|
|
1648
1768
|
] })
|
|
1649
1769
|
] }),
|
|
1650
|
-
step === "select_provider" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-
|
|
1770
|
+
step === "select_provider" && (isLoading && providers.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-loading-block", children: [
|
|
1771
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-spinner" }),
|
|
1772
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Loading providers\u2026" })
|
|
1773
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-kyc-providers", children: [
|
|
1651
1774
|
providers.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { color: "var(--pollar-muted)", textAlign: "center" }, children: "No providers available for your country." }),
|
|
1652
1775
|
providers.map((p) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1653
1776
|
"button",
|
|
@@ -1663,7 +1786,7 @@ function KycModalTemplate({
|
|
|
1663
1786
|
},
|
|
1664
1787
|
p.id
|
|
1665
1788
|
))
|
|
1666
|
-
] }),
|
|
1789
|
+
] })),
|
|
1667
1790
|
step === "verifying" && selectedProvider && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1668
1791
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-kyc-iframe-wrap", children: session?.kycUrl ? /* @__PURE__ */ jsxRuntime.jsx("iframe", { className: "pollar-kyc-iframe", src: session.kycUrl, title: "KYC verification", allow: "camera; microphone" }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-kyc-iframe-mock", children: [
|
|
1669
1792
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u{1F512}" }),
|
|
@@ -1696,10 +1819,13 @@ function KycModal({ onClose, country = "MX", level = "basic", onApproved }) {
|
|
|
1696
1819
|
const [isLoading, setIsLoading] = react.useState(false);
|
|
1697
1820
|
const client = getClient();
|
|
1698
1821
|
const { theme = "light", accentColor = "#005DB4" } = styles;
|
|
1699
|
-
react.
|
|
1822
|
+
const loadProviders = react.useCallback(() => {
|
|
1700
1823
|
setIsLoading(true);
|
|
1701
|
-
getClient().getKycProviders(country).then((result) => setProviders(result.providers)).catch(() => setProviders([])).finally(() => setIsLoading(false));
|
|
1824
|
+
return getClient().getKycProviders(country).then((result) => setProviders(result.providers)).catch(() => setProviders([])).finally(() => setIsLoading(false));
|
|
1702
1825
|
}, [getClient, country]);
|
|
1826
|
+
react.useEffect(() => {
|
|
1827
|
+
void loadProviders();
|
|
1828
|
+
}, [loadProviders]);
|
|
1703
1829
|
async function handleSelectProvider(provider) {
|
|
1704
1830
|
setSelectedProvider(provider);
|
|
1705
1831
|
setIsLoading(true);
|
|
@@ -1745,6 +1871,7 @@ function KycModal({ onClose, country = "MX", level = "basic", onApproved }) {
|
|
|
1745
1871
|
isLoading,
|
|
1746
1872
|
onSelectProvider: handleSelectProvider,
|
|
1747
1873
|
onDoneVerifying: handleDoneVerifying,
|
|
1874
|
+
onRefresh: () => void loadProviders(),
|
|
1748
1875
|
onClose
|
|
1749
1876
|
}
|
|
1750
1877
|
) });
|
|
@@ -1800,8 +1927,8 @@ function EmailCodeInput({ email, onSubmit }) {
|
|
|
1800
1927
|
] });
|
|
1801
1928
|
}
|
|
1802
1929
|
var GithubButton = ({ disabled, onClick }) => {
|
|
1803
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "github-button", disabled, onClick, children: [
|
|
1804
|
-
/* @__PURE__ */ jsxRuntime.jsx("svg", { className: "github-button-icon", viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1930
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-github-button", disabled, onClick, children: [
|
|
1931
|
+
/* @__PURE__ */ jsxRuntime.jsx("svg", { className: "pollar-github-button-icon", viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1805
1932
|
"path",
|
|
1806
1933
|
{
|
|
1807
1934
|
fillRule: "evenodd",
|
|
@@ -1809,14 +1936,14 @@ var GithubButton = ({ disabled, onClick }) => {
|
|
|
1809
1936
|
clipRule: "evenodd"
|
|
1810
1937
|
}
|
|
1811
1938
|
) }),
|
|
1812
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "github-button-contents", children: "GitHub" })
|
|
1939
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-github-button-contents", children: "GitHub" })
|
|
1813
1940
|
] });
|
|
1814
1941
|
};
|
|
1815
1942
|
var GoogleButton = ({ disabled, onClick }) => {
|
|
1816
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "gsi-material-button", disabled, onClick, children: [
|
|
1817
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "gsi-material-button-state" }),
|
|
1818
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "gsi-material-button-content-wrapper", children: [
|
|
1819
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "gsi-material-button-icon", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { version: "1.1", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 48 48", style: { display: "block" }, children: [
|
|
1943
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-gsi-material-button", disabled, onClick, children: [
|
|
1944
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-gsi-material-button-state" }),
|
|
1945
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-gsi-material-button-content-wrapper", children: [
|
|
1946
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-gsi-material-button-icon", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { version: "1.1", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 48 48", style: { display: "block" }, children: [
|
|
1820
1947
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1821
1948
|
"path",
|
|
1822
1949
|
{
|
|
@@ -1847,7 +1974,7 @@ var GoogleButton = ({ disabled, onClick }) => {
|
|
|
1847
1974
|
),
|
|
1848
1975
|
/* @__PURE__ */ jsxRuntime.jsx("path", { fill: "none", d: "M0 0h48v48H0z" })
|
|
1849
1976
|
] }) }),
|
|
1850
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "gsi-material-button-contents", children: "Google" }),
|
|
1977
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-gsi-material-button-contents", children: "Google" }),
|
|
1851
1978
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { display: "none" }, children: "Google" })
|
|
1852
1979
|
] })
|
|
1853
1980
|
] });
|
|
@@ -2053,7 +2180,7 @@ function LoginModalTemplate({
|
|
|
2053
2180
|
placeholder: "you@email.com",
|
|
2054
2181
|
value: email,
|
|
2055
2182
|
disabled: isLoading,
|
|
2056
|
-
className: "pollar-
|
|
2183
|
+
className: "pollar-input",
|
|
2057
2184
|
onChange: (e) => onEmailChange?.(e.target.value),
|
|
2058
2185
|
onKeyDown: (e) => e.key === "Enter" && onEmailSubmit?.()
|
|
2059
2186
|
}
|
|
@@ -2232,12 +2359,38 @@ function PrivyLoginSubmodal({
|
|
|
2232
2359
|
fail(error);
|
|
2233
2360
|
}
|
|
2234
2361
|
}
|
|
2235
|
-
const BackButton = ({ onClick }) => /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-back-btn", onClick, "aria-label": "Back", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2362
|
+
const BackButton = ({ onClick }) => /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-back-btn", onClick, "aria-label": "Back", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2363
|
+
"svg",
|
|
2364
|
+
{
|
|
2365
|
+
width: "20",
|
|
2366
|
+
height: "20",
|
|
2367
|
+
viewBox: "0 0 24 24",
|
|
2368
|
+
fill: "none",
|
|
2369
|
+
stroke: "currentColor",
|
|
2370
|
+
strokeWidth: "2.5",
|
|
2371
|
+
strokeLinecap: "round",
|
|
2372
|
+
strokeLinejoin: "round",
|
|
2373
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15 19l-7-7 7-7" })
|
|
2374
|
+
}
|
|
2375
|
+
) });
|
|
2236
2376
|
const showEmail = options.includes("email");
|
|
2237
2377
|
const showGoogle = options.includes("google");
|
|
2238
2378
|
const showGithub = options.includes("github");
|
|
2239
2379
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-card pollar-modal", style: cssVars, onClick: (e) => e.stopPropagation(), children: [
|
|
2240
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-close-btn", onClick: onCancel, "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2380
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-close-btn", onClick: onCancel, "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2381
|
+
"svg",
|
|
2382
|
+
{
|
|
2383
|
+
width: "18",
|
|
2384
|
+
height: "18",
|
|
2385
|
+
viewBox: "0 0 24 24",
|
|
2386
|
+
fill: "none",
|
|
2387
|
+
stroke: "currentColor",
|
|
2388
|
+
strokeWidth: "2.5",
|
|
2389
|
+
strokeLinecap: "round",
|
|
2390
|
+
strokeLinejoin: "round",
|
|
2391
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6L6 18M6 6l12 12" })
|
|
2392
|
+
}
|
|
2393
|
+
) }),
|
|
2241
2394
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-header", children: [
|
|
2242
2395
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-logo-wrap", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: logoUrl ?? LOGO_POLLAR, alt: "Logo", className: "pollar-logo" }) }),
|
|
2243
2396
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-title", children: appName }),
|
|
@@ -2256,7 +2409,7 @@ function PrivyLoginSubmodal({
|
|
|
2256
2409
|
placeholder: "you@email.com",
|
|
2257
2410
|
value: email,
|
|
2258
2411
|
disabled: isLoading,
|
|
2259
|
-
className: "pollar-
|
|
2412
|
+
className: "pollar-input",
|
|
2260
2413
|
onChange: (e) => setEmail(e.target.value),
|
|
2261
2414
|
onKeyDown: (e) => e.key === "Enter" && handleEmailSubmit()
|
|
2262
2415
|
}
|
|
@@ -2458,21 +2611,63 @@ function RouteDisplay({ quote, onSelect }) {
|
|
|
2458
2611
|
}
|
|
2459
2612
|
);
|
|
2460
2613
|
}
|
|
2614
|
+
var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2615
|
+
function isFieldValid(spec, raw) {
|
|
2616
|
+
const value = (raw ?? "").trim();
|
|
2617
|
+
if (!value) return false;
|
|
2618
|
+
if (spec.type === "email") return EMAIL_RE.test(value);
|
|
2619
|
+
return true;
|
|
2620
|
+
}
|
|
2461
2621
|
var LOADING_STEPS = ["Detecting your country\u2026", "Consulting providers\u2026", "Route found!"];
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
AR: "ARS"
|
|
2469
|
-
};
|
|
2622
|
+
function flagEmoji(code) {
|
|
2623
|
+
const cc = code.trim().toUpperCase();
|
|
2624
|
+
if (!/^[A-Z]{2}$/.test(cc)) return "";
|
|
2625
|
+
const base = 127462;
|
|
2626
|
+
return String.fromCodePoint(base + (cc.charCodeAt(0) - 65), base + (cc.charCodeAt(1) - 65));
|
|
2627
|
+
}
|
|
2470
2628
|
var STATUS_LABEL = {
|
|
2471
2629
|
pending: "Pending",
|
|
2472
2630
|
processing: "Processing",
|
|
2473
2631
|
completed: "Completed",
|
|
2474
2632
|
failed: "Failed"
|
|
2475
2633
|
};
|
|
2634
|
+
var INSTRUCTION_LABELS = {
|
|
2635
|
+
br_code: "Pix code",
|
|
2636
|
+
account_holder_name: "Account holder",
|
|
2637
|
+
bank_name: "Bank",
|
|
2638
|
+
bank_address: "Bank address",
|
|
2639
|
+
bank_account_number: "Account number",
|
|
2640
|
+
bank_routing_number: "Routing number",
|
|
2641
|
+
iban: "IBAN",
|
|
2642
|
+
bic: "BIC",
|
|
2643
|
+
clabe: "CLABE",
|
|
2644
|
+
amount: "Amount",
|
|
2645
|
+
currency: "Currency",
|
|
2646
|
+
payment_rails: "Rails"
|
|
2647
|
+
};
|
|
2648
|
+
function flattenInstructions(instr) {
|
|
2649
|
+
const out = [];
|
|
2650
|
+
for (const [k, v] of Object.entries(instr)) {
|
|
2651
|
+
if (k === "qrBase64") {
|
|
2652
|
+
if (typeof v === "string" && v) out.push({ key: k, label: INSTRUCTION_LABELS[k] ?? "Payment QR", value: v, kind: "qr" });
|
|
2653
|
+
continue;
|
|
2654
|
+
}
|
|
2655
|
+
if ((k === "expiresAt" || k === "expires_at") && (typeof v === "number" || typeof v === "string")) {
|
|
2656
|
+
const ms = Number(v);
|
|
2657
|
+
if (Number.isFinite(ms) && ms > 0) {
|
|
2658
|
+
out.push({ key: k, label: INSTRUCTION_LABELS[k] ?? "Expires", value: new Date(ms).toLocaleString(), kind: "datetime" });
|
|
2659
|
+
}
|
|
2660
|
+
continue;
|
|
2661
|
+
}
|
|
2662
|
+
let value;
|
|
2663
|
+
if (typeof v === "string" || typeof v === "number") value = String(v);
|
|
2664
|
+
else if (Array.isArray(v)) value = v.filter((x) => typeof x === "string" || typeof x === "number").join(", ");
|
|
2665
|
+
else continue;
|
|
2666
|
+
if (!value) continue;
|
|
2667
|
+
out.push({ key: k, label: INSTRUCTION_LABELS[k] ?? k, value, kind: "text" });
|
|
2668
|
+
}
|
|
2669
|
+
return out;
|
|
2670
|
+
}
|
|
2476
2671
|
function RampWidgetTemplate({
|
|
2477
2672
|
theme,
|
|
2478
2673
|
accentColor,
|
|
@@ -2481,24 +2676,35 @@ function RampWidgetTemplate({
|
|
|
2481
2676
|
amount,
|
|
2482
2677
|
currency,
|
|
2483
2678
|
country,
|
|
2679
|
+
requiredFields,
|
|
2680
|
+
fieldValues,
|
|
2681
|
+
countries,
|
|
2682
|
+
countriesLoading,
|
|
2683
|
+
refreshing,
|
|
2484
2684
|
quotes,
|
|
2485
2685
|
isLoading,
|
|
2486
2686
|
provider,
|
|
2487
2687
|
txStatus,
|
|
2488
2688
|
kycUrl,
|
|
2689
|
+
tosUrl,
|
|
2489
2690
|
stellarTxHash,
|
|
2691
|
+
explorerUrl,
|
|
2692
|
+
depositInstructions,
|
|
2490
2693
|
canComplete,
|
|
2491
2694
|
completing,
|
|
2492
2695
|
errorMsg,
|
|
2493
2696
|
onDirectionChange,
|
|
2494
2697
|
onAmountChange,
|
|
2495
|
-
|
|
2698
|
+
onFieldChange,
|
|
2496
2699
|
onCountryChange,
|
|
2497
2700
|
onFindRoute,
|
|
2498
2701
|
onSelectQuote,
|
|
2702
|
+
onContactContinue,
|
|
2499
2703
|
onOpenKyc,
|
|
2704
|
+
onOpenTos,
|
|
2500
2705
|
onCompleteWithdraw,
|
|
2501
2706
|
onRetry,
|
|
2707
|
+
onRefresh,
|
|
2502
2708
|
onClose
|
|
2503
2709
|
}) {
|
|
2504
2710
|
const isDark = theme === "dark";
|
|
@@ -2526,6 +2732,7 @@ function RampWidgetTemplate({
|
|
|
2526
2732
|
input: direction === "onramp" ? "Buy crypto" : "Sell crypto",
|
|
2527
2733
|
loading_quote: "Finding best route",
|
|
2528
2734
|
select_route: "Select provider",
|
|
2735
|
+
contact: "Your details",
|
|
2529
2736
|
status: direction === "onramp" ? "Complete your deposit" : "Complete your withdrawal",
|
|
2530
2737
|
error: "Something went wrong"
|
|
2531
2738
|
};
|
|
@@ -2533,21 +2740,48 @@ function RampWidgetTemplate({
|
|
|
2533
2740
|
input: direction === "onramp" ? "Enter the amount you want to deposit" : "Enter the amount you want to withdraw",
|
|
2534
2741
|
loading_quote: "Comparing providers in real time\u2026",
|
|
2535
2742
|
select_route: "All prices include fees",
|
|
2743
|
+
contact: `${provider || "This provider"} needs your name and email to verify you`,
|
|
2536
2744
|
status: `Finish the flow at ${provider || "the provider"} to continue`,
|
|
2537
2745
|
error: "Please try again"
|
|
2538
2746
|
};
|
|
2539
2747
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-card pollar-ramp-modal", style: cssVars, onClick: (e) => e.stopPropagation(), children: [
|
|
2540
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-
|
|
2541
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2542
|
-
|
|
2748
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
|
|
2749
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-header-text", children: [
|
|
2750
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: stepTitle[step] }),
|
|
2751
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "pollar-ramp-subtitle", children: stepSubtitle[step] })
|
|
2752
|
+
] }),
|
|
2753
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
|
|
2754
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-modal-close", onClick: onRefresh, disabled: refreshing, "aria-label": "Refresh", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2755
|
+
"svg",
|
|
2756
|
+
{
|
|
2757
|
+
className: refreshing ? "pollar-modal-refresh-icon pollar-spinning" : "pollar-modal-refresh-icon",
|
|
2758
|
+
width: "16",
|
|
2759
|
+
height: "16",
|
|
2760
|
+
viewBox: "0 0 16 16",
|
|
2761
|
+
fill: "none",
|
|
2762
|
+
"aria-hidden": true,
|
|
2763
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2764
|
+
"path",
|
|
2765
|
+
{
|
|
2766
|
+
d: "M13.5 8a5.5 5.5 0 1 1-1.6-3.9M13.5 2v3h-3",
|
|
2767
|
+
stroke: "currentColor",
|
|
2768
|
+
strokeWidth: "1.6",
|
|
2769
|
+
strokeLinecap: "round",
|
|
2770
|
+
strokeLinejoin: "round"
|
|
2771
|
+
}
|
|
2772
|
+
)
|
|
2773
|
+
}
|
|
2774
|
+
) }),
|
|
2775
|
+
/* @__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" }) }) })
|
|
2776
|
+
] })
|
|
2543
2777
|
] }),
|
|
2544
2778
|
step === "input" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2545
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-
|
|
2779
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tabs", children: [
|
|
2546
2780
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2547
2781
|
"button",
|
|
2548
2782
|
{
|
|
2549
2783
|
type: "button",
|
|
2550
|
-
className: "pollar-
|
|
2784
|
+
className: "pollar-tab",
|
|
2551
2785
|
"data-active": direction === "onramp",
|
|
2552
2786
|
onClick: () => onDirectionChange("onramp"),
|
|
2553
2787
|
children: "Buy"
|
|
@@ -2557,79 +2791,110 @@ function RampWidgetTemplate({
|
|
|
2557
2791
|
"button",
|
|
2558
2792
|
{
|
|
2559
2793
|
type: "button",
|
|
2560
|
-
className: "pollar-
|
|
2794
|
+
className: "pollar-tab",
|
|
2561
2795
|
"data-active": direction === "offramp",
|
|
2562
2796
|
onClick: () => onDirectionChange("offramp"),
|
|
2563
2797
|
children: "Sell"
|
|
2564
2798
|
}
|
|
2565
2799
|
)
|
|
2566
2800
|
] }),
|
|
2567
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-input-row", children: [
|
|
2568
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-field", children: [
|
|
2569
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "pollar-ramp-label", children: "Amount" }),
|
|
2570
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2571
|
-
"input",
|
|
2572
|
-
{
|
|
2573
|
-
type: "number",
|
|
2574
|
-
className: "pollar-ramp-input",
|
|
2575
|
-
placeholder: "0.00",
|
|
2576
|
-
value: amount,
|
|
2577
|
-
min: "0",
|
|
2578
|
-
onChange: (e) => onAmountChange(e.target.value)
|
|
2579
|
-
}
|
|
2580
|
-
)
|
|
2581
|
-
] }),
|
|
2582
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-field", style: { maxWidth: 90 }, children: [
|
|
2583
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "pollar-ramp-label", children: "Currency" }),
|
|
2584
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2585
|
-
"input",
|
|
2586
|
-
{
|
|
2587
|
-
type: "text",
|
|
2588
|
-
className: "pollar-ramp-input",
|
|
2589
|
-
placeholder: "MXN",
|
|
2590
|
-
value: currency,
|
|
2591
|
-
maxLength: 5,
|
|
2592
|
-
onChange: (e) => onCurrencyChange(e.target.value.toUpperCase())
|
|
2593
|
-
}
|
|
2594
|
-
)
|
|
2595
|
-
] })
|
|
2596
|
-
] }),
|
|
2597
2801
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-field", children: [
|
|
2598
2802
|
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "pollar-ramp-label", children: "Country" }),
|
|
2599
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2600
|
-
"
|
|
2803
|
+
countriesLoading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-input pollar-ramp-input-loading", children: [
|
|
2804
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-spinner pollar-spinner-sm" }),
|
|
2805
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Loading countries\u2026" })
|
|
2806
|
+
] }) : countries.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: "No ramp providers available on this network yet." }) : /* @__PURE__ */ jsxRuntime.jsx("select", { className: "pollar-ramp-input", value: country, onChange: (e) => onCountryChange(e.target.value), children: countries.map((c) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: c.code, children: [
|
|
2807
|
+
flagEmoji(c.code),
|
|
2808
|
+
" ",
|
|
2809
|
+
c.code,
|
|
2810
|
+
c.currency ? ` \u2014 ${c.currency}` : ""
|
|
2811
|
+
] }, c.code)) })
|
|
2812
|
+
] }),
|
|
2813
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-field", children: [
|
|
2814
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "pollar-ramp-label", children: [
|
|
2815
|
+
"Amount",
|
|
2816
|
+
currency ? ` (${currency})` : ""
|
|
2817
|
+
] }),
|
|
2818
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2819
|
+
"input",
|
|
2601
2820
|
{
|
|
2821
|
+
type: "number",
|
|
2602
2822
|
className: "pollar-ramp-input",
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
if (COUNTRY_CURRENCIES[c]) onCurrencyChange(COUNTRY_CURRENCIES[c]);
|
|
2608
|
-
},
|
|
2609
|
-
children: [
|
|
2610
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "MX", children: "\u{1F1F2}\u{1F1FD} Mexico" }),
|
|
2611
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "BR", children: "\u{1F1E7}\u{1F1F7} Brazil" }),
|
|
2612
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "CO", children: "\u{1F1E8}\u{1F1F4} Colombia" }),
|
|
2613
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "CL", children: "\u{1F1E8}\u{1F1F1} Chile" }),
|
|
2614
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "PE", children: "\u{1F1F5}\u{1F1EA} Peru" }),
|
|
2615
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "AR", children: "\u{1F1E6}\u{1F1F7} Argentina" })
|
|
2616
|
-
]
|
|
2823
|
+
placeholder: "0.00",
|
|
2824
|
+
value: amount,
|
|
2825
|
+
min: "0",
|
|
2826
|
+
onChange: (e) => onAmountChange(e.target.value)
|
|
2617
2827
|
}
|
|
2618
2828
|
)
|
|
2619
2829
|
] }),
|
|
2620
2830
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-actions", children: [
|
|
2621
2831
|
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-secondary", onClick: onClose, children: "Cancel" }),
|
|
2622
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2832
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2833
|
+
"button",
|
|
2834
|
+
{
|
|
2835
|
+
type: "button",
|
|
2836
|
+
className: "pollar-btn-primary",
|
|
2837
|
+
disabled: !amount || isLoading || countriesLoading || countries.length === 0,
|
|
2838
|
+
onClick: onFindRoute,
|
|
2839
|
+
children: "Find best route"
|
|
2840
|
+
}
|
|
2841
|
+
)
|
|
2623
2842
|
] })
|
|
2624
2843
|
] }),
|
|
2625
|
-
step === "loading_quote" && /* @__PURE__ */ jsxRuntime.
|
|
2626
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-ramp-loading-
|
|
2627
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2628
|
-
|
|
2844
|
+
step === "loading_quote" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-loading", children: [
|
|
2845
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-spinner pollar-ramp-loading-spinner" }),
|
|
2846
|
+
LOADING_STEPS.map((text, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-loading-row", children: [
|
|
2847
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-ramp-loading-dot" }),
|
|
2848
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: text })
|
|
2849
|
+
] }, i))
|
|
2850
|
+
] }),
|
|
2629
2851
|
step === "select_route" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2630
2852
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-ramp-route-list", children: quotes.map((q, i) => /* @__PURE__ */ jsxRuntime.jsx(RouteDisplay, { quote: q, onSelect: onSelectQuote }, i)) }),
|
|
2631
2853
|
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-secondary", onClick: onClose, children: "Cancel" })
|
|
2632
2854
|
] }),
|
|
2855
|
+
step === "contact" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2856
|
+
requiredFields.map((f) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-field", children: [
|
|
2857
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "pollar-ramp-label", children: f.label }),
|
|
2858
|
+
f.type === "select" ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2859
|
+
"select",
|
|
2860
|
+
{
|
|
2861
|
+
className: "pollar-ramp-input",
|
|
2862
|
+
value: fieldValues[f.key] ?? "",
|
|
2863
|
+
onChange: (e) => onFieldChange(f.key, e.target.value),
|
|
2864
|
+
children: [
|
|
2865
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, children: "Select\u2026" }),
|
|
2866
|
+
(f.options ?? []).map((o) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: o.value, children: o.label }, o.value))
|
|
2867
|
+
]
|
|
2868
|
+
}
|
|
2869
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2870
|
+
"input",
|
|
2871
|
+
{
|
|
2872
|
+
type: f.type,
|
|
2873
|
+
className: "pollar-ramp-input",
|
|
2874
|
+
value: fieldValues[f.key] ?? "",
|
|
2875
|
+
autoComplete: f.type === "email" ? "email" : "off",
|
|
2876
|
+
onChange: (e) => onFieldChange(f.key, e.target.value)
|
|
2877
|
+
}
|
|
2878
|
+
),
|
|
2879
|
+
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." })
|
|
2880
|
+
] }, f.key)),
|
|
2881
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-actions", children: [
|
|
2882
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-secondary", onClick: onRetry, children: "Back" }),
|
|
2883
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2884
|
+
"button",
|
|
2885
|
+
{
|
|
2886
|
+
type: "button",
|
|
2887
|
+
className: "pollar-btn-primary",
|
|
2888
|
+
disabled: requiredFields.some((f) => !isFieldValid(f, fieldValues[f.key])) || isLoading,
|
|
2889
|
+
onClick: onContactContinue,
|
|
2890
|
+
children: isLoading ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2891
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-spinner pollar-spinner-sm" }),
|
|
2892
|
+
"Starting\u2026"
|
|
2893
|
+
] }) : "Continue"
|
|
2894
|
+
}
|
|
2895
|
+
)
|
|
2896
|
+
] })
|
|
2897
|
+
] }),
|
|
2633
2898
|
step === "status" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-payment", children: [
|
|
2634
2899
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-payment-field", children: [
|
|
2635
2900
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-ramp-payment-label", children: "Provider" }),
|
|
@@ -2637,27 +2902,81 @@ function RampWidgetTemplate({
|
|
|
2637
2902
|
] }),
|
|
2638
2903
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-payment-field", children: [
|
|
2639
2904
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-ramp-payment-label", children: "Status" }),
|
|
2640
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2641
|
-
"code",
|
|
2642
|
-
{
|
|
2643
|
-
|
|
2644
|
-
children: txStatus ? STATUS_LABEL[txStatus] : "Processing"
|
|
2645
|
-
}
|
|
2646
|
-
) })
|
|
2905
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-payment-value", children: [
|
|
2906
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { style: { color: txStatus === "completed" ? "var(--pollar-success-text)" : void 0 }, children: txStatus ? STATUS_LABEL[txStatus] : "Processing" }),
|
|
2907
|
+
txStatus !== "completed" && txStatus !== "failed" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-spinner pollar-spinner-sm", "aria-label": "Checking status" })
|
|
2908
|
+
] })
|
|
2647
2909
|
] }),
|
|
2648
2910
|
stellarTxHash && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-payment-field", children: [
|
|
2649
2911
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-ramp-payment-label", children: "Stellar tx" }),
|
|
2650
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2912
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-payment-value", style: { display: "flex", alignItems: "center", gap: 6 }, children: [
|
|
2913
|
+
/* @__PURE__ */ jsxRuntime.jsxs("code", { style: { flex: 1, wordBreak: "break-all" }, children: [
|
|
2914
|
+
stellarTxHash.slice(0, 8),
|
|
2915
|
+
"\u2026",
|
|
2916
|
+
stellarTxHash.slice(-8)
|
|
2917
|
+
] }),
|
|
2918
|
+
/* @__PURE__ */ jsxRuntime.jsx(CopyButton, { value: stellarTxHash, label: "Copy transaction hash" }),
|
|
2919
|
+
explorerUrl && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2920
|
+
"a",
|
|
2921
|
+
{
|
|
2922
|
+
href: explorerUrl,
|
|
2923
|
+
target: "_blank",
|
|
2924
|
+
rel: "noopener noreferrer",
|
|
2925
|
+
className: "pollar-copy-btn",
|
|
2926
|
+
"aria-label": "View on Stellar Expert",
|
|
2927
|
+
title: "View on Stellar Expert",
|
|
2928
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
|
|
2929
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2930
|
+
"path",
|
|
2931
|
+
{
|
|
2932
|
+
d: "M6 3H3v8h8V8",
|
|
2933
|
+
stroke: "currentColor",
|
|
2934
|
+
strokeWidth: "1.5",
|
|
2935
|
+
strokeLinecap: "round",
|
|
2936
|
+
strokeLinejoin: "round"
|
|
2937
|
+
}
|
|
2938
|
+
),
|
|
2939
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2940
|
+
"path",
|
|
2941
|
+
{
|
|
2942
|
+
d: "M8.5 2.5h3v3M11 3L6.5 7.5",
|
|
2943
|
+
stroke: "currentColor",
|
|
2944
|
+
strokeWidth: "1.5",
|
|
2945
|
+
strokeLinecap: "round",
|
|
2946
|
+
strokeLinejoin: "round"
|
|
2947
|
+
}
|
|
2948
|
+
)
|
|
2949
|
+
] })
|
|
2950
|
+
}
|
|
2951
|
+
)
|
|
2952
|
+
] })
|
|
2953
|
+
] }),
|
|
2954
|
+
depositInstructions && txStatus !== "completed" && flattenInstructions(depositInstructions).map(({ key, label, value, kind }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-payment-field", children: [
|
|
2955
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-ramp-payment-label", children: label }),
|
|
2956
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-ramp-payment-value", children: kind === "qr" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2957
|
+
"img",
|
|
2958
|
+
{
|
|
2959
|
+
src: value.startsWith("data:") ? value : `data:image/png;base64,${value}`,
|
|
2960
|
+
alt: label,
|
|
2961
|
+
style: { width: "100%", maxWidth: 220, height: "auto", display: "block", margin: "0 auto" }
|
|
2962
|
+
}
|
|
2963
|
+
) : kind === "datetime" ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: value }) : /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
|
|
2964
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { style: { flex: 1, wordBreak: "break-all" }, children: value }),
|
|
2965
|
+
/* @__PURE__ */ jsxRuntime.jsx(CopyButton, { value, label: `Copy ${label}` })
|
|
2654
2966
|
] }) })
|
|
2967
|
+
] }, key)),
|
|
2968
|
+
tosUrl && !depositInstructions && txStatus !== "completed" && /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "pollar-btn-primary", onClick: onOpenTos, children: [
|
|
2969
|
+
"Accept terms at ",
|
|
2970
|
+
provider
|
|
2655
2971
|
] }),
|
|
2656
|
-
kycUrl && txStatus !== "completed" && /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "pollar-btn-primary", onClick: onOpenKyc, children: [
|
|
2972
|
+
kycUrl && !depositInstructions && txStatus !== "completed" && /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "pollar-btn-primary", onClick: onOpenKyc, children: [
|
|
2657
2973
|
"Continue at ",
|
|
2658
2974
|
provider
|
|
2659
2975
|
] }),
|
|
2660
|
-
canComplete && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-primary", disabled: completing, onClick: onCompleteWithdraw, children: completing ?
|
|
2976
|
+
canComplete && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-primary", disabled: completing, onClick: onCompleteWithdraw, children: completing ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2977
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-spinner pollar-spinner-sm" }),
|
|
2978
|
+
"Submitting\u2026"
|
|
2979
|
+
] }) : "I've completed KYC \u2014 withdraw" }),
|
|
2661
2980
|
errorMsg && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "pollar-ramp-payment-note", style: { color: "var(--pollar-error-text)" }, children: errorMsg }),
|
|
2662
2981
|
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-secondary", onClick: onClose, children: txStatus === "completed" ? "Done" : "Close" })
|
|
2663
2982
|
] }),
|
|
@@ -2671,23 +2990,34 @@ function RampWidgetTemplate({
|
|
|
2671
2990
|
] });
|
|
2672
2991
|
}
|
|
2673
2992
|
var TERMINAL = ["completed", "failed"];
|
|
2993
|
+
function requiredFieldsOf(quote) {
|
|
2994
|
+
return quote.requiredFields ?? [];
|
|
2995
|
+
}
|
|
2674
2996
|
function RampWidget({ onClose }) {
|
|
2675
|
-
const { getClient, signTx, wallet, styles } = usePollar();
|
|
2997
|
+
const { getClient, signTx, wallet, styles, network } = usePollar();
|
|
2676
2998
|
const walletAddress = wallet?.address ?? "";
|
|
2677
2999
|
const client = getClient();
|
|
2678
3000
|
const { theme = "light", accentColor = "#005DB4" } = styles;
|
|
2679
3001
|
const [step, setStep] = react.useState("input");
|
|
2680
3002
|
const [direction, setDirection] = react.useState("onramp");
|
|
2681
3003
|
const [amount, setAmount] = react.useState("");
|
|
2682
|
-
const [currency, setCurrency] = react.useState("
|
|
2683
|
-
const [country, setCountry] = react.useState("
|
|
3004
|
+
const [currency, setCurrency] = react.useState("");
|
|
3005
|
+
const [country, setCountry] = react.useState("");
|
|
3006
|
+
const [fieldValues, setFieldValues] = react.useState({});
|
|
3007
|
+
const setFieldValue = (key, value) => setFieldValues((v) => ({ ...v, [key]: value }));
|
|
3008
|
+
const [countries, setCountries] = react.useState([]);
|
|
3009
|
+
const [countriesLoading, setCountriesLoading] = react.useState(true);
|
|
3010
|
+
const [refreshing, setRefreshing] = react.useState(false);
|
|
2684
3011
|
const [quotes, setQuotes] = react.useState([]);
|
|
3012
|
+
const [selectedQuote, setSelectedQuote] = react.useState(null);
|
|
2685
3013
|
const [isLoading, setIsLoading] = react.useState(false);
|
|
2686
3014
|
const [txId, setTxId] = react.useState(null);
|
|
2687
3015
|
const [provider, setProvider] = react.useState("");
|
|
2688
3016
|
const [kycUrl, setKycUrl] = react.useState(null);
|
|
3017
|
+
const [tosUrl, setTosUrl] = react.useState(null);
|
|
2689
3018
|
const [txStatus, setTxStatus] = react.useState(null);
|
|
2690
3019
|
const [stellarTxHash, setStellarTxHash] = react.useState(null);
|
|
3020
|
+
const [depositInstructions, setDepositInstructions] = react.useState(null);
|
|
2691
3021
|
const [completing, setCompleting] = react.useState(false);
|
|
2692
3022
|
const [errorMsg, setErrorMsg] = react.useState(null);
|
|
2693
3023
|
const directionRef = react.useRef(direction);
|
|
@@ -2703,6 +3033,7 @@ function RampWidget({ onClose }) {
|
|
|
2703
3033
|
setTxStatus(tx.status);
|
|
2704
3034
|
if (tx.stellarTxHash) setStellarTxHash(tx.stellarTxHash);
|
|
2705
3035
|
if (tx.kycUrl) setKycUrl(tx.kycUrl);
|
|
3036
|
+
if (tx.depositInstructions) setDepositInstructions(tx.depositInstructions);
|
|
2706
3037
|
if (TERMINAL.includes(tx.status)) clearInterval(id);
|
|
2707
3038
|
} catch {
|
|
2708
3039
|
}
|
|
@@ -2712,14 +3043,63 @@ function RampWidget({ onClose }) {
|
|
|
2712
3043
|
clearInterval(id);
|
|
2713
3044
|
};
|
|
2714
3045
|
}, [step, txId, txStatus, client]);
|
|
3046
|
+
async function loadCountries(resetSelection) {
|
|
3047
|
+
setCountriesLoading(true);
|
|
3048
|
+
try {
|
|
3049
|
+
const { countries: list } = await client.getRampCountries();
|
|
3050
|
+
setCountries(list);
|
|
3051
|
+
const first = list[0];
|
|
3052
|
+
const stillValid = list.some((c) => c.code === country);
|
|
3053
|
+
if (first && (resetSelection || !stillValid)) {
|
|
3054
|
+
setCountry(first.code);
|
|
3055
|
+
if (first.currency) setCurrency(first.currency);
|
|
3056
|
+
}
|
|
3057
|
+
} catch {
|
|
3058
|
+
setCountries([]);
|
|
3059
|
+
} finally {
|
|
3060
|
+
setCountriesLoading(false);
|
|
3061
|
+
}
|
|
3062
|
+
}
|
|
3063
|
+
react.useEffect(() => {
|
|
3064
|
+
loadCountries(true);
|
|
3065
|
+
}, []);
|
|
3066
|
+
function handleCountryChange(code) {
|
|
3067
|
+
setCountry(code);
|
|
3068
|
+
const match = countries.find((c) => c.code === code);
|
|
3069
|
+
if (match?.currency) setCurrency(match.currency);
|
|
3070
|
+
}
|
|
3071
|
+
async function handleRefresh() {
|
|
3072
|
+
if (refreshing) return;
|
|
3073
|
+
setRefreshing(true);
|
|
3074
|
+
try {
|
|
3075
|
+
await loadCountries(false);
|
|
3076
|
+
if (step === "select_route") {
|
|
3077
|
+
const result = await client.getRampsQuote({ country, amount: Number(amount), currency, direction });
|
|
3078
|
+
setQuotes(result.quotes ?? []);
|
|
3079
|
+
} else if (step === "status" && txId) {
|
|
3080
|
+
const tx = await client.getRampTransaction(txId);
|
|
3081
|
+
setTxStatus(tx.status);
|
|
3082
|
+
if (tx.stellarTxHash) setStellarTxHash(tx.stellarTxHash);
|
|
3083
|
+
if (tx.kycUrl) setKycUrl(tx.kycUrl);
|
|
3084
|
+
if (tx.depositInstructions) setDepositInstructions(tx.depositInstructions);
|
|
3085
|
+
}
|
|
3086
|
+
} catch {
|
|
3087
|
+
} finally {
|
|
3088
|
+
setRefreshing(false);
|
|
3089
|
+
}
|
|
3090
|
+
}
|
|
2715
3091
|
function resetToInput() {
|
|
2716
3092
|
setStep("input");
|
|
2717
3093
|
setQuotes([]);
|
|
3094
|
+
setSelectedQuote(null);
|
|
3095
|
+
setFieldValues({});
|
|
2718
3096
|
setTxId(null);
|
|
2719
3097
|
setProvider("");
|
|
2720
3098
|
setKycUrl(null);
|
|
3099
|
+
setTosUrl(null);
|
|
2721
3100
|
setTxStatus(null);
|
|
2722
3101
|
setStellarTxHash(null);
|
|
3102
|
+
setDepositInstructions(null);
|
|
2723
3103
|
setErrorMsg(null);
|
|
2724
3104
|
}
|
|
2725
3105
|
async function resumeWithSignature(id, ps) {
|
|
@@ -2743,8 +3123,10 @@ function RampWidget({ onClose }) {
|
|
|
2743
3123
|
return;
|
|
2744
3124
|
}
|
|
2745
3125
|
setKycUrl(result.kycUrl ?? null);
|
|
3126
|
+
setTosUrl(result.tosUrl ?? null);
|
|
2746
3127
|
setTxStatus(result.status);
|
|
2747
3128
|
setStellarTxHash(result.stellarTxHash ?? null);
|
|
3129
|
+
setDepositInstructions(result.depositInstructions ?? null);
|
|
2748
3130
|
setStep("status");
|
|
2749
3131
|
}
|
|
2750
3132
|
async function handleFindRoute() {
|
|
@@ -2768,12 +3150,37 @@ function RampWidget({ onClose }) {
|
|
|
2768
3150
|
setIsLoading(false);
|
|
2769
3151
|
}
|
|
2770
3152
|
}
|
|
2771
|
-
|
|
3153
|
+
function handleSelectQuote(quote) {
|
|
3154
|
+
setSelectedQuote(quote);
|
|
3155
|
+
setErrorMsg(null);
|
|
3156
|
+
const fields = requiredFieldsOf(quote);
|
|
3157
|
+
const missing = fields.some((f) => !(fieldValues[f.key] ?? "").trim());
|
|
3158
|
+
if (fields.length > 0 && missing) {
|
|
3159
|
+
setStep("contact");
|
|
3160
|
+
return;
|
|
3161
|
+
}
|
|
3162
|
+
void startRamp(quote);
|
|
3163
|
+
}
|
|
3164
|
+
function handleContactContinue() {
|
|
3165
|
+
if (selectedQuote) void startRamp(selectedQuote);
|
|
3166
|
+
}
|
|
3167
|
+
async function startRamp(quote) {
|
|
2772
3168
|
setIsLoading(true);
|
|
2773
3169
|
setErrorMsg(null);
|
|
2774
3170
|
try {
|
|
2775
3171
|
const base = { quoteId: quote.quoteId, amount: Number(amount), currency, country };
|
|
2776
|
-
|
|
3172
|
+
if (walletAddress) base.walletAddress = walletAddress;
|
|
3173
|
+
const STANDARD_BODY_KEYS = /* @__PURE__ */ new Set(["email", "fullName", "taxId", "qrCode"]);
|
|
3174
|
+
const extraFields = {};
|
|
3175
|
+
for (const f of requiredFieldsOf(quote)) {
|
|
3176
|
+
const val = (fieldValues[f.key] ?? "").trim();
|
|
3177
|
+
if (!val) continue;
|
|
3178
|
+
if (f.bankType) base.bankDetails = { type: f.bankType, value: val };
|
|
3179
|
+
else if (STANDARD_BODY_KEYS.has(f.key)) base[f.key] = val;
|
|
3180
|
+
else extraFields[f.key] = val;
|
|
3181
|
+
}
|
|
3182
|
+
if (Object.keys(extraFields).length > 0) base.fields = extraFields;
|
|
3183
|
+
const result = direction === "onramp" ? await client.createOnRamp(base) : await client.createOffRamp(base);
|
|
2777
3184
|
await applyResult(result);
|
|
2778
3185
|
} catch (e) {
|
|
2779
3186
|
setErrorMsg(e instanceof Error ? e.message : "Failed to start the ramp.");
|
|
@@ -2785,6 +3192,9 @@ function RampWidget({ onClose }) {
|
|
|
2785
3192
|
function handleOpenKyc() {
|
|
2786
3193
|
if (kycUrl) window.open(kycUrl, "_blank", "noopener,noreferrer");
|
|
2787
3194
|
}
|
|
3195
|
+
function handleOpenTos() {
|
|
3196
|
+
if (tosUrl) window.open(tosUrl, "_blank", "noopener,noreferrer");
|
|
3197
|
+
}
|
|
2788
3198
|
async function handleCompleteWithdraw() {
|
|
2789
3199
|
if (!txId) return;
|
|
2790
3200
|
setCompleting(true);
|
|
@@ -2817,24 +3227,35 @@ function RampWidget({ onClose }) {
|
|
|
2817
3227
|
amount,
|
|
2818
3228
|
currency,
|
|
2819
3229
|
country,
|
|
3230
|
+
requiredFields: selectedQuote ? requiredFieldsOf(selectedQuote) : [],
|
|
3231
|
+
fieldValues,
|
|
3232
|
+
countries,
|
|
3233
|
+
countriesLoading,
|
|
3234
|
+
refreshing,
|
|
2820
3235
|
quotes,
|
|
2821
3236
|
isLoading,
|
|
2822
3237
|
provider,
|
|
2823
3238
|
txStatus,
|
|
2824
3239
|
kycUrl,
|
|
3240
|
+
tosUrl,
|
|
2825
3241
|
stellarTxHash,
|
|
3242
|
+
explorerUrl: stellarTxHash ? `https://stellar.expert/explorer/${network === "mainnet" ? "public" : "testnet"}/tx/${stellarTxHash}` : null,
|
|
3243
|
+
depositInstructions,
|
|
2826
3244
|
canComplete,
|
|
2827
3245
|
completing,
|
|
2828
3246
|
errorMsg,
|
|
2829
3247
|
onDirectionChange: setDirection,
|
|
2830
3248
|
onAmountChange: setAmount,
|
|
2831
|
-
|
|
2832
|
-
onCountryChange:
|
|
3249
|
+
onFieldChange: setFieldValue,
|
|
3250
|
+
onCountryChange: handleCountryChange,
|
|
2833
3251
|
onFindRoute: handleFindRoute,
|
|
2834
3252
|
onSelectQuote: handleSelectQuote,
|
|
3253
|
+
onContactContinue: handleContactContinue,
|
|
2835
3254
|
onOpenKyc: handleOpenKyc,
|
|
3255
|
+
onOpenTos: handleOpenTos,
|
|
2836
3256
|
onCompleteWithdraw: handleCompleteWithdraw,
|
|
2837
3257
|
onRetry: resetToInput,
|
|
3258
|
+
onRefresh: handleRefresh,
|
|
2838
3259
|
onClose
|
|
2839
3260
|
}
|
|
2840
3261
|
) });
|
|
@@ -2997,6 +3418,43 @@ function ReceiveModal({ onClose }) {
|
|
|
2997
3418
|
}
|
|
2998
3419
|
) });
|
|
2999
3420
|
}
|
|
3421
|
+
function formatAmount2(value) {
|
|
3422
|
+
const n = parseFloat(value);
|
|
3423
|
+
return isNaN(n) ? value : n.toLocaleString(void 0, { maximumFractionDigits: 7 });
|
|
3424
|
+
}
|
|
3425
|
+
var optionLabel = (o) => o.available !== void 0 ? `${o.code} \u2014 ${formatAmount2(o.available)} available` : o.code;
|
|
3426
|
+
function AssetSelect({
|
|
3427
|
+
label,
|
|
3428
|
+
value,
|
|
3429
|
+
options,
|
|
3430
|
+
onChange,
|
|
3431
|
+
loading = false,
|
|
3432
|
+
disabled = false,
|
|
3433
|
+
appGroupLabel = "App assets",
|
|
3434
|
+
otherGroupLabel = "Other assets",
|
|
3435
|
+
children
|
|
3436
|
+
}) {
|
|
3437
|
+
const appAssets = options.filter((o) => o.enabledInApp);
|
|
3438
|
+
const otherAssets = options.filter((o) => !o.enabledInApp);
|
|
3439
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-send-field", children: [
|
|
3440
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "pollar-send-label", children: label }),
|
|
3441
|
+
loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-send-skeleton" }) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3442
|
+
"select",
|
|
3443
|
+
{
|
|
3444
|
+
className: "pollar-input pollar-send-select",
|
|
3445
|
+
value,
|
|
3446
|
+
disabled,
|
|
3447
|
+
onChange: (e) => onChange(e.target.value),
|
|
3448
|
+
children: [
|
|
3449
|
+
value === "" && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, hidden: true }),
|
|
3450
|
+
appAssets.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("optgroup", { label: appGroupLabel, children: appAssets.map((o) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: o.key, children: optionLabel(o) }, o.key)) }),
|
|
3451
|
+
otherAssets.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("optgroup", { label: otherGroupLabel, children: otherAssets.map((o) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: o.key, children: optionLabel(o) }, o.key)) })
|
|
3452
|
+
]
|
|
3453
|
+
}
|
|
3454
|
+
),
|
|
3455
|
+
!loading && children
|
|
3456
|
+
] });
|
|
3457
|
+
}
|
|
3000
3458
|
var STATUS_MESSAGES = {
|
|
3001
3459
|
idle: "",
|
|
3002
3460
|
building: "Building transaction\u2026",
|
|
@@ -3221,6 +3679,7 @@ function SendModalTemplate({
|
|
|
3221
3679
|
isInProgress,
|
|
3222
3680
|
onClose,
|
|
3223
3681
|
onBack,
|
|
3682
|
+
onRefresh,
|
|
3224
3683
|
onSelectAsset,
|
|
3225
3684
|
onAmountChange,
|
|
3226
3685
|
onDestinationChange,
|
|
@@ -3249,8 +3708,6 @@ function SendModalTemplate({
|
|
|
3249
3708
|
"--pollar-input-border-radius": "0.5rem",
|
|
3250
3709
|
"--pollar-card-border-radius": "10px"
|
|
3251
3710
|
};
|
|
3252
|
-
const enabledAssets = assets.filter((a) => a.enabledInApp);
|
|
3253
|
-
const otherAssets = assets.filter((a) => !a.enabledInApp);
|
|
3254
3711
|
const selectedKey = selectedAsset ? assetKey3(selectedAsset) : "";
|
|
3255
3712
|
const canSubmit = !!selectedAsset && !!amount && !!destination.trim() && !isLoadingBalance;
|
|
3256
3713
|
const title = step === "form" ? "Send" : txTitle;
|
|
@@ -3267,39 +3724,61 @@ function SendModalTemplate({
|
|
|
3267
3724
|
showBack && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-modal-close", onClick: onBack, "aria-label": "Back", 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: "M10 3L5 8l5 5", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }),
|
|
3268
3725
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: title })
|
|
3269
3726
|
] }),
|
|
3270
|
-
!isInProgress && /* @__PURE__ */ jsxRuntime.
|
|
3727
|
+
!isInProgress && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
|
|
3728
|
+
step === "form" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3729
|
+
"button",
|
|
3730
|
+
{
|
|
3731
|
+
type: "button",
|
|
3732
|
+
className: "pollar-modal-close",
|
|
3733
|
+
onClick: onRefresh,
|
|
3734
|
+
disabled: isLoadingBalance,
|
|
3735
|
+
"aria-label": "Refresh",
|
|
3736
|
+
title: "Refresh balances",
|
|
3737
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3738
|
+
"svg",
|
|
3739
|
+
{
|
|
3740
|
+
className: isLoadingBalance ? "pollar-modal-refresh-icon pollar-spinning" : "pollar-modal-refresh-icon",
|
|
3741
|
+
width: "16",
|
|
3742
|
+
height: "16",
|
|
3743
|
+
viewBox: "0 0 16 16",
|
|
3744
|
+
fill: "none",
|
|
3745
|
+
"aria-hidden": true,
|
|
3746
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3747
|
+
"path",
|
|
3748
|
+
{
|
|
3749
|
+
d: "M13.5 8a5.5 5.5 0 1 1-1.6-3.9M13.5 2v3h-3",
|
|
3750
|
+
stroke: "currentColor",
|
|
3751
|
+
strokeWidth: "1.6",
|
|
3752
|
+
strokeLinecap: "round",
|
|
3753
|
+
strokeLinejoin: "round"
|
|
3754
|
+
}
|
|
3755
|
+
)
|
|
3756
|
+
}
|
|
3757
|
+
)
|
|
3758
|
+
}
|
|
3759
|
+
),
|
|
3760
|
+
/* @__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" }) }) })
|
|
3761
|
+
] })
|
|
3271
3762
|
] }),
|
|
3272
3763
|
step === "form" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3273
|
-
/* @__PURE__ */ jsxRuntime.
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
"
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
a.code,
|
|
3289
|
-
" \u2014 ",
|
|
3290
|
-
formatBalance(a.available),
|
|
3291
|
-
" available"
|
|
3292
|
-
] }, assetKey3(a))) }),
|
|
3293
|
-
otherAssets.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("optgroup", { label: "Other assets", children: otherAssets.map((a) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: assetKey3(a), children: [
|
|
3294
|
-
a.code,
|
|
3295
|
-
" \u2014 ",
|
|
3296
|
-
formatBalance(a.available),
|
|
3297
|
-
" available"
|
|
3298
|
-
] }, assetKey3(a))) })
|
|
3299
|
-
]
|
|
3764
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3765
|
+
AssetSelect,
|
|
3766
|
+
{
|
|
3767
|
+
label: "Asset",
|
|
3768
|
+
value: selectedKey,
|
|
3769
|
+
loading: isLoadingBalance,
|
|
3770
|
+
options: assets.map((a) => ({
|
|
3771
|
+
key: assetKey3(a),
|
|
3772
|
+
code: a.code,
|
|
3773
|
+
available: a.available,
|
|
3774
|
+
enabledInApp: a.enabledInApp
|
|
3775
|
+
})),
|
|
3776
|
+
onChange: (key) => {
|
|
3777
|
+
const found = assets.find((a) => assetKey3(a) === key);
|
|
3778
|
+
if (found) onSelectAsset(found);
|
|
3300
3779
|
}
|
|
3301
|
-
|
|
3302
|
-
|
|
3780
|
+
}
|
|
3781
|
+
),
|
|
3303
3782
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-send-field", children: [
|
|
3304
3783
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-send-label-row", children: [
|
|
3305
3784
|
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "pollar-send-label", children: "Amount" }),
|
|
@@ -3399,13 +3878,16 @@ function SendModal({ onClose }) {
|
|
|
3399
3878
|
const allAssets = balanceData?.balances ?? [];
|
|
3400
3879
|
const sortedAssets = [
|
|
3401
3880
|
...allAssets.filter((b) => b.enabledInApp),
|
|
3402
|
-
...allAssets.filter((b) => !b.enabledInApp && parseFloat(b.balance) > 0)
|
|
3881
|
+
...allAssets.filter((b) => !b.enabledInApp && (b.type === "native" || parseFloat(b.balance) > 0))
|
|
3403
3882
|
];
|
|
3883
|
+
react.useEffect(() => {
|
|
3884
|
+
if (!selectedAsset && sortedAssets.length > 0) setSelectedAsset(sortedAssets[0]);
|
|
3885
|
+
}, [sortedAssets, selectedAsset]);
|
|
3404
3886
|
const hash = transaction.step === "success" ? transaction.hash : null;
|
|
3405
3887
|
const buildData = "buildData" in transaction ? transaction.buildData : null;
|
|
3406
3888
|
const explorerNetwork = buildData?.summary.network?.toLowerCase().includes("testnet") ? "testnet" : buildData ? "public" : network === "testnet" ? "testnet" : "public";
|
|
3407
3889
|
const explorerUrl = hash ? `https://stellar.expert/explorer/${explorerNetwork}/tx/${hash}` : null;
|
|
3408
|
-
const
|
|
3890
|
+
const IN_FLIGHT_STEPS3 = [
|
|
3409
3891
|
"building",
|
|
3410
3892
|
"signing",
|
|
3411
3893
|
"submitting",
|
|
@@ -3413,7 +3895,7 @@ function SendModal({ onClose }) {
|
|
|
3413
3895
|
"signing-submitting",
|
|
3414
3896
|
"building-signing-submitting"
|
|
3415
3897
|
];
|
|
3416
|
-
const isInProgress =
|
|
3898
|
+
const isInProgress = IN_FLIGHT_STEPS3.includes(transaction.step);
|
|
3417
3899
|
const showBack = step === "tx" && (transaction.step === "error" || transaction.step === "success") && !isInProgress;
|
|
3418
3900
|
const txTitle = isInProgress ? "Sending\u2026" : transaction.step === "success" ? "Sent!" : transaction.step === "error" ? "Send failed" : "Confirm Send";
|
|
3419
3901
|
async function handleSubmit() {
|
|
@@ -3486,6 +3968,7 @@ function SendModal({ onClose }) {
|
|
|
3486
3968
|
isInProgress,
|
|
3487
3969
|
onClose,
|
|
3488
3970
|
onBack: handleBack,
|
|
3971
|
+
onRefresh: () => void refreshWalletBalance(),
|
|
3489
3972
|
onSelectAsset: setSelectedAsset,
|
|
3490
3973
|
onAmountChange: setAmount,
|
|
3491
3974
|
onDestinationChange: setDestination,
|
|
@@ -3507,7 +3990,7 @@ var PROVIDER_LABELS = {
|
|
|
3507
3990
|
soroswap: "Soroswap",
|
|
3508
3991
|
sdex: "Stellar DEX"
|
|
3509
3992
|
};
|
|
3510
|
-
function
|
|
3993
|
+
function formatAmount3(value) {
|
|
3511
3994
|
const n = parseFloat(value);
|
|
3512
3995
|
return isNaN(n) ? value : n.toLocaleString(void 0, { maximumFractionDigits: 7 });
|
|
3513
3996
|
}
|
|
@@ -3544,6 +4027,7 @@ function SwapModalTemplate({
|
|
|
3544
4027
|
onRefresh,
|
|
3545
4028
|
onSelectSell,
|
|
3546
4029
|
onSelectBuy,
|
|
4030
|
+
onAddCustomToken,
|
|
3547
4031
|
onAmountChange,
|
|
3548
4032
|
onProviderChange,
|
|
3549
4033
|
onSwap,
|
|
@@ -3553,6 +4037,21 @@ function SwapModalTemplate({
|
|
|
3553
4037
|
onDone
|
|
3554
4038
|
}) {
|
|
3555
4039
|
const isDark = theme === "dark";
|
|
4040
|
+
const [customOpen, setCustomOpen] = react.useState(false);
|
|
4041
|
+
const [customCode, setCustomCode] = react.useState("");
|
|
4042
|
+
const [customIssuer, setCustomIssuer] = react.useState("");
|
|
4043
|
+
const [customError, setCustomError] = react.useState("");
|
|
4044
|
+
const submitCustomToken = () => {
|
|
4045
|
+
const err = onAddCustomToken(customCode, customIssuer);
|
|
4046
|
+
if (err) {
|
|
4047
|
+
setCustomError(err);
|
|
4048
|
+
return;
|
|
4049
|
+
}
|
|
4050
|
+
setCustomCode("");
|
|
4051
|
+
setCustomIssuer("");
|
|
4052
|
+
setCustomError("");
|
|
4053
|
+
setCustomOpen(false);
|
|
4054
|
+
};
|
|
3556
4055
|
const cssVars = {
|
|
3557
4056
|
"--pollar-accent": accentColor,
|
|
3558
4057
|
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
@@ -3574,176 +4073,235 @@ function SwapModalTemplate({
|
|
|
3574
4073
|
const buyKey = selectedBuy ? assetOptionKey(selectedBuy) : "";
|
|
3575
4074
|
const canSwap = !smartUnsupported && !!selectedSell && !!selectedBuy && !!amount && !!quote && !quoteLoading && !isLoadingData;
|
|
3576
4075
|
const title = step === "form" ? "Swap" : txTitle;
|
|
3577
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
{
|
|
3587
|
-
type: "button",
|
|
3588
|
-
className: "pollar-modal-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
"
|
|
3592
|
-
|
|
3593
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3594
|
-
"path",
|
|
4076
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4077
|
+
"div",
|
|
4078
|
+
{
|
|
4079
|
+
className: "pollar-modal-card pollar-send-modal",
|
|
4080
|
+
"data-theme": theme,
|
|
4081
|
+
style: cssVars,
|
|
4082
|
+
onClick: (e) => e.stopPropagation(),
|
|
4083
|
+
children: [
|
|
4084
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
|
|
4085
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-send-header-left", children: [
|
|
4086
|
+
showBack && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-modal-close", onClick: onBack, "aria-label": "Back", 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: "M10 3L5 8l5 5", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }),
|
|
4087
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: title })
|
|
4088
|
+
] }),
|
|
4089
|
+
!isInProgress && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
|
|
4090
|
+
step === "form" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4091
|
+
"button",
|
|
3595
4092
|
{
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
4093
|
+
type: "button",
|
|
4094
|
+
className: "pollar-modal-close",
|
|
4095
|
+
onClick: onRefresh,
|
|
4096
|
+
disabled: configLoading || isLoadingData,
|
|
4097
|
+
"aria-label": "Refresh",
|
|
4098
|
+
title: "Refresh balances and options",
|
|
4099
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4100
|
+
"path",
|
|
4101
|
+
{
|
|
4102
|
+
d: "M13.5 8a5.5 5.5 0 1 1-1.6-3.9M13.5 2.5v3h-3",
|
|
4103
|
+
stroke: "currentColor",
|
|
4104
|
+
strokeWidth: "1.6",
|
|
4105
|
+
strokeLinecap: "round",
|
|
4106
|
+
strokeLinejoin: "round"
|
|
4107
|
+
}
|
|
4108
|
+
) })
|
|
3601
4109
|
}
|
|
3602
|
-
)
|
|
3603
|
-
|
|
3604
|
-
),
|
|
3605
|
-
/* @__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" }) }) })
|
|
3606
|
-
] })
|
|
3607
|
-
] }),
|
|
3608
|
-
step === "form" && configLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-send-hint", children: "Loading swap options\u2026" }),
|
|
3609
|
-
step === "form" && !configLoading && swapUnavailable && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: "Swap is not available for this app." }),
|
|
3610
|
-
step === "form" && !configLoading && !swapUnavailable && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3611
|
-
smartUnsupported && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: "Swaps are not yet available for smart (passkey) wallets." }),
|
|
3612
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-send-field", children: [
|
|
3613
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "pollar-send-label", children: "You pay" }),
|
|
3614
|
-
isLoadingData ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-send-skeleton" }) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3615
|
-
"select",
|
|
3616
|
-
{
|
|
3617
|
-
className: "pollar-input pollar-send-select",
|
|
3618
|
-
value: sellKey,
|
|
3619
|
-
onChange: (e) => {
|
|
3620
|
-
const found = sellOptions.find((o) => assetOptionKey(o) === e.target.value);
|
|
3621
|
-
if (found) onSelectSell(found);
|
|
3622
|
-
},
|
|
3623
|
-
children: [
|
|
3624
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, children: "Select asset to sell" }),
|
|
3625
|
-
sellOptions.map((o) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: assetOptionKey(o), children: [
|
|
3626
|
-
o.code,
|
|
3627
|
-
o.available !== void 0 ? ` \u2014 ${formatAmount2(o.available)} available` : ""
|
|
3628
|
-
] }, assetOptionKey(o)))
|
|
3629
|
-
]
|
|
3630
|
-
}
|
|
3631
|
-
)
|
|
3632
|
-
] }),
|
|
3633
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-send-field", children: [
|
|
3634
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-send-label-row", children: [
|
|
3635
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "pollar-send-label", children: "Amount" }),
|
|
3636
|
-
selectedSell?.available !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-send-hint", children: [
|
|
3637
|
-
"Available: ",
|
|
3638
|
-
formatAmount2(selectedSell.available),
|
|
3639
|
-
" ",
|
|
3640
|
-
selectedSell.code
|
|
4110
|
+
),
|
|
4111
|
+
/* @__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" }) }) })
|
|
3641
4112
|
] })
|
|
3642
4113
|
] }),
|
|
3643
|
-
/* @__PURE__ */ jsxRuntime.
|
|
3644
|
-
"
|
|
3645
|
-
{
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
4114
|
+
step === "form" && configLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-loading-block", children: [
|
|
4115
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-spinner" }),
|
|
4116
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Loading swap options\u2026" })
|
|
4117
|
+
] }),
|
|
4118
|
+
step === "form" && !configLoading && swapUnavailable && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: "Swap is not available for this app." }),
|
|
4119
|
+
step === "form" && !swapUnavailable && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4120
|
+
smartUnsupported && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: "Swaps are not yet available for smart (passkey) wallets." }),
|
|
4121
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4122
|
+
AssetSelect,
|
|
4123
|
+
{
|
|
4124
|
+
label: "You pay",
|
|
4125
|
+
value: sellKey,
|
|
4126
|
+
loading: isLoadingData,
|
|
4127
|
+
disabled: configLoading,
|
|
4128
|
+
options: sellOptions.map((o) => ({
|
|
4129
|
+
key: assetOptionKey(o),
|
|
4130
|
+
code: o.code,
|
|
4131
|
+
available: o.available,
|
|
4132
|
+
enabledInApp: o.enabledInApp
|
|
4133
|
+
})),
|
|
4134
|
+
onChange: (key) => {
|
|
4135
|
+
const found = sellOptions.find((o) => assetOptionKey(o) === key);
|
|
4136
|
+
if (found) onSelectSell(found);
|
|
4137
|
+
}
|
|
4138
|
+
}
|
|
4139
|
+
),
|
|
4140
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-send-field", children: [
|
|
4141
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-send-label-row", children: [
|
|
4142
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "pollar-send-label", children: "Amount" }),
|
|
4143
|
+
selectedSell?.available !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-send-hint", children: [
|
|
4144
|
+
"Available: ",
|
|
4145
|
+
formatAmount3(selectedSell.available),
|
|
4146
|
+
" ",
|
|
4147
|
+
selectedSell.code
|
|
4148
|
+
] })
|
|
4149
|
+
] }),
|
|
4150
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4151
|
+
"input",
|
|
4152
|
+
{
|
|
4153
|
+
className: "pollar-input",
|
|
4154
|
+
type: "text",
|
|
4155
|
+
inputMode: "decimal",
|
|
4156
|
+
placeholder: "0.00",
|
|
4157
|
+
value: amount,
|
|
4158
|
+
disabled: configLoading,
|
|
4159
|
+
onChange: (e) => onAmountChange(e.target.value)
|
|
4160
|
+
}
|
|
4161
|
+
)
|
|
4162
|
+
] }),
|
|
4163
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4164
|
+
AssetSelect,
|
|
4165
|
+
{
|
|
4166
|
+
label: "You receive",
|
|
4167
|
+
value: buyKey,
|
|
4168
|
+
loading: isLoadingData,
|
|
4169
|
+
disabled: configLoading,
|
|
4170
|
+
options: buyOptions.map((o) => ({
|
|
4171
|
+
key: assetOptionKey(o),
|
|
4172
|
+
code: o.code,
|
|
4173
|
+
enabledInApp: o.enabledInApp
|
|
4174
|
+
})),
|
|
4175
|
+
onChange: (key) => {
|
|
4176
|
+
const found = buyOptions.find((o) => assetOptionKey(o) === key);
|
|
4177
|
+
if (found) onSelectBuy(found);
|
|
4178
|
+
},
|
|
4179
|
+
children: customOpen ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-swap-custom", children: [
|
|
4180
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4181
|
+
"input",
|
|
4182
|
+
{
|
|
4183
|
+
className: "pollar-input",
|
|
4184
|
+
type: "text",
|
|
4185
|
+
placeholder: "Code (e.g. USDC)",
|
|
4186
|
+
value: customCode,
|
|
4187
|
+
onChange: (e) => setCustomCode(e.target.value)
|
|
4188
|
+
}
|
|
4189
|
+
),
|
|
4190
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4191
|
+
"input",
|
|
4192
|
+
{
|
|
4193
|
+
className: "pollar-input",
|
|
4194
|
+
type: "text",
|
|
4195
|
+
placeholder: "Issuer (G...)",
|
|
4196
|
+
value: customIssuer,
|
|
4197
|
+
onChange: (e) => setCustomIssuer(e.target.value)
|
|
4198
|
+
}
|
|
4199
|
+
),
|
|
4200
|
+
customError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: customError }),
|
|
4201
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-swap-custom-actions", children: [
|
|
4202
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-primary", onClick: submitCustomToken, children: "Add token" }),
|
|
4203
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4204
|
+
"button",
|
|
4205
|
+
{
|
|
4206
|
+
type: "button",
|
|
4207
|
+
className: "pollar-swap-custom-cancel",
|
|
4208
|
+
onClick: () => {
|
|
4209
|
+
setCustomOpen(false);
|
|
4210
|
+
setCustomError("");
|
|
4211
|
+
},
|
|
4212
|
+
children: "Cancel"
|
|
4213
|
+
}
|
|
4214
|
+
)
|
|
4215
|
+
] })
|
|
4216
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
4217
|
+
"button",
|
|
4218
|
+
{
|
|
4219
|
+
type: "button",
|
|
4220
|
+
className: "pollar-swap-custom-toggle",
|
|
4221
|
+
disabled: configLoading,
|
|
4222
|
+
onClick: () => setCustomOpen(true),
|
|
4223
|
+
children: "+ Add a token by code / issuer"
|
|
4224
|
+
}
|
|
4225
|
+
)
|
|
4226
|
+
}
|
|
4227
|
+
),
|
|
4228
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-send-field", children: [
|
|
4229
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "pollar-send-label", children: "Route" }),
|
|
4230
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4231
|
+
"select",
|
|
4232
|
+
{
|
|
4233
|
+
className: "pollar-input pollar-send-select",
|
|
4234
|
+
value: provider,
|
|
4235
|
+
disabled: configLoading || providers.length === 0,
|
|
4236
|
+
onChange: (e) => onProviderChange(e.target.value),
|
|
4237
|
+
children: providers.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("option", { value: provider, children: configLoading ? "Loading\u2026" : PROVIDER_LABELS[provider] }) : providers.map((p) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: p, children: PROVIDER_LABELS[p] }, p))
|
|
4238
|
+
}
|
|
4239
|
+
)
|
|
4240
|
+
] }),
|
|
4241
|
+
quoteLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-send-hint pollar-inline-loading", children: [
|
|
4242
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-spinner pollar-spinner-sm" }),
|
|
4243
|
+
"Fetching best price\u2026"
|
|
4244
|
+
] }),
|
|
4245
|
+
!quoteLoading && quoteError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: quoteError }),
|
|
4246
|
+
!quoteLoading && !quoteError && quote && selectedBuy && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-swap-quote", children: [
|
|
4247
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-swap-quote-row", children: [
|
|
4248
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-send-hint", children: "You receive" }),
|
|
4249
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
4250
|
+
"~ ",
|
|
4251
|
+
formatAmount3(quote.amountOut),
|
|
4252
|
+
" ",
|
|
4253
|
+
selectedBuy.code
|
|
4254
|
+
] })
|
|
4255
|
+
] }),
|
|
4256
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-swap-quote-row", children: [
|
|
4257
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-send-hint", children: "Minimum received" }),
|
|
4258
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
4259
|
+
formatAmount3(quote.minReceived),
|
|
4260
|
+
" ",
|
|
4261
|
+
selectedBuy.code
|
|
4262
|
+
] })
|
|
4263
|
+
] }),
|
|
4264
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-swap-quote-row", children: [
|
|
4265
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-send-hint", children: "Price impact" }),
|
|
4266
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
4267
|
+
quote.priceImpactPct,
|
|
4268
|
+
"%"
|
|
4269
|
+
] })
|
|
4270
|
+
] }),
|
|
4271
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-swap-quote-row", children: [
|
|
4272
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-send-hint", children: "Route" }),
|
|
4273
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: PROVIDER_LABELS[quote.provider] })
|
|
4274
|
+
] })
|
|
4275
|
+
] }),
|
|
4276
|
+
!quoteLoading && !quoteError && !quote && selectedSell && selectedBuy && !!amount && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-send-hint", children: "No route found for this pair." }),
|
|
4277
|
+
buyNeedsTrustline && selectedBuy && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-swap-trustline-notice", children: [
|
|
4278
|
+
"To receive ",
|
|
4279
|
+
selectedBuy.code,
|
|
4280
|
+
" your wallet needs a trustline. Swapping will create it first (~0.5 XLM reserve, refundable if you later remove it)."
|
|
4281
|
+
] }),
|
|
4282
|
+
formError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: formError }),
|
|
4283
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-actions", children: /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-btn-primary", onClick: onSwap, disabled: !canSwap, children: buyNeedsTrustline ? "Create trustline & swap" : "Swap" }) })
|
|
4284
|
+
] }),
|
|
4285
|
+
step === "tx" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4286
|
+
TxStatusView,
|
|
3659
4287
|
{
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
4288
|
+
transaction,
|
|
4289
|
+
showXdr,
|
|
4290
|
+
copied,
|
|
4291
|
+
explorerUrl,
|
|
4292
|
+
walletType,
|
|
4293
|
+
onSignAndSend: () => {
|
|
3665
4294
|
},
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
o.enabledInApp ? "" : " (external)"
|
|
3671
|
-
] }, assetOptionKey(o)))
|
|
3672
|
-
]
|
|
3673
|
-
}
|
|
3674
|
-
)
|
|
3675
|
-
] }),
|
|
3676
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-send-field", children: [
|
|
3677
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "pollar-send-label", children: "Route" }),
|
|
3678
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3679
|
-
"select",
|
|
3680
|
-
{
|
|
3681
|
-
className: "pollar-input pollar-send-select",
|
|
3682
|
-
value: provider,
|
|
3683
|
-
onChange: (e) => onProviderChange(e.target.value),
|
|
3684
|
-
children: providers.map((p) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: p, children: PROVIDER_LABELS[p] }, p))
|
|
4295
|
+
onToggleXdr,
|
|
4296
|
+
onCopyHash,
|
|
4297
|
+
onRetry,
|
|
4298
|
+
onDone
|
|
3685
4299
|
}
|
|
3686
|
-
)
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-swap-quote-row", children: [
|
|
3692
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-send-hint", children: "You receive" }),
|
|
3693
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
3694
|
-
"~ ",
|
|
3695
|
-
formatAmount2(quote.amountOut),
|
|
3696
|
-
" ",
|
|
3697
|
-
selectedBuy.code
|
|
3698
|
-
] })
|
|
3699
|
-
] }),
|
|
3700
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-swap-quote-row", children: [
|
|
3701
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-send-hint", children: "Minimum received" }),
|
|
3702
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
3703
|
-
formatAmount2(quote.minReceived),
|
|
3704
|
-
" ",
|
|
3705
|
-
selectedBuy.code
|
|
3706
|
-
] })
|
|
3707
|
-
] }),
|
|
3708
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-swap-quote-row", children: [
|
|
3709
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-send-hint", children: "Price impact" }),
|
|
3710
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
3711
|
-
quote.priceImpactPct,
|
|
3712
|
-
"%"
|
|
3713
|
-
] })
|
|
3714
|
-
] }),
|
|
3715
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-swap-quote-row", children: [
|
|
3716
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-send-hint", children: "Route" }),
|
|
3717
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: PROVIDER_LABELS[quote.provider] })
|
|
3718
|
-
] })
|
|
3719
|
-
] }),
|
|
3720
|
-
!quoteLoading && !quoteError && !quote && selectedSell && selectedBuy && !!amount && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-send-hint", children: "No route found for this pair." }),
|
|
3721
|
-
buyNeedsTrustline && selectedBuy && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-swap-trustline-notice", children: [
|
|
3722
|
-
"To receive ",
|
|
3723
|
-
selectedBuy.code,
|
|
3724
|
-
" your wallet needs a trustline. Swapping will create it first (~0.5 XLM reserve, refundable if you later remove it)."
|
|
3725
|
-
] }),
|
|
3726
|
-
formError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: formError }),
|
|
3727
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-actions", children: /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-btn-primary", onClick: onSwap, disabled: !canSwap, children: buyNeedsTrustline ? "Create trustline & swap" : "Swap" }) })
|
|
3728
|
-
] }),
|
|
3729
|
-
step === "tx" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3730
|
-
TxStatusView,
|
|
3731
|
-
{
|
|
3732
|
-
transaction,
|
|
3733
|
-
showXdr,
|
|
3734
|
-
copied,
|
|
3735
|
-
explorerUrl,
|
|
3736
|
-
walletType,
|
|
3737
|
-
onSignAndSend: () => {
|
|
3738
|
-
},
|
|
3739
|
-
onToggleXdr,
|
|
3740
|
-
onCopyHash,
|
|
3741
|
-
onRetry,
|
|
3742
|
-
onDone
|
|
3743
|
-
}
|
|
3744
|
-
),
|
|
3745
|
-
/* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
|
|
3746
|
-
] });
|
|
4300
|
+
),
|
|
4301
|
+
/* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
|
|
4302
|
+
]
|
|
4303
|
+
}
|
|
4304
|
+
);
|
|
3747
4305
|
}
|
|
3748
4306
|
var QUOTE_DEBOUNCE_MS = 400;
|
|
3749
4307
|
function toRef(a) {
|
|
@@ -3779,6 +4337,7 @@ function SwapModal({ onClose }) {
|
|
|
3779
4337
|
const [provider, setProvider] = react.useState("auto");
|
|
3780
4338
|
const [venues, setVenues] = react.useState(null);
|
|
3781
4339
|
const [catalogTokens, setCatalogTokens] = react.useState([]);
|
|
4340
|
+
const [customTokens, setCustomTokens] = react.useState([]);
|
|
3782
4341
|
const [quotes, setQuotes] = react.useState([]);
|
|
3783
4342
|
const [quoteLoading, setQuoteLoading] = react.useState(false);
|
|
3784
4343
|
const [quoteError, setQuoteError] = react.useState("");
|
|
@@ -3820,7 +4379,7 @@ function SwapModal({ onClose }) {
|
|
|
3820
4379
|
const balances = walletBalance.step === "loaded" ? walletBalance.data.balances : [];
|
|
3821
4380
|
const assetRecords = enabledAssets.step === "loaded" ? enabledAssets.data.assets : [];
|
|
3822
4381
|
const isLoadingData = walletBalance.step === "loading" || enabledAssets.step === "loading";
|
|
3823
|
-
const sellOptions = balances.filter((b) =>
|
|
4382
|
+
const sellOptions = balances.filter((b) => b.type === "native" || !b.trustlineRemoved).map((b) => ({ ref: toRef(b), code: b.code, issuer: b.issuer, available: b.available, enabledInApp: b.enabledInApp }));
|
|
3824
4383
|
const buyKeyOfSell = selectedSell ? `${selectedSell.code}:${selectedSell.issuer ?? "native"}` : "";
|
|
3825
4384
|
const optKey = (o) => `${o.code}:${o.issuer ?? "native"}`;
|
|
3826
4385
|
const enabledBuy = assetRecords.map((a) => ({
|
|
@@ -3836,7 +4395,31 @@ function SwapModal({ onClose }) {
|
|
|
3836
4395
|
issuer: tk.issuer,
|
|
3837
4396
|
enabledInApp: false
|
|
3838
4397
|
})).filter((o) => !enabledKeys.has(optKey(o)));
|
|
3839
|
-
const
|
|
4398
|
+
const knownKeys = /* @__PURE__ */ new Set([...enabledKeys, ...catalogBuy.map(optKey)]);
|
|
4399
|
+
const customBuy = customTokens.filter((o) => !knownKeys.has(optKey(o)));
|
|
4400
|
+
const buyOptions = [...enabledBuy, ...catalogBuy, ...customBuy].filter((o) => optKey(o) !== buyKeyOfSell);
|
|
4401
|
+
react.useEffect(() => {
|
|
4402
|
+
if (sellOptions.length === 0) return;
|
|
4403
|
+
if (!selectedSell || !sellOptions.some((o) => optKey(o) === optKey(selectedSell))) {
|
|
4404
|
+
setSelectedSell(sellOptions[0]);
|
|
4405
|
+
}
|
|
4406
|
+
}, [sellOptions, selectedSell]);
|
|
4407
|
+
react.useEffect(() => {
|
|
4408
|
+
if (buyOptions.length === 0) return;
|
|
4409
|
+
if (!selectedBuy || !buyOptions.some((o) => optKey(o) === optKey(selectedBuy))) {
|
|
4410
|
+
setSelectedBuy(buyOptions[0]);
|
|
4411
|
+
}
|
|
4412
|
+
}, [buyOptions, selectedBuy]);
|
|
4413
|
+
function addCustomToken(code, issuer) {
|
|
4414
|
+
const c = code.trim().toUpperCase();
|
|
4415
|
+
const i = issuer.trim();
|
|
4416
|
+
if (c.length < 1 || c.length > 12) return "Code must be 1-12 characters";
|
|
4417
|
+
if (i.length !== 56 || !i.startsWith("G")) return "Issuer must be a Stellar address (G..., 56 chars)";
|
|
4418
|
+
const opt = { ref: catalogRef(c, i), code: c, issuer: i, enabledInApp: false };
|
|
4419
|
+
setCustomTokens((prev) => prev.some((o) => optKey(o) === optKey(opt)) ? prev : [...prev, opt]);
|
|
4420
|
+
setSelectedBuy(opt);
|
|
4421
|
+
return null;
|
|
4422
|
+
}
|
|
3840
4423
|
const buyNeedsTrustline = (() => {
|
|
3841
4424
|
if (!selectedBuy || smartUnsupported) return false;
|
|
3842
4425
|
if (selectedBuy.ref.type === "native") return false;
|
|
@@ -3885,7 +4468,7 @@ function SwapModal({ onClose }) {
|
|
|
3885
4468
|
const buildData = "buildData" in transaction ? transaction.buildData : null;
|
|
3886
4469
|
const explorerNetwork = buildData?.summary.network?.toLowerCase().includes("testnet") ? "testnet" : buildData ? "public" : network === "testnet" ? "testnet" : "public";
|
|
3887
4470
|
const explorerUrl = hash ? `https://stellar.expert/explorer/${explorerNetwork}/tx/${hash}` : null;
|
|
3888
|
-
const
|
|
4471
|
+
const IN_FLIGHT_STEPS3 = [
|
|
3889
4472
|
"building",
|
|
3890
4473
|
"signing",
|
|
3891
4474
|
"submitting",
|
|
@@ -3893,7 +4476,7 @@ function SwapModal({ onClose }) {
|
|
|
3893
4476
|
"signing-submitting",
|
|
3894
4477
|
"building-signing-submitting"
|
|
3895
4478
|
];
|
|
3896
|
-
const isInProgress =
|
|
4479
|
+
const isInProgress = IN_FLIGHT_STEPS3.includes(transaction.step);
|
|
3897
4480
|
const showBack = step === "tx" && (transaction.step === "error" || transaction.step === "success") && !isInProgress;
|
|
3898
4481
|
const txTitle = isInProgress ? "Swapping\u2026" : transaction.step === "success" ? "Swapped!" : transaction.step === "error" ? "Swap failed" : "Confirm Swap";
|
|
3899
4482
|
async function handleSwap() {
|
|
@@ -3902,8 +4485,224 @@ function SwapModal({ onClose }) {
|
|
|
3902
4485
|
setFormError("Swaps are not yet supported for smart (passkey) wallets");
|
|
3903
4486
|
return;
|
|
3904
4487
|
}
|
|
3905
|
-
if (!selectedSell || !selectedBuy) {
|
|
3906
|
-
setFormError("Select both assets");
|
|
4488
|
+
if (!selectedSell || !selectedBuy) {
|
|
4489
|
+
setFormError("Select both assets");
|
|
4490
|
+
return;
|
|
4491
|
+
}
|
|
4492
|
+
const parsed = parseFloat(amount);
|
|
4493
|
+
if (!amount || isNaN(parsed) || parsed <= 0) {
|
|
4494
|
+
setFormError("Enter a valid amount");
|
|
4495
|
+
return;
|
|
4496
|
+
}
|
|
4497
|
+
if (selectedSell.available !== void 0 && parsed > parseFloat(selectedSell.available)) {
|
|
4498
|
+
setFormError("Insufficient balance");
|
|
4499
|
+
return;
|
|
4500
|
+
}
|
|
4501
|
+
if (!quote) {
|
|
4502
|
+
setFormError("No route available for this pair");
|
|
4503
|
+
return;
|
|
4504
|
+
}
|
|
4505
|
+
setStep("tx");
|
|
4506
|
+
await swap(quote);
|
|
4507
|
+
}
|
|
4508
|
+
async function handleRetry() {
|
|
4509
|
+
if (transaction.step === "error" && quote) await swap(quote);
|
|
4510
|
+
}
|
|
4511
|
+
function handleCopyHash() {
|
|
4512
|
+
if (!hash) return;
|
|
4513
|
+
navigator.clipboard.writeText(hash).then(() => {
|
|
4514
|
+
setCopied(true);
|
|
4515
|
+
if (copyTimerRef.current !== null) clearTimeout(copyTimerRef.current);
|
|
4516
|
+
copyTimerRef.current = setTimeout(() => {
|
|
4517
|
+
copyTimerRef.current = null;
|
|
4518
|
+
setCopied(false);
|
|
4519
|
+
}, 2e3);
|
|
4520
|
+
});
|
|
4521
|
+
}
|
|
4522
|
+
function handleBack() {
|
|
4523
|
+
setStep("form");
|
|
4524
|
+
setShowXdr(false);
|
|
4525
|
+
setCopied(false);
|
|
4526
|
+
}
|
|
4527
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: !isInProgress ? onClose : void 0, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4528
|
+
SwapModalTemplate,
|
|
4529
|
+
{
|
|
4530
|
+
theme,
|
|
4531
|
+
accentColor,
|
|
4532
|
+
step,
|
|
4533
|
+
txTitle,
|
|
4534
|
+
sellOptions,
|
|
4535
|
+
buyOptions,
|
|
4536
|
+
selectedSell,
|
|
4537
|
+
selectedBuy,
|
|
4538
|
+
amount,
|
|
4539
|
+
provider,
|
|
4540
|
+
providers,
|
|
4541
|
+
quote,
|
|
4542
|
+
quoteLoading,
|
|
4543
|
+
quoteError,
|
|
4544
|
+
formError,
|
|
4545
|
+
isLoadingData,
|
|
4546
|
+
smartUnsupported,
|
|
4547
|
+
configLoading,
|
|
4548
|
+
swapUnavailable,
|
|
4549
|
+
buyNeedsTrustline,
|
|
4550
|
+
transaction,
|
|
4551
|
+
showXdr,
|
|
4552
|
+
copied,
|
|
4553
|
+
explorerUrl,
|
|
4554
|
+
walletType,
|
|
4555
|
+
showBack,
|
|
4556
|
+
isInProgress,
|
|
4557
|
+
onClose,
|
|
4558
|
+
onBack: handleBack,
|
|
4559
|
+
onRefresh: handleRefresh,
|
|
4560
|
+
onSelectSell: setSelectedSell,
|
|
4561
|
+
onSelectBuy: setSelectedBuy,
|
|
4562
|
+
onAddCustomToken: addCustomToken,
|
|
4563
|
+
onAmountChange: setAmount,
|
|
4564
|
+
onProviderChange: setProvider,
|
|
4565
|
+
onSwap: () => void handleSwap(),
|
|
4566
|
+
onToggleXdr: () => setShowXdr((v) => !v),
|
|
4567
|
+
onCopyHash: handleCopyHash,
|
|
4568
|
+
onRetry: () => void handleRetry(),
|
|
4569
|
+
onDone: onClose
|
|
4570
|
+
}
|
|
4571
|
+
) });
|
|
4572
|
+
}
|
|
4573
|
+
var POSITION_POLL_MS = 1e4;
|
|
4574
|
+
var PROVIDER_LABELS2 = {
|
|
4575
|
+
blend: "Blend",
|
|
4576
|
+
defindex: "DeFindex"
|
|
4577
|
+
};
|
|
4578
|
+
var IN_FLIGHT_STEPS2 = [
|
|
4579
|
+
"building",
|
|
4580
|
+
"signing",
|
|
4581
|
+
"submitting",
|
|
4582
|
+
"submitted",
|
|
4583
|
+
"signing-submitting",
|
|
4584
|
+
"building-signing-submitting"
|
|
4585
|
+
];
|
|
4586
|
+
function formatAmount4(value) {
|
|
4587
|
+
const n = parseFloat(value);
|
|
4588
|
+
return isNaN(n) ? value : n.toLocaleString(void 0, { maximumFractionDigits: 7 });
|
|
4589
|
+
}
|
|
4590
|
+
function EarnModal({ onClose }) {
|
|
4591
|
+
const {
|
|
4592
|
+
getEarnProviders,
|
|
4593
|
+
getEarnOpportunities,
|
|
4594
|
+
getEarnPosition,
|
|
4595
|
+
earnDeposit,
|
|
4596
|
+
earnWithdraw,
|
|
4597
|
+
tx: transaction,
|
|
4598
|
+
wallet,
|
|
4599
|
+
network,
|
|
4600
|
+
styles
|
|
4601
|
+
} = usePollar();
|
|
4602
|
+
const walletType = wallet?.custody === "external" ? wallet.provider : null;
|
|
4603
|
+
const smartUnsupported = wallet?.custody === "smart";
|
|
4604
|
+
const { theme = "light", accentColor = "#005DB4" } = styles;
|
|
4605
|
+
const isDark = theme === "dark";
|
|
4606
|
+
const [step, setStep] = react.useState("form");
|
|
4607
|
+
const [tab, setTab] = react.useState("deposit");
|
|
4608
|
+
const [providers, setProviders] = react.useState(null);
|
|
4609
|
+
const [provider, setProvider] = react.useState(null);
|
|
4610
|
+
const [opportunities, setOpportunities] = react.useState([]);
|
|
4611
|
+
const [opportunityId, setOpportunityId] = react.useState("");
|
|
4612
|
+
const [position, setPosition] = react.useState(null);
|
|
4613
|
+
const [amount, setAmount] = react.useState("");
|
|
4614
|
+
const [loadingOpps, setLoadingOpps] = react.useState(false);
|
|
4615
|
+
const [formError, setFormError] = react.useState("");
|
|
4616
|
+
const [refreshing, setRefreshing] = react.useState(false);
|
|
4617
|
+
const [showXdr, setShowXdr] = react.useState(false);
|
|
4618
|
+
const [copied, setCopied] = react.useState(false);
|
|
4619
|
+
const copyTimerRef = react.useRef(null);
|
|
4620
|
+
const loadProviders = react.useCallback(() => {
|
|
4621
|
+
setProviders(null);
|
|
4622
|
+
return getEarnProviders().then((ps) => {
|
|
4623
|
+
setProviders(ps);
|
|
4624
|
+
setProvider((cur) => cur ?? ps[0] ?? null);
|
|
4625
|
+
}).catch(() => setProviders([]));
|
|
4626
|
+
}, [getEarnProviders]);
|
|
4627
|
+
react.useEffect(() => {
|
|
4628
|
+
void loadProviders();
|
|
4629
|
+
}, [loadProviders]);
|
|
4630
|
+
react.useEffect(() => {
|
|
4631
|
+
if (!provider) return;
|
|
4632
|
+
let cancelled = false;
|
|
4633
|
+
setLoadingOpps(true);
|
|
4634
|
+
getEarnOpportunities(provider).then((opps) => {
|
|
4635
|
+
if (cancelled) return;
|
|
4636
|
+
setOpportunities(opps);
|
|
4637
|
+
setOpportunityId((cur) => opps.some((o) => o.id === cur) ? cur : opps[0]?.id ?? "");
|
|
4638
|
+
}).catch(() => {
|
|
4639
|
+
if (!cancelled) setOpportunities([]);
|
|
4640
|
+
}).finally(() => {
|
|
4641
|
+
if (!cancelled) setLoadingOpps(false);
|
|
4642
|
+
});
|
|
4643
|
+
return () => {
|
|
4644
|
+
cancelled = true;
|
|
4645
|
+
};
|
|
4646
|
+
}, [provider, getEarnOpportunities]);
|
|
4647
|
+
const selectedOpportunity = opportunities.find((o) => o.id === opportunityId) ?? null;
|
|
4648
|
+
const refreshPosition = react.useCallback(() => {
|
|
4649
|
+
if (!provider || !opportunityId || !wallet) return;
|
|
4650
|
+
getEarnPosition({ provider, opportunity: opportunityId }).then(setPosition).catch(() => {
|
|
4651
|
+
});
|
|
4652
|
+
}, [provider, opportunityId, wallet, getEarnPosition]);
|
|
4653
|
+
react.useEffect(() => {
|
|
4654
|
+
setPosition(null);
|
|
4655
|
+
refreshPosition();
|
|
4656
|
+
}, [refreshPosition]);
|
|
4657
|
+
react.useEffect(() => {
|
|
4658
|
+
if (step !== "form" || !provider || !opportunityId) return;
|
|
4659
|
+
const id = setInterval(refreshPosition, POSITION_POLL_MS);
|
|
4660
|
+
return () => clearInterval(id);
|
|
4661
|
+
}, [step, provider, opportunityId, refreshPosition]);
|
|
4662
|
+
react.useEffect(
|
|
4663
|
+
() => () => {
|
|
4664
|
+
if (copyTimerRef.current !== null) clearTimeout(copyTimerRef.current);
|
|
4665
|
+
},
|
|
4666
|
+
[]
|
|
4667
|
+
);
|
|
4668
|
+
const providersLoading = providers === null;
|
|
4669
|
+
const earnUnavailable = providers !== null && providers.length === 0;
|
|
4670
|
+
const withdrawUnit = position?.withdrawUnit ?? "asset";
|
|
4671
|
+
const assetCode = selectedOpportunity?.asset.code ?? "";
|
|
4672
|
+
const amountUnitLabel = tab === "deposit" ? assetCode : withdrawUnit === "shares" ? "shares" : assetCode;
|
|
4673
|
+
const hash = transaction.step === "success" ? transaction.hash : null;
|
|
4674
|
+
const buildData = "buildData" in transaction ? transaction.buildData : null;
|
|
4675
|
+
const explorerNetwork = buildData?.summary.network?.toLowerCase().includes("testnet") ? "testnet" : buildData ? "public" : network === "testnet" ? "testnet" : "public";
|
|
4676
|
+
const explorerUrl = hash ? `https://stellar.expert/explorer/${explorerNetwork}/tx/${hash}` : null;
|
|
4677
|
+
const isInProgress = IN_FLIGHT_STEPS2.includes(transaction.step);
|
|
4678
|
+
const showBack = step === "tx" && (transaction.step === "error" || transaction.step === "success") && !isInProgress;
|
|
4679
|
+
const txTitle = isInProgress ? tab === "deposit" ? "Depositing\u2026" : "Withdrawing\u2026" : transaction.step === "success" ? "Done!" : transaction.step === "error" ? tab === "deposit" ? "Deposit failed" : "Withdraw failed" : "Confirm";
|
|
4680
|
+
const canSubmit = !smartUnsupported && !!provider && !!opportunityId && !!amount && parseFloat(amount) > 0 && !providersLoading && !loadingOpps;
|
|
4681
|
+
const cssVars = {
|
|
4682
|
+
"--pollar-accent": accentColor,
|
|
4683
|
+
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
4684
|
+
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
4685
|
+
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
4686
|
+
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
4687
|
+
"--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
|
|
4688
|
+
"--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
|
|
4689
|
+
"--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
|
|
4690
|
+
"--pollar-error-text": isDark ? "#f87171" : "#dc2626",
|
|
4691
|
+
"--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
|
|
4692
|
+
"--pollar-buttons-border-radius": "6px",
|
|
4693
|
+
"--pollar-buttons-height": "44px",
|
|
4694
|
+
"--pollar-input-height": "44px",
|
|
4695
|
+
"--pollar-input-border-radius": "0.5rem",
|
|
4696
|
+
"--pollar-card-border-radius": "10px"
|
|
4697
|
+
};
|
|
4698
|
+
async function handleSubmit() {
|
|
4699
|
+
setFormError("");
|
|
4700
|
+
if (smartUnsupported) {
|
|
4701
|
+
setFormError("Earn is not yet supported for smart (passkey) wallets");
|
|
4702
|
+
return;
|
|
4703
|
+
}
|
|
4704
|
+
if (!provider || !opportunityId) {
|
|
4705
|
+
setFormError("Select a vault or pool");
|
|
3907
4706
|
return;
|
|
3908
4707
|
}
|
|
3909
4708
|
const parsed = parseFloat(amount);
|
|
@@ -3911,19 +4710,23 @@ function SwapModal({ onClose }) {
|
|
|
3911
4710
|
setFormError("Enter a valid amount");
|
|
3912
4711
|
return;
|
|
3913
4712
|
}
|
|
3914
|
-
if (
|
|
3915
|
-
setFormError("
|
|
3916
|
-
return;
|
|
3917
|
-
}
|
|
3918
|
-
if (!quote) {
|
|
3919
|
-
setFormError("No route available for this pair");
|
|
4713
|
+
if (tab === "withdraw" && position && parsed > parseFloat(position.withdrawable)) {
|
|
4714
|
+
setFormError("Amount exceeds your position");
|
|
3920
4715
|
return;
|
|
3921
4716
|
}
|
|
3922
4717
|
setStep("tx");
|
|
3923
|
-
|
|
4718
|
+
const params = { provider, opportunity: opportunityId, amount };
|
|
4719
|
+
const outcome = tab === "deposit" ? await earnDeposit(params) : await earnWithdraw(params);
|
|
4720
|
+
if (outcome.status === "success" || outcome.status === "pending") {
|
|
4721
|
+
setAmount("");
|
|
4722
|
+
refreshPosition();
|
|
4723
|
+
}
|
|
3924
4724
|
}
|
|
3925
4725
|
async function handleRetry() {
|
|
3926
|
-
if (transaction.step
|
|
4726
|
+
if (transaction.step !== "error" || !provider || !opportunityId) return;
|
|
4727
|
+
const params = { provider, opportunity: opportunityId, amount };
|
|
4728
|
+
if (tab === "deposit") await earnDeposit(params);
|
|
4729
|
+
else await earnWithdraw(params);
|
|
3927
4730
|
}
|
|
3928
4731
|
function handleCopyHash() {
|
|
3929
4732
|
if (!hash) return;
|
|
@@ -3940,49 +4743,201 @@ function SwapModal({ onClose }) {
|
|
|
3940
4743
|
setStep("form");
|
|
3941
4744
|
setShowXdr(false);
|
|
3942
4745
|
setCopied(false);
|
|
4746
|
+
refreshPosition();
|
|
3943
4747
|
}
|
|
3944
|
-
|
|
3945
|
-
|
|
4748
|
+
async function handleRefresh() {
|
|
4749
|
+
if (refreshing || !provider) return;
|
|
4750
|
+
setRefreshing(true);
|
|
4751
|
+
try {
|
|
4752
|
+
const opps = await getEarnOpportunities(provider);
|
|
4753
|
+
setOpportunities(opps);
|
|
4754
|
+
setOpportunityId((cur) => opps.some((o) => o.id === cur) ? cur : opps[0]?.id ?? "");
|
|
4755
|
+
refreshPosition();
|
|
4756
|
+
} catch {
|
|
4757
|
+
} finally {
|
|
4758
|
+
setRefreshing(false);
|
|
4759
|
+
}
|
|
4760
|
+
}
|
|
4761
|
+
const title = step === "form" ? "Earn" : txTitle;
|
|
4762
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: !isInProgress ? onClose : void 0, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4763
|
+
"div",
|
|
3946
4764
|
{
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
4765
|
+
className: "pollar-modal-card pollar-send-modal",
|
|
4766
|
+
"data-theme": theme,
|
|
4767
|
+
style: cssVars,
|
|
4768
|
+
onClick: (e) => e.stopPropagation(),
|
|
4769
|
+
children: [
|
|
4770
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
|
|
4771
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-send-header-left", children: [
|
|
4772
|
+
showBack && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-modal-close", onClick: handleBack, "aria-label": "Back", 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: "M10 3L5 8l5 5", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }),
|
|
4773
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: title })
|
|
4774
|
+
] }),
|
|
4775
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
|
|
4776
|
+
step === "form" && !earnUnavailable && !smartUnsupported && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4777
|
+
"button",
|
|
4778
|
+
{
|
|
4779
|
+
type: "button",
|
|
4780
|
+
className: "pollar-modal-close",
|
|
4781
|
+
onClick: () => void handleRefresh(),
|
|
4782
|
+
disabled: refreshing || providersLoading,
|
|
4783
|
+
"aria-label": "Refresh",
|
|
4784
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4785
|
+
"svg",
|
|
4786
|
+
{
|
|
4787
|
+
className: refreshing ? "pollar-modal-refresh-icon pollar-spinning" : "pollar-modal-refresh-icon",
|
|
4788
|
+
width: "16",
|
|
4789
|
+
height: "16",
|
|
4790
|
+
viewBox: "0 0 16 16",
|
|
4791
|
+
fill: "none",
|
|
4792
|
+
"aria-hidden": true,
|
|
4793
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4794
|
+
"path",
|
|
4795
|
+
{
|
|
4796
|
+
d: "M13.5 8a5.5 5.5 0 1 1-1.6-3.9M13.5 2v3h-3",
|
|
4797
|
+
stroke: "currentColor",
|
|
4798
|
+
strokeWidth: "1.6",
|
|
4799
|
+
strokeLinecap: "round",
|
|
4800
|
+
strokeLinejoin: "round"
|
|
4801
|
+
}
|
|
4802
|
+
)
|
|
4803
|
+
}
|
|
4804
|
+
)
|
|
4805
|
+
}
|
|
4806
|
+
),
|
|
4807
|
+
!isInProgress && /* @__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" }) }) })
|
|
4808
|
+
] })
|
|
4809
|
+
] }),
|
|
4810
|
+
step === "form" && providersLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-loading-block", children: [
|
|
4811
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-spinner" }),
|
|
4812
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Loading Earn options\u2026" })
|
|
4813
|
+
] }),
|
|
4814
|
+
step === "form" && earnUnavailable && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: "Earn is not available for this app." }),
|
|
4815
|
+
step === "form" && !earnUnavailable && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4816
|
+
smartUnsupported && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: "Earn is not yet available for smart (passkey) wallets." }),
|
|
4817
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tabs", children: [
|
|
4818
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4819
|
+
"button",
|
|
4820
|
+
{
|
|
4821
|
+
type: "button",
|
|
4822
|
+
className: "pollar-tab",
|
|
4823
|
+
"data-active": tab === "deposit",
|
|
4824
|
+
onClick: () => {
|
|
4825
|
+
setTab("deposit");
|
|
4826
|
+
setFormError("");
|
|
4827
|
+
},
|
|
4828
|
+
children: "Deposit"
|
|
4829
|
+
}
|
|
4830
|
+
),
|
|
4831
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4832
|
+
"button",
|
|
4833
|
+
{
|
|
4834
|
+
type: "button",
|
|
4835
|
+
className: "pollar-tab",
|
|
4836
|
+
"data-active": tab === "withdraw",
|
|
4837
|
+
onClick: () => {
|
|
4838
|
+
setTab("withdraw");
|
|
4839
|
+
setFormError("");
|
|
4840
|
+
},
|
|
4841
|
+
children: "Withdraw"
|
|
4842
|
+
}
|
|
4843
|
+
)
|
|
4844
|
+
] }),
|
|
4845
|
+
providers && providers.length > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-send-field", children: [
|
|
4846
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "pollar-send-label", children: "Provider" }),
|
|
4847
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4848
|
+
"select",
|
|
4849
|
+
{
|
|
4850
|
+
className: "pollar-input pollar-send-select",
|
|
4851
|
+
value: provider ?? "",
|
|
4852
|
+
onChange: (e) => setProvider(e.target.value),
|
|
4853
|
+
children: providers.map((p) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: p, children: PROVIDER_LABELS2[p] }, p))
|
|
4854
|
+
}
|
|
4855
|
+
)
|
|
4856
|
+
] }),
|
|
4857
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-send-field", children: [
|
|
4858
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-send-label-row", children: [
|
|
4859
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "pollar-send-label", children: provider === "defindex" ? "Vault" : "Pool" }),
|
|
4860
|
+
loadingOpps && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-spinner pollar-spinner-sm", "aria-label": "Loading options" })
|
|
4861
|
+
] }),
|
|
4862
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4863
|
+
"select",
|
|
4864
|
+
{
|
|
4865
|
+
className: "pollar-input pollar-send-select",
|
|
4866
|
+
value: opportunityId,
|
|
4867
|
+
disabled: loadingOpps || opportunities.length === 0,
|
|
4868
|
+
onChange: (e) => setOpportunityId(e.target.value),
|
|
4869
|
+
children: opportunities.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: loadingOpps ? "Loading\u2026" : "None available" }) : opportunities.map((o) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: o.id, children: [
|
|
4870
|
+
o.name,
|
|
4871
|
+
" \xB7 ",
|
|
4872
|
+
o.apy.toFixed(2),
|
|
4873
|
+
"% APY"
|
|
4874
|
+
] }, o.id))
|
|
4875
|
+
}
|
|
4876
|
+
)
|
|
4877
|
+
] }),
|
|
4878
|
+
selectedOpportunity && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-swap-quote", children: [
|
|
4879
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-swap-quote-row", children: [
|
|
4880
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-send-hint", children: "Your position" }),
|
|
4881
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
4882
|
+
position ? formatAmount4(position.balance) : "\u2026",
|
|
4883
|
+
" ",
|
|
4884
|
+
assetCode
|
|
4885
|
+
] })
|
|
4886
|
+
] }),
|
|
4887
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-swap-quote-row", children: [
|
|
4888
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-send-hint", children: "APY" }),
|
|
4889
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-earn-live", children: [
|
|
4890
|
+
selectedOpportunity.apy.toFixed(2),
|
|
4891
|
+
"%"
|
|
4892
|
+
] })
|
|
4893
|
+
] })
|
|
4894
|
+
] }),
|
|
4895
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-send-field", children: [
|
|
4896
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-send-label-row", children: [
|
|
4897
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "pollar-send-label", children: tab === "deposit" ? "Amount" : "Withdraw amount" }),
|
|
4898
|
+
tab === "withdraw" && position && /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "pollar-swap-custom-toggle", onClick: () => setAmount(position.withdrawable), children: [
|
|
4899
|
+
"Max: ",
|
|
4900
|
+
formatAmount4(position.withdrawable),
|
|
4901
|
+
" ",
|
|
4902
|
+
amountUnitLabel
|
|
4903
|
+
] })
|
|
4904
|
+
] }),
|
|
4905
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-earn-amount", children: [
|
|
4906
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4907
|
+
"input",
|
|
4908
|
+
{
|
|
4909
|
+
className: "pollar-input",
|
|
4910
|
+
type: "text",
|
|
4911
|
+
inputMode: "decimal",
|
|
4912
|
+
placeholder: "0.00",
|
|
4913
|
+
value: amount,
|
|
4914
|
+
onChange: (e) => setAmount(e.target.value)
|
|
4915
|
+
}
|
|
4916
|
+
),
|
|
4917
|
+
amountUnitLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-earn-amount-unit", children: amountUnitLabel })
|
|
4918
|
+
] })
|
|
4919
|
+
] }),
|
|
4920
|
+
formError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: formError }),
|
|
4921
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-actions", children: /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-btn-primary", onClick: () => void handleSubmit(), disabled: !canSubmit, children: tab === "deposit" ? "Deposit" : "Withdraw" }) })
|
|
4922
|
+
] }),
|
|
4923
|
+
step === "tx" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4924
|
+
TxStatusView,
|
|
4925
|
+
{
|
|
4926
|
+
transaction,
|
|
4927
|
+
showXdr,
|
|
4928
|
+
copied,
|
|
4929
|
+
explorerUrl,
|
|
4930
|
+
walletType,
|
|
4931
|
+
onSignAndSend: () => {
|
|
4932
|
+
},
|
|
4933
|
+
onToggleXdr: () => setShowXdr((v) => !v),
|
|
4934
|
+
onCopyHash: handleCopyHash,
|
|
4935
|
+
onRetry: () => void handleRetry(),
|
|
4936
|
+
onDone: onClose
|
|
4937
|
+
}
|
|
4938
|
+
),
|
|
4939
|
+
/* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
|
|
4940
|
+
]
|
|
3986
4941
|
}
|
|
3987
4942
|
) });
|
|
3988
4943
|
}
|
|
@@ -4077,30 +5032,46 @@ function SessionsModalTemplate({
|
|
|
4077
5032
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
|
|
4078
5033
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Active sessions" }),
|
|
4079
5034
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
|
|
4080
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
5035
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5036
|
+
"button",
|
|
5037
|
+
{
|
|
5038
|
+
type: "button",
|
|
5039
|
+
className: "pollar-modal-close",
|
|
5040
|
+
onClick: onRefresh,
|
|
5041
|
+
disabled: isLoading,
|
|
5042
|
+
"aria-label": "Refresh",
|
|
5043
|
+
title: "Refresh",
|
|
5044
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5045
|
+
"svg",
|
|
5046
|
+
{
|
|
5047
|
+
className: isLoading ? "pollar-modal-refresh-icon pollar-spinning" : "pollar-modal-refresh-icon",
|
|
5048
|
+
width: "16",
|
|
5049
|
+
height: "16",
|
|
5050
|
+
viewBox: "0 0 16 16",
|
|
5051
|
+
fill: "none",
|
|
5052
|
+
"aria-hidden": true,
|
|
5053
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5054
|
+
"path",
|
|
5055
|
+
{
|
|
5056
|
+
d: "M13.5 8a5.5 5.5 0 1 1-1.6-3.9M13.5 2v3h-3",
|
|
5057
|
+
stroke: "currentColor",
|
|
5058
|
+
strokeWidth: "1.6",
|
|
5059
|
+
strokeLinecap: "round",
|
|
5060
|
+
strokeLinejoin: "round"
|
|
5061
|
+
}
|
|
5062
|
+
)
|
|
5063
|
+
}
|
|
5064
|
+
)
|
|
5065
|
+
}
|
|
5066
|
+
),
|
|
4098
5067
|
/* @__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" }) }) })
|
|
4099
5068
|
] })
|
|
4100
5069
|
] }),
|
|
4101
5070
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-sessions-list", children: [
|
|
4102
|
-
state.step === "idle" && /* @__PURE__ */ jsxRuntime.
|
|
4103
|
-
|
|
5071
|
+
(state.step === "idle" || isLoading) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-loading-block", children: [
|
|
5072
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-spinner" }),
|
|
5073
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Loading\u2026" })
|
|
5074
|
+
] }),
|
|
4104
5075
|
state.step === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: state.message }),
|
|
4105
5076
|
state.step === "loaded" && sessions.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No active sessions." }),
|
|
4106
5077
|
sessions.map((s) => {
|
|
@@ -4129,7 +5100,10 @@ function SessionsModalTemplate({
|
|
|
4129
5100
|
className: "pollar-sessions-item-revoke",
|
|
4130
5101
|
onClick: () => onRevoke(s.familyId),
|
|
4131
5102
|
disabled: isRevoking || signingOutEverywhere,
|
|
4132
|
-
children: isRevoking ?
|
|
5103
|
+
children: isRevoking ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5104
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-spinner pollar-spinner-sm pollar-spinner-current" }),
|
|
5105
|
+
"Revoking\u2026"
|
|
5106
|
+
] }) : "Revoke"
|
|
4133
5107
|
}
|
|
4134
5108
|
)
|
|
4135
5109
|
] }, s.familyId);
|
|
@@ -4142,7 +5116,10 @@ function SessionsModalTemplate({
|
|
|
4142
5116
|
onClick: onLogoutEverywhere,
|
|
4143
5117
|
disabled: signingOutEverywhere || otherCount === 0,
|
|
4144
5118
|
title: otherCount === 0 ? "No other devices to sign out" : void 0,
|
|
4145
|
-
children: signingOutEverywhere ?
|
|
5119
|
+
children: signingOutEverywhere ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5120
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-spinner pollar-spinner-sm pollar-spinner-current" }),
|
|
5121
|
+
"Signing out\u2026"
|
|
5122
|
+
] }) : "Sign out everywhere"
|
|
4146
5123
|
}
|
|
4147
5124
|
) }),
|
|
4148
5125
|
/* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
|
|
@@ -4335,6 +5312,33 @@ function StatusBadge({ status }) {
|
|
|
4335
5312
|
function formatDate(iso) {
|
|
4336
5313
|
return new Date(iso).toLocaleDateString(void 0, { month: "short", day: "numeric", year: "numeric" });
|
|
4337
5314
|
}
|
|
5315
|
+
function truncateMiddle(value, head = 4, tail = 4) {
|
|
5316
|
+
return value.length <= head + tail + 1 ? value : `${value.slice(0, head)}\u2026${value.slice(-tail)}`;
|
|
5317
|
+
}
|
|
5318
|
+
var STELLAR_ADDRESS = /\b[GC][A-Z2-7]{55}\b/g;
|
|
5319
|
+
function AddressChip({ value, label }) {
|
|
5320
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-hist-item-issuer", children: [
|
|
5321
|
+
truncateMiddle(value),
|
|
5322
|
+
/* @__PURE__ */ jsxRuntime.jsx(CopyButton, { value, label, className: "pollar-copy-btn-sm" })
|
|
5323
|
+
] });
|
|
5324
|
+
}
|
|
5325
|
+
function renderSummary(summary) {
|
|
5326
|
+
const parts = [];
|
|
5327
|
+
let last = 0;
|
|
5328
|
+
let key = 0;
|
|
5329
|
+
STELLAR_ADDRESS.lastIndex = 0;
|
|
5330
|
+
for (let m = STELLAR_ADDRESS.exec(summary); m !== null; m = STELLAR_ADDRESS.exec(summary)) {
|
|
5331
|
+
if (m.index > last) parts.push(/* @__PURE__ */ jsxRuntime.jsx("span", { children: summary.slice(last, m.index) }, key++));
|
|
5332
|
+
const address = m[0];
|
|
5333
|
+
parts.push(
|
|
5334
|
+
/* @__PURE__ */ jsxRuntime.jsx(AddressChip, { value: address, label: address[0] === "C" ? "Copy contract address" : "Copy wallet address" }, key++)
|
|
5335
|
+
);
|
|
5336
|
+
last = m.index + address.length;
|
|
5337
|
+
}
|
|
5338
|
+
if (parts.length === 0) return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-hist-item-title", children: summary });
|
|
5339
|
+
if (last < summary.length) parts.push(/* @__PURE__ */ jsxRuntime.jsx("span", { children: summary.slice(last) }, key));
|
|
5340
|
+
return parts;
|
|
5341
|
+
}
|
|
4338
5342
|
function TxHistoryModalTemplate({
|
|
4339
5343
|
theme,
|
|
4340
5344
|
accentColor,
|
|
@@ -4380,59 +5384,106 @@ function TxHistoryModalTemplate({
|
|
|
4380
5384
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
|
|
4381
5385
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Transaction History" }),
|
|
4382
5386
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
|
|
4383
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
5387
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5388
|
+
"button",
|
|
5389
|
+
{
|
|
5390
|
+
type: "button",
|
|
5391
|
+
className: "pollar-modal-close",
|
|
5392
|
+
onClick: onRefresh,
|
|
5393
|
+
disabled: isLoading,
|
|
5394
|
+
"aria-label": "Refresh",
|
|
5395
|
+
title: "Refresh",
|
|
5396
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5397
|
+
"svg",
|
|
5398
|
+
{
|
|
5399
|
+
className: isLoading ? "pollar-modal-refresh-icon pollar-spinning" : "pollar-modal-refresh-icon",
|
|
5400
|
+
width: "16",
|
|
5401
|
+
height: "16",
|
|
5402
|
+
viewBox: "0 0 16 16",
|
|
5403
|
+
fill: "none",
|
|
5404
|
+
"aria-hidden": true,
|
|
5405
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5406
|
+
"path",
|
|
5407
|
+
{
|
|
5408
|
+
d: "M13.5 8a5.5 5.5 0 1 1-1.6-3.9M13.5 2v3h-3",
|
|
5409
|
+
stroke: "currentColor",
|
|
5410
|
+
strokeWidth: "1.6",
|
|
5411
|
+
strokeLinecap: "round",
|
|
5412
|
+
strokeLinejoin: "round"
|
|
5413
|
+
}
|
|
5414
|
+
)
|
|
5415
|
+
}
|
|
5416
|
+
)
|
|
5417
|
+
}
|
|
5418
|
+
),
|
|
4401
5419
|
/* @__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" }) }) })
|
|
4402
5420
|
] })
|
|
4403
5421
|
] }),
|
|
4404
5422
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-list", children: [
|
|
4405
5423
|
txHistory.step === "idle" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "Click Refresh to load transactions." }),
|
|
4406
|
-
isLoading && /* @__PURE__ */ jsxRuntime.
|
|
5424
|
+
isLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-loading-block", children: [
|
|
5425
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-spinner" }),
|
|
5426
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Loading\u2026" })
|
|
5427
|
+
] }),
|
|
4407
5428
|
txHistory.step === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: txHistory.message }),
|
|
4408
5429
|
txHistory.step === "loaded" && records.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No transactions yet." }),
|
|
4409
5430
|
records.map((record) => {
|
|
4410
|
-
const
|
|
5431
|
+
const hash = typeof record.hash === "string" && record.hash.length > 0 ? record.hash : void 0;
|
|
5432
|
+
const explorerUrl = hash ? `https://stellar.expert/explorer/${record.network === "testnet" ? "testnet" : "public"}/tx/${hash}` : void 0;
|
|
5433
|
+
const asset = typeof record.details?.asset === "string" ? record.details.asset : void 0;
|
|
5434
|
+
const colon = asset ? asset.indexOf(":") : -1;
|
|
5435
|
+
const trustline = record.operation === "change_trust" && asset && colon > 0 ? {
|
|
5436
|
+
prefix: record.summary.split(":")[0],
|
|
5437
|
+
code: asset.slice(0, colon),
|
|
5438
|
+
issuer: asset.slice(colon + 1)
|
|
5439
|
+
} : void 0;
|
|
5440
|
+
const contract = record.operation === "invoke_contract" && typeof record.details?.contractId === "string" && typeof record.details?.method === "string" ? { method: record.details.method, contractId: record.details.contractId } : void 0;
|
|
4411
5441
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-item", children: [
|
|
4412
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4413
|
-
|
|
5442
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-item-top", children: [
|
|
5443
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-hist-item-summary", children: trustline ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5444
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-hist-item-title", children: [
|
|
5445
|
+
trustline.prefix,
|
|
5446
|
+
": ",
|
|
5447
|
+
trustline.code
|
|
5448
|
+
] }),
|
|
5449
|
+
/* @__PURE__ */ jsxRuntime.jsx(AddressChip, { value: trustline.issuer, label: "Copy issuer" })
|
|
5450
|
+
] }) : contract ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5451
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-hist-item-title", children: [
|
|
5452
|
+
"Invoke ",
|
|
5453
|
+
contract.method,
|
|
5454
|
+
"() on"
|
|
5455
|
+
] }),
|
|
5456
|
+
/* @__PURE__ */ jsxRuntime.jsx(AddressChip, { value: contract.contractId, label: "Copy contract address" })
|
|
5457
|
+
] }) : renderSummary(record.summary) }),
|
|
5458
|
+
/* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: record.status })
|
|
5459
|
+
] }),
|
|
4414
5460
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-hist-item-meta", children: [
|
|
4415
5461
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: record.operation }),
|
|
5462
|
+
typeof record.details?.sponsored === "boolean" && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
5463
|
+
"\xB7 ",
|
|
5464
|
+
record.details.sponsored ? "Sponsored" : "Self-paid"
|
|
5465
|
+
] }),
|
|
4416
5466
|
record.feeXlm && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
4417
5467
|
"\xB7 ",
|
|
4418
5468
|
record.feeXlm,
|
|
4419
5469
|
" XLM"
|
|
4420
|
-
] })
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
"
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
5470
|
+
] })
|
|
5471
|
+
] }),
|
|
5472
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-item-footer", children: [
|
|
5473
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: formatDate(record.createdAt) }),
|
|
5474
|
+
hash && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5475
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-hist-item-dot", children: "\xB7" }),
|
|
5476
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-hist-item-hash", children: truncateMiddle(hash, 6, 6) }),
|
|
5477
|
+
/* @__PURE__ */ jsxRuntime.jsx(CopyButton, { value: hash, label: "Copy transaction hash", className: "pollar-copy-btn-sm" }),
|
|
5478
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5479
|
+
"a",
|
|
5480
|
+
{
|
|
5481
|
+
className: "pollar-hist-item-explorer",
|
|
5482
|
+
href: explorerUrl,
|
|
5483
|
+
target: "_blank",
|
|
5484
|
+
rel: "noopener noreferrer",
|
|
5485
|
+
"aria-label": "View on Stellar Explorer",
|
|
5486
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "12", height: "12", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
|
|
4436
5487
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4437
5488
|
"path",
|
|
4438
5489
|
{
|
|
@@ -4452,11 +5503,10 @@ function TxHistoryModalTemplate({
|
|
|
4452
5503
|
strokeLinejoin: "round"
|
|
4453
5504
|
}
|
|
4454
5505
|
)
|
|
4455
|
-
] })
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
)
|
|
5506
|
+
] })
|
|
5507
|
+
}
|
|
5508
|
+
)
|
|
5509
|
+
] })
|
|
4460
5510
|
] })
|
|
4461
5511
|
] }, record.id);
|
|
4462
5512
|
})
|
|
@@ -4510,7 +5560,7 @@ function TxHistoryModal({ onClose }) {
|
|
|
4510
5560
|
}
|
|
4511
5561
|
function formatBalance2(balance) {
|
|
4512
5562
|
const n = parseFloat(balance);
|
|
4513
|
-
return isNaN(n) ? balance : n.toLocaleString(void 0, { maximumFractionDigits: 7 });
|
|
5563
|
+
return isNaN(n) ? balance : n.toLocaleString(void 0, { minimumFractionDigits: 7, maximumFractionDigits: 7 });
|
|
4514
5564
|
}
|
|
4515
5565
|
function cropAddress2(address) {
|
|
4516
5566
|
if (address.length <= 16) return address;
|
|
@@ -4519,7 +5569,13 @@ function cropAddress2(address) {
|
|
|
4519
5569
|
function BalanceItem({ record }) {
|
|
4520
5570
|
const balanceDiffers = record.balance !== record.available;
|
|
4521
5571
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-bal-item", children: [
|
|
4522
|
-
/* @__PURE__ */ jsxRuntime.
|
|
5572
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-bal-asset-info", children: [
|
|
5573
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-bal-asset", children: record.code }),
|
|
5574
|
+
record.issuer && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-bal-issuer", children: [
|
|
5575
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-bal-issuer-addr", children: cropAddress2(record.issuer) }),
|
|
5576
|
+
/* @__PURE__ */ jsxRuntime.jsx(CopyButton, { value: record.issuer, label: "Copy issuer address", className: "pollar-copy-btn-sm" })
|
|
5577
|
+
] })
|
|
5578
|
+
] }),
|
|
4523
5579
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-bal-amounts", children: [
|
|
4524
5580
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-bal-amount", children: formatBalance2(record.balance) }),
|
|
4525
5581
|
balanceDiffers && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-bal-available", children: [
|
|
@@ -4561,29 +5617,49 @@ function WalletBalanceModalTemplate({
|
|
|
4561
5617
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
|
|
4562
5618
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Wallet Balance" }),
|
|
4563
5619
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
|
|
4564
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
5620
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5621
|
+
"button",
|
|
5622
|
+
{
|
|
5623
|
+
type: "button",
|
|
5624
|
+
className: "pollar-modal-close",
|
|
5625
|
+
onClick: onRefresh,
|
|
5626
|
+
disabled: isLoading,
|
|
5627
|
+
"aria-label": "Refresh",
|
|
5628
|
+
title: "Refresh",
|
|
5629
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5630
|
+
"svg",
|
|
5631
|
+
{
|
|
5632
|
+
className: isLoading ? "pollar-modal-refresh-icon pollar-spinning" : "pollar-modal-refresh-icon",
|
|
5633
|
+
width: "16",
|
|
5634
|
+
height: "16",
|
|
5635
|
+
viewBox: "0 0 16 16",
|
|
5636
|
+
fill: "none",
|
|
5637
|
+
"aria-hidden": true,
|
|
5638
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5639
|
+
"path",
|
|
5640
|
+
{
|
|
5641
|
+
d: "M13.5 8a5.5 5.5 0 1 1-1.6-3.9M13.5 2v3h-3",
|
|
5642
|
+
stroke: "currentColor",
|
|
5643
|
+
strokeWidth: "1.6",
|
|
5644
|
+
strokeLinecap: "round",
|
|
5645
|
+
strokeLinejoin: "round"
|
|
5646
|
+
}
|
|
5647
|
+
)
|
|
5648
|
+
}
|
|
5649
|
+
)
|
|
5650
|
+
}
|
|
5651
|
+
),
|
|
4582
5652
|
/* @__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" }) }) })
|
|
4583
5653
|
] })
|
|
4584
5654
|
] }),
|
|
4585
|
-
walletAddress && /* @__PURE__ */ jsxRuntime.
|
|
4586
|
-
|
|
5655
|
+
walletAddress && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-bal-address-row", children: [
|
|
5656
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-bal-address", children: cropAddress2(walletAddress) }),
|
|
5657
|
+
/* @__PURE__ */ jsxRuntime.jsx(CopyButton, { value: walletAddress, label: "Copy wallet address" })
|
|
5658
|
+
] }),
|
|
5659
|
+
isLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-loading-block", children: [
|
|
5660
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-spinner" }),
|
|
5661
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Loading\u2026" })
|
|
5662
|
+
] }),
|
|
4587
5663
|
walletBalance.step === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: walletBalance.message }),
|
|
4588
5664
|
data && !data.exists && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-empty", children: [
|
|
4589
5665
|
"Account not found on ",
|
|
@@ -4793,6 +5869,7 @@ function PollarProvider({
|
|
|
4793
5869
|
const [enabledAssetsModalOpen, setEnabledAssetsModalOpen] = react.useState(false);
|
|
4794
5870
|
const [sendModalOpen, setSendModalOpen] = react.useState(false);
|
|
4795
5871
|
const [swapModalOpen, setSwapModalOpen] = react.useState(false);
|
|
5872
|
+
const [earnModalOpen, setEarnModalOpen] = react.useState(false);
|
|
4796
5873
|
const [receiveModalOpen, setReceiveModalOpen] = react.useState(false);
|
|
4797
5874
|
const [sessionsModalOpen, setSessionsModalOpen] = react.useState(false);
|
|
4798
5875
|
const [distributionRulesModalOpen, setDistributionRulesModalOpen] = react.useState(false);
|
|
@@ -4843,6 +5920,13 @@ function PollarProvider({
|
|
|
4843
5920
|
getSwapQuote: (params) => pollarClient.getSwapQuote(params),
|
|
4844
5921
|
swap: (quote, opts) => pollarClient.swap(quote, opts),
|
|
4845
5922
|
openSwapModal: () => setSwapModalOpen(true),
|
|
5923
|
+
// earn
|
|
5924
|
+
getEarnProviders: () => pollarClient.getEarnProviders(),
|
|
5925
|
+
getEarnOpportunities: (provider) => pollarClient.getEarnOpportunities(provider),
|
|
5926
|
+
getEarnPosition: (params) => pollarClient.getEarnPosition(params),
|
|
5927
|
+
earnDeposit: (params) => pollarClient.earnDeposit(params),
|
|
5928
|
+
earnWithdraw: (params) => pollarClient.earnWithdraw(params),
|
|
5929
|
+
openEarnModal: () => setEarnModalOpen(true),
|
|
4846
5930
|
// sessions
|
|
4847
5931
|
sessions,
|
|
4848
5932
|
openSessionsModal: () => setSessionsModalOpen(true),
|
|
@@ -4898,6 +5982,7 @@ function PollarProvider({
|
|
|
4898
5982
|
enabledAssetsModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setEnabledAssetsModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(EnabledAssetsModal, { onClose: () => setEnabledAssetsModalOpen(false) }) }),
|
|
4899
5983
|
sendModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setSendModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(SendModal, { onClose: () => setSendModalOpen(false) }) }),
|
|
4900
5984
|
swapModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setSwapModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(SwapModal, { onClose: () => setSwapModalOpen(false) }) }),
|
|
5985
|
+
earnModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setEarnModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(EarnModal, { onClose: () => setEarnModalOpen(false) }) }),
|
|
4901
5986
|
receiveModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setReceiveModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(ReceiveModal, { onClose: () => setReceiveModalOpen(false) }) }),
|
|
4902
5987
|
sessionsModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setSessionsModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(SessionsModal, { onClose: () => setSessionsModalOpen(false) }) }),
|
|
4903
5988
|
distributionRulesModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setDistributionRulesModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(DistributionRulesModal, { onClose: () => setDistributionRulesModalOpen(false) }) })
|
|
@@ -4931,7 +6016,7 @@ function createPollarAdapterHook(key) {
|
|
|
4931
6016
|
};
|
|
4932
6017
|
}
|
|
4933
6018
|
function ButtonLogo() {
|
|
4934
|
-
return /* @__PURE__ */ jsxRuntime.jsx("img", { src: LOGO_POLLAR, alt: "Pollar", width: 22, height: 22, className: "wallet-btn-logo" });
|
|
6019
|
+
return /* @__PURE__ */ jsxRuntime.jsx("img", { src: LOGO_POLLAR, alt: "Pollar", width: 22, height: 22, className: "pollar-wallet-btn-logo" });
|
|
4935
6020
|
}
|
|
4936
6021
|
function cropWallet(address) {
|
|
4937
6022
|
if (address.length <= 12) return address;
|
|
@@ -4947,7 +6032,10 @@ function WalletButtonTemplate({
|
|
|
4947
6032
|
itemColor,
|
|
4948
6033
|
wrapperRef,
|
|
4949
6034
|
isInProgress,
|
|
6035
|
+
showCreateAccount,
|
|
6036
|
+
creatingAccount,
|
|
4950
6037
|
onToggleOpen,
|
|
6038
|
+
onCreateAccount,
|
|
4951
6039
|
onCopy,
|
|
4952
6040
|
onWalletBalance,
|
|
4953
6041
|
onTxHistory,
|
|
@@ -4961,23 +6049,23 @@ function WalletButtonTemplate({
|
|
|
4961
6049
|
onLogin
|
|
4962
6050
|
}) {
|
|
4963
6051
|
if (!walletAddress) {
|
|
4964
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "wallet-login-btn", style: { backgroundColor: accentColor }, onClick: onLogin, children: [
|
|
6052
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "pollar-wallet-login-btn", style: { backgroundColor: accentColor }, onClick: onLogin, children: [
|
|
4965
6053
|
/* @__PURE__ */ jsxRuntime.jsx(ButtonLogo, {}),
|
|
4966
6054
|
"Login with Pollar"
|
|
4967
6055
|
] });
|
|
4968
6056
|
}
|
|
4969
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "wallet-wrapper", ref: wrapperRef, children: [
|
|
6057
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-wallet-wrapper", ref: wrapperRef, children: [
|
|
4970
6058
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4971
6059
|
"button",
|
|
4972
6060
|
{
|
|
4973
|
-
className: "wallet-btn",
|
|
6061
|
+
className: "pollar-wallet-btn",
|
|
4974
6062
|
style: { backgroundColor: accentColor },
|
|
4975
6063
|
onClick: isInProgress ? void 0 : onToggleOpen,
|
|
4976
6064
|
disabled: isInProgress,
|
|
4977
6065
|
"aria-busy": isInProgress,
|
|
4978
6066
|
children: [
|
|
4979
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "wallet-btn-label", children: cropWallet(walletAddress) }),
|
|
4980
|
-
isInProgress ? /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "wallet-btn-spinner", viewBox: "0 0 12 12", width: "12", height: "12", fill: "none", "aria-hidden": true, children: [
|
|
6067
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-wallet-btn-label", children: cropWallet(walletAddress) }),
|
|
6068
|
+
isInProgress ? /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "pollar-wallet-btn-spinner", viewBox: "0 0 12 12", width: "12", height: "12", fill: "none", "aria-hidden": true, children: [
|
|
4981
6069
|
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "6", cy: "6", r: "4.5", stroke: "rgba(255,255,255,0.35)", strokeWidth: "1.5" }),
|
|
4982
6070
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4983
6071
|
"circle",
|
|
@@ -4995,7 +6083,7 @@ function WalletButtonTemplate({
|
|
|
4995
6083
|
] }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
4996
6084
|
"svg",
|
|
4997
6085
|
{
|
|
4998
|
-
className: `wallet-chevron${open ? " open" : ""}`,
|
|
6086
|
+
className: `pollar-wallet-chevron${open ? " pollar-open" : ""}`,
|
|
4999
6087
|
viewBox: "0 0 12 12",
|
|
5000
6088
|
fill: "none",
|
|
5001
6089
|
stroke: "currentColor",
|
|
@@ -5008,8 +6096,42 @@ function WalletButtonTemplate({
|
|
|
5008
6096
|
]
|
|
5009
6097
|
}
|
|
5010
6098
|
),
|
|
5011
|
-
open && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "wallet-dropdown", style: { backgroundColor: dropdownBg, borderColor: dropdownBorder }, children: [
|
|
5012
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
6099
|
+
open && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-wallet-dropdown", style: { backgroundColor: dropdownBg, borderColor: dropdownBorder }, children: [
|
|
6100
|
+
showCreateAccount && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
6101
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
6102
|
+
"button",
|
|
6103
|
+
{
|
|
6104
|
+
className: "pollar-wallet-dropdown-item",
|
|
6105
|
+
style: { color: itemColor },
|
|
6106
|
+
onClick: onCreateAccount,
|
|
6107
|
+
disabled: creatingAccount,
|
|
6108
|
+
children: [
|
|
6109
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
6110
|
+
"svg",
|
|
6111
|
+
{
|
|
6112
|
+
width: "14",
|
|
6113
|
+
height: "14",
|
|
6114
|
+
viewBox: "0 0 24 24",
|
|
6115
|
+
fill: "none",
|
|
6116
|
+
stroke: "currentColor",
|
|
6117
|
+
strokeWidth: "2",
|
|
6118
|
+
strokeLinecap: "round",
|
|
6119
|
+
strokeLinejoin: "round",
|
|
6120
|
+
children: [
|
|
6121
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }),
|
|
6122
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "9", cy: "7", r: "4" }),
|
|
6123
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "19", y1: "8", x2: "19", y2: "14" }),
|
|
6124
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "22", y1: "11", x2: "16", y2: "11" })
|
|
6125
|
+
]
|
|
6126
|
+
}
|
|
6127
|
+
),
|
|
6128
|
+
creatingAccount ? "Creating account\u2026" : "Create account"
|
|
6129
|
+
]
|
|
6130
|
+
}
|
|
6131
|
+
),
|
|
6132
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-wallet-dropdown-divider" })
|
|
6133
|
+
] }),
|
|
6134
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-wallet-dropdown-item", style: { color: itemColor }, onClick: onSend, children: [
|
|
5013
6135
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5014
6136
|
"svg",
|
|
5015
6137
|
{
|
|
@@ -5029,7 +6151,7 @@ function WalletButtonTemplate({
|
|
|
5029
6151
|
),
|
|
5030
6152
|
"Send"
|
|
5031
6153
|
] }),
|
|
5032
|
-
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "wallet-dropdown-item", style: { color: itemColor }, onClick: onReceive, children: [
|
|
6154
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-wallet-dropdown-item", style: { color: itemColor }, onClick: onReceive, children: [
|
|
5033
6155
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5034
6156
|
"svg",
|
|
5035
6157
|
{
|
|
@@ -5050,8 +6172,8 @@ function WalletButtonTemplate({
|
|
|
5050
6172
|
),
|
|
5051
6173
|
"Receive"
|
|
5052
6174
|
] }),
|
|
5053
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "wallet-dropdown-divider" }),
|
|
5054
|
-
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "wallet-dropdown-item", style: { color: itemColor }, onClick: onCopy, children: [
|
|
6175
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-wallet-dropdown-divider" }),
|
|
6176
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-wallet-dropdown-item", style: { color: itemColor }, onClick: onCopy, children: [
|
|
5055
6177
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5056
6178
|
"svg",
|
|
5057
6179
|
{
|
|
@@ -5071,7 +6193,7 @@ function WalletButtonTemplate({
|
|
|
5071
6193
|
),
|
|
5072
6194
|
copied ? "Copied!" : "Copy address"
|
|
5073
6195
|
] }),
|
|
5074
|
-
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "wallet-dropdown-item", style: { color: itemColor }, onClick: onWalletBalance, children: [
|
|
6196
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-wallet-dropdown-item", style: { color: itemColor }, onClick: onWalletBalance, children: [
|
|
5075
6197
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5076
6198
|
"svg",
|
|
5077
6199
|
{
|
|
@@ -5092,7 +6214,7 @@ function WalletButtonTemplate({
|
|
|
5092
6214
|
),
|
|
5093
6215
|
"Wallet balance"
|
|
5094
6216
|
] }),
|
|
5095
|
-
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "wallet-dropdown-item", style: { color: itemColor }, onClick: onTxHistory, children: [
|
|
6217
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-wallet-dropdown-item", style: { color: itemColor }, onClick: onTxHistory, children: [
|
|
5096
6218
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5097
6219
|
"svg",
|
|
5098
6220
|
{
|
|
@@ -5115,8 +6237,8 @@ function WalletButtonTemplate({
|
|
|
5115
6237
|
),
|
|
5116
6238
|
"Transaction history"
|
|
5117
6239
|
] }),
|
|
5118
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "wallet-dropdown-divider" }),
|
|
5119
|
-
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "wallet-dropdown-item", style: { color: itemColor }, onClick: onRamp, children: [
|
|
6240
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-wallet-dropdown-divider" }),
|
|
6241
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-wallet-dropdown-item", style: { color: itemColor }, onClick: onRamp, children: [
|
|
5120
6242
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5121
6243
|
"svg",
|
|
5122
6244
|
{
|
|
@@ -5138,7 +6260,7 @@ function WalletButtonTemplate({
|
|
|
5138
6260
|
),
|
|
5139
6261
|
"Buy / Sell"
|
|
5140
6262
|
] }),
|
|
5141
|
-
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "wallet-dropdown-item", style: { color: itemColor }, onClick: onKyc, children: [
|
|
6263
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-wallet-dropdown-item", style: { color: itemColor }, onClick: onKyc, children: [
|
|
5142
6264
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5143
6265
|
"svg",
|
|
5144
6266
|
{
|
|
@@ -5159,7 +6281,7 @@ function WalletButtonTemplate({
|
|
|
5159
6281
|
),
|
|
5160
6282
|
"Identity verification"
|
|
5161
6283
|
] }),
|
|
5162
|
-
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "wallet-dropdown-item", style: { color: itemColor }, onClick: onDistributionRules, children: [
|
|
6284
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-wallet-dropdown-item", style: { color: itemColor }, onClick: onDistributionRules, children: [
|
|
5163
6285
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5164
6286
|
"svg",
|
|
5165
6287
|
{
|
|
@@ -5182,7 +6304,7 @@ function WalletButtonTemplate({
|
|
|
5182
6304
|
),
|
|
5183
6305
|
"Distribution rules"
|
|
5184
6306
|
] }),
|
|
5185
|
-
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "wallet-dropdown-item", style: { color: itemColor }, onClick: onSessions, children: [
|
|
6307
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-wallet-dropdown-item", style: { color: itemColor }, onClick: onSessions, children: [
|
|
5186
6308
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5187
6309
|
"svg",
|
|
5188
6310
|
{
|
|
@@ -5203,8 +6325,8 @@ function WalletButtonTemplate({
|
|
|
5203
6325
|
),
|
|
5204
6326
|
"Active sessions"
|
|
5205
6327
|
] }),
|
|
5206
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "wallet-dropdown-divider" }),
|
|
5207
|
-
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "wallet-dropdown-item danger", onClick: onLogout, children: [
|
|
6328
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-wallet-dropdown-divider" }),
|
|
6329
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-wallet-dropdown-item pollar-danger", onClick: onLogout, children: [
|
|
5208
6330
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5209
6331
|
"svg",
|
|
5210
6332
|
{
|
|
@@ -5248,9 +6370,12 @@ function WalletButton() {
|
|
|
5248
6370
|
const walletType = wallet?.custody === "external" ? wallet.provider : null;
|
|
5249
6371
|
const [open, setOpen] = react.useState(false);
|
|
5250
6372
|
const [copied, setCopied] = react.useState(false);
|
|
6373
|
+
const [creating, setCreating] = react.useState(false);
|
|
6374
|
+
const [created, setCreated] = react.useState(false);
|
|
5251
6375
|
const wrapperRef = react.useRef(null);
|
|
5252
6376
|
const copyTimerRef = react.useRef(null);
|
|
5253
6377
|
const isInProgress = transaction.step === "building" || transaction.step === "signing";
|
|
6378
|
+
const canCreateAccount = !created && wallet?.custody === "external" && wallet.existsOnStellar === false && wallet.fundingMode === "IMMEDIATE";
|
|
5254
6379
|
const { theme = "light", accentColor = "#005DB4" } = styles;
|
|
5255
6380
|
const isDark = theme === "dark";
|
|
5256
6381
|
const dropdownBg = isDark ? "#18181b" : "#fff";
|
|
@@ -5285,6 +6410,20 @@ function WalletButton() {
|
|
|
5285
6410
|
setOpen(false);
|
|
5286
6411
|
getClient().logout();
|
|
5287
6412
|
}
|
|
6413
|
+
async function handleCreateAccount() {
|
|
6414
|
+
if (creating) return;
|
|
6415
|
+
setCreating(true);
|
|
6416
|
+
try {
|
|
6417
|
+
const res = await getClient().createAccount();
|
|
6418
|
+
if (res.status === "success" || res.status === "pending") {
|
|
6419
|
+
setCreated(true);
|
|
6420
|
+
setOpen(false);
|
|
6421
|
+
await getClient().refreshBalance();
|
|
6422
|
+
}
|
|
6423
|
+
} finally {
|
|
6424
|
+
setCreating(false);
|
|
6425
|
+
}
|
|
6426
|
+
}
|
|
5288
6427
|
function handleWalletBalance() {
|
|
5289
6428
|
setOpen(false);
|
|
5290
6429
|
openWalletBalanceModal();
|
|
@@ -5330,7 +6469,10 @@ function WalletButton() {
|
|
|
5330
6469
|
wrapperRef,
|
|
5331
6470
|
isInProgress,
|
|
5332
6471
|
walletType,
|
|
6472
|
+
showCreateAccount: canCreateAccount,
|
|
6473
|
+
creatingAccount: creating,
|
|
5333
6474
|
onToggleOpen: () => setOpen((v) => !v),
|
|
6475
|
+
onCreateAccount: handleCreateAccount,
|
|
5334
6476
|
onCopy: handleCopy,
|
|
5335
6477
|
onWalletBalance: handleWalletBalance,
|
|
5336
6478
|
onTxHistory: handleTxHistory,
|
|
@@ -5348,6 +6490,7 @@ function WalletButton() {
|
|
|
5348
6490
|
|
|
5349
6491
|
exports.DistributionRulesModal = DistributionRulesModal;
|
|
5350
6492
|
exports.DistributionRulesModalTemplate = DistributionRulesModalTemplate;
|
|
6493
|
+
exports.EarnModal = EarnModal;
|
|
5351
6494
|
exports.EnabledAssetsModal = EnabledAssetsModal;
|
|
5352
6495
|
exports.EnabledAssetsModalTemplate = EnabledAssetsModalTemplate;
|
|
5353
6496
|
exports.KycModal = KycModal;
|