@pollar/react 0.11.1-rc.3 → 0.11.2
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 +103 -33
- package/dist/index.css +173 -124
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +150 -15
- package/dist/index.d.ts +150 -15
- package/dist/index.js +366 -94
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +364 -97
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -3
package/dist/index.js
CHANGED
|
@@ -1035,7 +1035,7 @@ var PollarModalFooter = () => {
|
|
|
1035
1035
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-footer-name", children: "Pollar" }),
|
|
1036
1036
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-footer-version", children: [
|
|
1037
1037
|
"v",
|
|
1038
|
-
"0.11.
|
|
1038
|
+
"0.11.2"
|
|
1039
1039
|
] })
|
|
1040
1040
|
] })
|
|
1041
1041
|
] });
|
|
@@ -1101,6 +1101,36 @@ function ModalStatusBanner({ message, status, onCancel, onRetry }) {
|
|
|
1101
1101
|
status === "ERROR" && onRetry && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-status-cancel", onClick: onRetry, children: "Retry" })
|
|
1102
1102
|
] });
|
|
1103
1103
|
}
|
|
1104
|
+
function cropAddress(address) {
|
|
1105
|
+
if (address.length <= 16) return address;
|
|
1106
|
+
return `${address.slice(0, 8)}...${address.slice(-8)}`;
|
|
1107
|
+
}
|
|
1108
|
+
function useStickyData(data) {
|
|
1109
|
+
const lastRef = react.useRef(null);
|
|
1110
|
+
if (data !== null) lastRef.current = data;
|
|
1111
|
+
return data ?? lastRef.current;
|
|
1112
|
+
}
|
|
1113
|
+
function BusyOverlay({ label = "Loading\u2026" }) {
|
|
1114
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-busy-overlay", "aria-busy": "true", "aria-live": "polite", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-busy-overlay-inner", children: [
|
|
1115
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-spinner" }),
|
|
1116
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: label })
|
|
1117
|
+
] }) });
|
|
1118
|
+
}
|
|
1119
|
+
function Toggle({ checked, onChange, disabled = false, busy = false, label }) {
|
|
1120
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1121
|
+
"button",
|
|
1122
|
+
{
|
|
1123
|
+
type: "button",
|
|
1124
|
+
role: "switch",
|
|
1125
|
+
"aria-checked": checked,
|
|
1126
|
+
"aria-label": label,
|
|
1127
|
+
className: `pollar-switch${checked ? " pollar-switch-on" : ""}${busy ? " pollar-switch-busy" : ""}`,
|
|
1128
|
+
onClick: onChange,
|
|
1129
|
+
disabled: disabled || busy,
|
|
1130
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-switch-knob", children: busy && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-spinner pollar-spinner-sm pollar-spinner-current" }) })
|
|
1131
|
+
}
|
|
1132
|
+
);
|
|
1133
|
+
}
|
|
1104
1134
|
var PERIOD_LABEL = {
|
|
1105
1135
|
DAY: "every 24h",
|
|
1106
1136
|
DAY_CALENDAR: "daily",
|
|
@@ -1328,9 +1358,66 @@ function DistributionRulesModal({ onClose }) {
|
|
|
1328
1358
|
}
|
|
1329
1359
|
) });
|
|
1330
1360
|
}
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1361
|
+
var CHAIN_LABEL = {
|
|
1362
|
+
STELLAR: "Stellar",
|
|
1363
|
+
POLYGON: "Polygon",
|
|
1364
|
+
SOLANA: "Solana"
|
|
1365
|
+
};
|
|
1366
|
+
function resolveChain(chain) {
|
|
1367
|
+
return chain ?? "STELLAR";
|
|
1368
|
+
}
|
|
1369
|
+
function chainsOf(wallets, order) {
|
|
1370
|
+
const held = [];
|
|
1371
|
+
for (const w of wallets) {
|
|
1372
|
+
const chain = resolveChain(w.chain);
|
|
1373
|
+
if (!held.includes(chain)) held.push(chain);
|
|
1374
|
+
}
|
|
1375
|
+
if (!order || order.length === 0) return held;
|
|
1376
|
+
return order.filter((c) => held.includes(c));
|
|
1377
|
+
}
|
|
1378
|
+
function addressForChain(wallets, chain) {
|
|
1379
|
+
if (!chain) return "";
|
|
1380
|
+
return wallets.find((w) => resolveChain(w.chain) === chain)?.address ?? "";
|
|
1381
|
+
}
|
|
1382
|
+
function ChainSelect({ label = "Network", value, options, onChange, disabled = false }) {
|
|
1383
|
+
if (options.length < 2) return null;
|
|
1384
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-send-field pollar-chain-field", children: [
|
|
1385
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "pollar-send-label", children: label }),
|
|
1386
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1387
|
+
"select",
|
|
1388
|
+
{
|
|
1389
|
+
className: "pollar-input pollar-send-select",
|
|
1390
|
+
value: value ?? "",
|
|
1391
|
+
disabled,
|
|
1392
|
+
onChange: (e) => onChange(e.target.value),
|
|
1393
|
+
children: [
|
|
1394
|
+
value === null && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, hidden: true }),
|
|
1395
|
+
options.map((chain) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: chain, children: CHAIN_LABEL[chain] ?? chain }, chain))
|
|
1396
|
+
]
|
|
1397
|
+
}
|
|
1398
|
+
)
|
|
1399
|
+
] });
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
// src/useChains.ts
|
|
1403
|
+
function useChains() {
|
|
1404
|
+
const { wallets, appConfig, configStatus } = usePollar();
|
|
1405
|
+
const configured = appConfig?.application?.chains;
|
|
1406
|
+
const ready = configStatus === "ready";
|
|
1407
|
+
return react.useMemo(() => {
|
|
1408
|
+
if (!ready) {
|
|
1409
|
+
const fallback = chainsOf(wallets);
|
|
1410
|
+
return {
|
|
1411
|
+
chains: [],
|
|
1412
|
+
primaryChain: null,
|
|
1413
|
+
primaryAddress: addressForChain(wallets, fallback[0] ?? null),
|
|
1414
|
+
ready: false
|
|
1415
|
+
};
|
|
1416
|
+
}
|
|
1417
|
+
const chains = chainsOf(wallets, configured);
|
|
1418
|
+
const primaryChain = chains[0] ?? null;
|
|
1419
|
+
return { chains, primaryChain, primaryAddress: addressForChain(wallets, primaryChain), ready: true };
|
|
1420
|
+
}, [wallets, configured, ready]);
|
|
1334
1421
|
}
|
|
1335
1422
|
function cssVarsFor(theme, accentColor) {
|
|
1336
1423
|
const isDark = theme === "dark";
|
|
@@ -1355,14 +1442,18 @@ function cssVarsFor(theme, accentColor) {
|
|
|
1355
1442
|
function assetKey(record) {
|
|
1356
1443
|
return record.code + (record.issuer ?? "");
|
|
1357
1444
|
}
|
|
1445
|
+
function rowKey(record) {
|
|
1446
|
+
return (record.chain ?? "") + assetKey(record);
|
|
1447
|
+
}
|
|
1358
1448
|
function AssetItem({
|
|
1359
1449
|
record,
|
|
1360
1450
|
busy,
|
|
1361
1451
|
disabled,
|
|
1362
1452
|
onToggle
|
|
1363
1453
|
}) {
|
|
1364
|
-
const established = record.trustlineEstablished;
|
|
1454
|
+
const established = record.trustlineEstablished ?? false;
|
|
1365
1455
|
const isNative = record.type === "native";
|
|
1456
|
+
const isStellar = resolveChain(record.chain) === "STELLAR";
|
|
1366
1457
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-asset-item", children: [
|
|
1367
1458
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-asset-info", children: [
|
|
1368
1459
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-asset-code-row", children: [
|
|
@@ -1370,17 +1461,22 @@ function AssetItem({
|
|
|
1370
1461
|
record.enabledInApp && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-asset-tag", children: "App" })
|
|
1371
1462
|
] }),
|
|
1372
1463
|
record.name && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-asset-name", children: record.name }),
|
|
1373
|
-
|
|
1464
|
+
record.issuer && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-issuer", children: [
|
|
1465
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-issuer-addr", children: cropAddress(record.issuer) }),
|
|
1466
|
+
/* @__PURE__ */ jsxRuntime.jsx(CopyButton, { value: record.issuer, label: "Copy issuer address", className: "pollar-copy-btn-sm" })
|
|
1467
|
+
] }),
|
|
1468
|
+
isStellar && !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)" })
|
|
1374
1469
|
] }),
|
|
1375
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-asset-actions", children: [
|
|
1376
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className:
|
|
1377
|
-
|
|
1378
|
-
|
|
1470
|
+
isStellar && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-asset-actions", children: [
|
|
1471
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-asset-trustline-label", children: "Trustline" }),
|
|
1472
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1473
|
+
Toggle,
|
|
1379
1474
|
{
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
disabled:
|
|
1383
|
-
|
|
1475
|
+
checked: established,
|
|
1476
|
+
busy,
|
|
1477
|
+
disabled: isNative || disabled,
|
|
1478
|
+
onChange: () => onToggle(record),
|
|
1479
|
+
label: `${established ? "Disable" : "Enable"} ${record.code} trustline`
|
|
1384
1480
|
}
|
|
1385
1481
|
)
|
|
1386
1482
|
] })
|
|
@@ -1391,6 +1487,9 @@ function EnabledAssetsModalTemplate({
|
|
|
1391
1487
|
accentColor,
|
|
1392
1488
|
enabledAssets,
|
|
1393
1489
|
walletAddress,
|
|
1490
|
+
chains,
|
|
1491
|
+
selectedChain,
|
|
1492
|
+
onSelectChain,
|
|
1394
1493
|
busyKey,
|
|
1395
1494
|
actionError,
|
|
1396
1495
|
onRefresh,
|
|
@@ -1400,8 +1499,10 @@ function EnabledAssetsModalTemplate({
|
|
|
1400
1499
|
}) {
|
|
1401
1500
|
const cssVars = cssVarsFor(theme, accentColor);
|
|
1402
1501
|
const isLoading = enabledAssets.step === "loading";
|
|
1403
|
-
const data = enabledAssets.step === "loaded" ? enabledAssets.data : null;
|
|
1502
|
+
const data = useStickyData(enabledAssets.step === "loaded" ? enabledAssets.data : null);
|
|
1404
1503
|
const busy = busyKey !== null;
|
|
1504
|
+
const assets = (data?.assets ?? []).filter((a) => resolveChain(a.chain) === selectedChain);
|
|
1505
|
+
const isStellarSelected = selectedChain === "STELLAR";
|
|
1405
1506
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1406
1507
|
"div",
|
|
1407
1508
|
{
|
|
@@ -1410,8 +1511,9 @@ function EnabledAssetsModalTemplate({
|
|
|
1410
1511
|
style: cssVars,
|
|
1411
1512
|
onClick: (e) => e.stopPropagation(),
|
|
1412
1513
|
children: [
|
|
1514
|
+
isLoading && data && /* @__PURE__ */ jsxRuntime.jsx(BusyOverlay, { label: "Refreshing assets\u2026" }),
|
|
1413
1515
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
|
|
1414
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "
|
|
1516
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Assets" }),
|
|
1415
1517
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
|
|
1416
1518
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1417
1519
|
"button",
|
|
@@ -1448,8 +1550,12 @@ function EnabledAssetsModalTemplate({
|
|
|
1448
1550
|
/* @__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" }) }) })
|
|
1449
1551
|
] })
|
|
1450
1552
|
] }),
|
|
1451
|
-
|
|
1452
|
-
|
|
1553
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChainSelect, { value: selectedChain, options: chains, onChange: onSelectChain, disabled: isLoading || busy }),
|
|
1554
|
+
walletAddress && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-address-row", children: [
|
|
1555
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-address", children: cropAddress(walletAddress) }),
|
|
1556
|
+
/* @__PURE__ */ jsxRuntime.jsx(CopyButton, { value: walletAddress, label: "Copy wallet address" })
|
|
1557
|
+
] }),
|
|
1558
|
+
isLoading && !data && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-loading-block", children: [
|
|
1453
1559
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-spinner" }),
|
|
1454
1560
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Loading\u2026" })
|
|
1455
1561
|
] }),
|
|
@@ -1460,8 +1566,8 @@ function EnabledAssetsModalTemplate({
|
|
|
1460
1566
|
data.network,
|
|
1461
1567
|
"."
|
|
1462
1568
|
] }),
|
|
1463
|
-
data &&
|
|
1464
|
-
data &&
|
|
1569
|
+
data && assets.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No assets found on this network." }),
|
|
1570
|
+
data && assets.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-asset-list", children: assets.map((a) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1465
1571
|
AssetItem,
|
|
1466
1572
|
{
|
|
1467
1573
|
record: a,
|
|
@@ -1469,9 +1575,9 @@ function EnabledAssetsModalTemplate({
|
|
|
1469
1575
|
disabled: busy && busyKey !== assetKey(a),
|
|
1470
1576
|
onToggle: onToggleTrustline
|
|
1471
1577
|
},
|
|
1472
|
-
|
|
1578
|
+
rowKey(a)
|
|
1473
1579
|
)) }),
|
|
1474
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-asset-add-custom", onClick: onAddCustom, disabled: busy, children: "+ Add custom trustline" }),
|
|
1580
|
+
isStellarSelected && /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-asset-add-custom", onClick: onAddCustom, disabled: busy, children: "+ Add custom trustline" }),
|
|
1475
1581
|
/* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
|
|
1476
1582
|
]
|
|
1477
1583
|
}
|
|
@@ -1585,9 +1691,14 @@ function assetKey2(record) {
|
|
|
1585
1691
|
return record.code + (record.issuer ?? "");
|
|
1586
1692
|
}
|
|
1587
1693
|
function EnabledAssetsModal({ onClose }) {
|
|
1588
|
-
const { enabledAssets, refreshAssets, setTrustline,
|
|
1589
|
-
const walletAddress = wallet?.address ?? "";
|
|
1694
|
+
const { enabledAssets, refreshAssets, setTrustline, wallets, styles } = usePollar();
|
|
1590
1695
|
const { theme = "light", accentColor = "#005DB4" } = styles;
|
|
1696
|
+
const { chains } = useChains();
|
|
1697
|
+
const [selectedChain, setSelectedChain] = react.useState(null);
|
|
1698
|
+
react.useEffect(() => {
|
|
1699
|
+
if (selectedChain === null && chains.length > 0) setSelectedChain(chains[0]);
|
|
1700
|
+
}, [chains, selectedChain]);
|
|
1701
|
+
const walletAddress = addressForChain(wallets, selectedChain);
|
|
1591
1702
|
const [view, setView] = react.useState("list");
|
|
1592
1703
|
const [busyKey, setBusyKey] = react.useState(null);
|
|
1593
1704
|
const [actionError, setActionError] = react.useState(null);
|
|
@@ -1616,7 +1727,7 @@ function EnabledAssetsModal({ onClose }) {
|
|
|
1616
1727
|
void runAction(
|
|
1617
1728
|
assetKey2(record),
|
|
1618
1729
|
{ code: record.code, issuer: record.issuer ?? "" },
|
|
1619
|
-
{ ...removing ? { limit: "0" } : {}
|
|
1730
|
+
{ ...removing ? { limit: "0" } : {} }
|
|
1620
1731
|
);
|
|
1621
1732
|
},
|
|
1622
1733
|
[runAction]
|
|
@@ -1626,7 +1737,7 @@ function EnabledAssetsModal({ onClose }) {
|
|
|
1626
1737
|
const ok = await runAction(
|
|
1627
1738
|
"custom",
|
|
1628
1739
|
{ code: input.code, issuer: input.issuer },
|
|
1629
|
-
{ ...input.limit ? { limit: input.limit } : {},
|
|
1740
|
+
{ ...input.limit ? { limit: input.limit } : {}, skipSponsorship: true }
|
|
1630
1741
|
);
|
|
1631
1742
|
if (ok) setView("list");
|
|
1632
1743
|
},
|
|
@@ -1639,6 +1750,9 @@ function EnabledAssetsModal({ onClose }) {
|
|
|
1639
1750
|
accentColor,
|
|
1640
1751
|
enabledAssets,
|
|
1641
1752
|
walletAddress,
|
|
1753
|
+
chains,
|
|
1754
|
+
selectedChain,
|
|
1755
|
+
onSelectChain: setSelectedChain,
|
|
1642
1756
|
busyKey,
|
|
1643
1757
|
actionError,
|
|
1644
1758
|
onRefresh: () => refreshAssets(),
|
|
@@ -3357,10 +3471,18 @@ var QRCode = react.forwardRef(function QRCode2({ bgColor = "#FFFFFF", fgColor =
|
|
|
3357
3471
|
}
|
|
3358
3472
|
);
|
|
3359
3473
|
});
|
|
3474
|
+
var CHAIN_NAME = {
|
|
3475
|
+
STELLAR: "Stellar",
|
|
3476
|
+
POLYGON: "Polygon",
|
|
3477
|
+
SOLANA: "Solana"
|
|
3478
|
+
};
|
|
3360
3479
|
function ReceiveModalTemplate({
|
|
3361
3480
|
theme,
|
|
3362
3481
|
accentColor,
|
|
3363
3482
|
walletAddress,
|
|
3483
|
+
chains,
|
|
3484
|
+
selectedChain,
|
|
3485
|
+
onSelectChain,
|
|
3364
3486
|
copied,
|
|
3365
3487
|
onCopy,
|
|
3366
3488
|
onClose
|
|
@@ -3383,6 +3505,7 @@ function ReceiveModalTemplate({
|
|
|
3383
3505
|
"--pollar-input-border-radius": "0.5rem",
|
|
3384
3506
|
"--pollar-card-border-radius": "10px"
|
|
3385
3507
|
};
|
|
3508
|
+
const chainName = selectedChain ? CHAIN_NAME[selectedChain] ?? selectedChain : "wallet";
|
|
3386
3509
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3387
3510
|
"div",
|
|
3388
3511
|
{
|
|
@@ -3395,9 +3518,16 @@ function ReceiveModalTemplate({
|
|
|
3395
3518
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Receive" }),
|
|
3396
3519
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-header-actions", children: /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-modal-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2 2l12 12M14 2L2 14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) }) })
|
|
3397
3520
|
] }),
|
|
3521
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChainSelect, { value: selectedChain, options: chains, onChange: onSelectChain }),
|
|
3398
3522
|
walletAddress ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3399
3523
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-receive-qr", children: /* @__PURE__ */ jsxRuntime.jsx(QRCode, { value: walletAddress, size: 180, fgColor: isDark ? "#ffffff" : "#111827", bgColor: "transparent" }) }),
|
|
3400
|
-
/* @__PURE__ */ jsxRuntime.
|
|
3524
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "pollar-receive-instructions", children: [
|
|
3525
|
+
"Share your ",
|
|
3526
|
+
chainName,
|
|
3527
|
+
" address to receive any asset. Only send ",
|
|
3528
|
+
chainName,
|
|
3529
|
+
" assets to this address. Funds sent from another network are lost."
|
|
3530
|
+
] }),
|
|
3401
3531
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-receive-address-row", children: [
|
|
3402
3532
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-receive-address", children: walletAddress }),
|
|
3403
3533
|
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-receive-copy-btn", onClick: onCopy, "aria-label": "Copy address", children: copied ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -3438,11 +3568,16 @@ function ReceiveModalTemplate({
|
|
|
3438
3568
|
);
|
|
3439
3569
|
}
|
|
3440
3570
|
function ReceiveModal({ onClose }) {
|
|
3441
|
-
const {
|
|
3442
|
-
const walletAddress = wallet?.address ?? "";
|
|
3571
|
+
const { wallets, styles } = usePollar();
|
|
3443
3572
|
const { theme = "light", accentColor = "#005DB4" } = styles;
|
|
3444
3573
|
const [copied, setCopied] = react.useState(false);
|
|
3445
3574
|
const copyTimerRef = react.useRef(null);
|
|
3575
|
+
const { chains } = useChains();
|
|
3576
|
+
const [selectedChain, setSelectedChain] = react.useState(null);
|
|
3577
|
+
react.useEffect(() => {
|
|
3578
|
+
if (selectedChain === null && chains.length > 0) setSelectedChain(chains[0]);
|
|
3579
|
+
}, [chains, selectedChain]);
|
|
3580
|
+
const walletAddress = addressForChain(wallets, selectedChain);
|
|
3446
3581
|
react.useEffect(
|
|
3447
3582
|
() => () => {
|
|
3448
3583
|
if (copyTimerRef.current !== null) clearTimeout(copyTimerRef.current);
|
|
@@ -3466,6 +3601,12 @@ function ReceiveModal({ onClose }) {
|
|
|
3466
3601
|
theme,
|
|
3467
3602
|
accentColor,
|
|
3468
3603
|
walletAddress,
|
|
3604
|
+
chains,
|
|
3605
|
+
selectedChain,
|
|
3606
|
+
onSelectChain: (chain) => {
|
|
3607
|
+
setCopied(false);
|
|
3608
|
+
setSelectedChain(chain);
|
|
3609
|
+
},
|
|
3469
3610
|
copied,
|
|
3470
3611
|
onCopy: handleCopy,
|
|
3471
3612
|
onClose
|
|
@@ -3711,6 +3852,7 @@ function TxStatusView({
|
|
|
3711
3852
|
] });
|
|
3712
3853
|
}
|
|
3713
3854
|
function formatBalance(balance) {
|
|
3855
|
+
if (balance === null) return "\u2014";
|
|
3714
3856
|
const n = parseFloat(balance);
|
|
3715
3857
|
return isNaN(n) ? balance : n.toLocaleString(void 0, { maximumFractionDigits: 7 });
|
|
3716
3858
|
}
|
|
@@ -3724,6 +3866,11 @@ function SendModalTemplate({
|
|
|
3724
3866
|
txTitle,
|
|
3725
3867
|
assets,
|
|
3726
3868
|
selectedAsset,
|
|
3869
|
+
chains,
|
|
3870
|
+
selectedChain,
|
|
3871
|
+
walletAddress,
|
|
3872
|
+
canSendOnChain,
|
|
3873
|
+
onSelectChain,
|
|
3727
3874
|
amount,
|
|
3728
3875
|
destination,
|
|
3729
3876
|
formError,
|
|
@@ -3767,7 +3914,7 @@ function SendModalTemplate({
|
|
|
3767
3914
|
"--pollar-card-border-radius": "10px"
|
|
3768
3915
|
};
|
|
3769
3916
|
const selectedKey = selectedAsset ? assetKey3(selectedAsset) : "";
|
|
3770
|
-
const canSubmit = !!selectedAsset && !!amount && !!destination.trim() && !isLoadingBalance;
|
|
3917
|
+
const canSubmit = canSendOnChain && !!selectedAsset && !!amount && !!destination.trim() && !isLoadingBalance;
|
|
3771
3918
|
const title = step === "form" ? "Send" : txTitle;
|
|
3772
3919
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3773
3920
|
"div",
|
|
@@ -3819,6 +3966,12 @@ function SendModalTemplate({
|
|
|
3819
3966
|
] })
|
|
3820
3967
|
] }),
|
|
3821
3968
|
step === "form" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3969
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChainSelect, { value: selectedChain, options: chains, onChange: onSelectChain, disabled: isLoadingBalance }),
|
|
3970
|
+
walletAddress && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-address-row", children: [
|
|
3971
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-address", children: cropAddress(walletAddress) }),
|
|
3972
|
+
/* @__PURE__ */ jsxRuntime.jsx(CopyButton, { value: walletAddress, label: "Copy wallet address" })
|
|
3973
|
+
] }),
|
|
3974
|
+
!canSendOnChain && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "Sending is not available on this network yet." }),
|
|
3822
3975
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3823
3976
|
AssetSelect,
|
|
3824
3977
|
{
|
|
@@ -3829,7 +3982,9 @@ function SendModalTemplate({
|
|
|
3829
3982
|
options: assets.map((a) => ({
|
|
3830
3983
|
key: assetKey3(a),
|
|
3831
3984
|
code: a.code,
|
|
3832
|
-
available
|
|
3985
|
+
// Unreadable (null) drops the "— X available" suffix instead of
|
|
3986
|
+
// claiming a zero balance.
|
|
3987
|
+
available: a.available ?? void 0,
|
|
3833
3988
|
enabledInApp: a.enabledInApp
|
|
3834
3989
|
})),
|
|
3835
3990
|
onChange: (key) => {
|
|
@@ -3908,9 +4063,11 @@ function SendModal({ onClose }) {
|
|
|
3908
4063
|
walletBalance,
|
|
3909
4064
|
refreshWalletBalance,
|
|
3910
4065
|
buildTx,
|
|
4066
|
+
sendPayment,
|
|
3911
4067
|
signAndSubmitTx,
|
|
3912
4068
|
tx: transaction,
|
|
3913
4069
|
wallet,
|
|
4070
|
+
wallets,
|
|
3914
4071
|
network,
|
|
3915
4072
|
styles
|
|
3916
4073
|
} = usePollar();
|
|
@@ -3924,6 +4081,14 @@ function SendModal({ onClose }) {
|
|
|
3924
4081
|
const [copied, setCopied] = react.useState(false);
|
|
3925
4082
|
const [formError, setFormError] = react.useState("");
|
|
3926
4083
|
const copyTimerRef = react.useRef(null);
|
|
4084
|
+
const { chains } = useChains();
|
|
4085
|
+
const [selectedChain, setSelectedChain] = react.useState(null);
|
|
4086
|
+
react.useEffect(() => {
|
|
4087
|
+
if (selectedChain === null && chains.length > 0) setSelectedChain(chains[0]);
|
|
4088
|
+
}, [chains, selectedChain]);
|
|
4089
|
+
const walletAddress = addressForChain(wallets, selectedChain);
|
|
4090
|
+
const canSendOnChain = selectedChain === "STELLAR" || selectedChain === "SOLANA";
|
|
4091
|
+
const isBaseUnitChain = selectedChain === "SOLANA";
|
|
3927
4092
|
react.useEffect(() => {
|
|
3928
4093
|
void refreshWalletBalance();
|
|
3929
4094
|
}, [refreshWalletBalance]);
|
|
@@ -3934,18 +4099,24 @@ function SendModal({ onClose }) {
|
|
|
3934
4099
|
[]
|
|
3935
4100
|
);
|
|
3936
4101
|
const balanceData = walletBalance.step === "loaded" ? walletBalance.data : null;
|
|
3937
|
-
const allAssets = (balanceData?.balances ?? []).filter((b) => b.chain ===
|
|
4102
|
+
const allAssets = (balanceData?.balances ?? []).filter((b) => resolveChain(b.chain) === selectedChain);
|
|
3938
4103
|
const sortedAssets = [
|
|
3939
4104
|
...allAssets.filter((b) => b.enabledInApp),
|
|
3940
|
-
|
|
4105
|
+
// An unreadable balance (null) is not a positive one, so it stays out.
|
|
4106
|
+
...allAssets.filter((b) => !b.enabledInApp && (b.type === "native" || parseFloat(b.balance ?? "0") > 0))
|
|
3941
4107
|
];
|
|
3942
4108
|
react.useEffect(() => {
|
|
4109
|
+
const stranded = selectedAsset !== null && resolveChain(selectedAsset.chain) !== selectedChain;
|
|
4110
|
+
if (stranded) {
|
|
4111
|
+
setSelectedAsset(sortedAssets[0] ?? null);
|
|
4112
|
+
return;
|
|
4113
|
+
}
|
|
3943
4114
|
if (!selectedAsset && sortedAssets.length > 0) setSelectedAsset(sortedAssets[0]);
|
|
3944
|
-
}, [sortedAssets, selectedAsset]);
|
|
4115
|
+
}, [sortedAssets, selectedAsset, selectedChain]);
|
|
3945
4116
|
const hash = transaction.step === "success" ? transaction.hash : null;
|
|
3946
4117
|
const buildData = "buildData" in transaction ? transaction.buildData : null;
|
|
3947
4118
|
const explorerNetwork = buildData?.summary.network?.toLowerCase().includes("testnet") ? "testnet" : buildData ? "public" : network === "testnet" ? "testnet" : "public";
|
|
3948
|
-
const explorerUrl = hash ? `https://stellar.expert/explorer/${explorerNetwork}/tx/${hash}
|
|
4119
|
+
const explorerUrl = !hash ? null : selectedChain === "SOLANA" ? `https://explorer.solana.com/tx/${hash}${explorerNetwork === "testnet" ? "?cluster=devnet" : ""}` : `https://stellar.expert/explorer/${explorerNetwork}/tx/${hash}`;
|
|
3949
4120
|
const IN_FLIGHT_STEPS3 = [
|
|
3950
4121
|
"building",
|
|
3951
4122
|
"signing",
|
|
@@ -3959,6 +4130,10 @@ function SendModal({ onClose }) {
|
|
|
3959
4130
|
const txTitle = isInProgress ? "Sending\u2026" : transaction.step === "success" ? "Sent!" : transaction.step === "error" ? "Send failed" : "Confirm Send";
|
|
3960
4131
|
async function handleSubmit() {
|
|
3961
4132
|
setFormError("");
|
|
4133
|
+
if (!canSendOnChain) {
|
|
4134
|
+
setFormError("Sending is not available on this network yet.");
|
|
4135
|
+
return;
|
|
4136
|
+
}
|
|
3962
4137
|
if (!selectedAsset) {
|
|
3963
4138
|
setFormError("Select an asset");
|
|
3964
4139
|
return;
|
|
@@ -3968,7 +4143,7 @@ function SendModal({ onClose }) {
|
|
|
3968
4143
|
setFormError("Enter a valid amount");
|
|
3969
4144
|
return;
|
|
3970
4145
|
}
|
|
3971
|
-
if (parsed > parseFloat(selectedAsset.available)) {
|
|
4146
|
+
if (parsed > parseFloat(selectedAsset.available ?? "0")) {
|
|
3972
4147
|
setFormError("Insufficient balance");
|
|
3973
4148
|
return;
|
|
3974
4149
|
}
|
|
@@ -3976,7 +4151,32 @@ function SendModal({ onClose }) {
|
|
|
3976
4151
|
setFormError("Enter a destination address");
|
|
3977
4152
|
return;
|
|
3978
4153
|
}
|
|
4154
|
+
const isNativeAsset = selectedAsset.type === "native";
|
|
4155
|
+
if (isBaseUnitChain && !isNativeAsset && (!selectedAsset.issuer || selectedAsset.decimals === void 0)) {
|
|
4156
|
+
setFormError("This token is missing its mint or decimals and cannot be sent.");
|
|
4157
|
+
return;
|
|
4158
|
+
}
|
|
4159
|
+
let sendAmount = amount;
|
|
4160
|
+
if (isBaseUnitChain) {
|
|
4161
|
+
try {
|
|
4162
|
+
sendAmount = core.toBaseUnits(amount, selectedAsset.decimals ?? 9);
|
|
4163
|
+
} catch (e) {
|
|
4164
|
+
setFormError(e instanceof Error ? e.message : "Invalid amount");
|
|
4165
|
+
return;
|
|
4166
|
+
}
|
|
4167
|
+
}
|
|
3979
4168
|
setStep("tx");
|
|
4169
|
+
if (selectedChain === "SOLANA") {
|
|
4170
|
+
await sendPayment({
|
|
4171
|
+
chain: "SOLANA",
|
|
4172
|
+
destination: destination.trim(),
|
|
4173
|
+
amount: sendAmount,
|
|
4174
|
+
// Native SOL carries no mint; an SPL token's mint rides in `issuer`,
|
|
4175
|
+
// which the guard above proved is present.
|
|
4176
|
+
...isNativeAsset ? {} : { mint: selectedAsset.issuer }
|
|
4177
|
+
});
|
|
4178
|
+
return;
|
|
4179
|
+
}
|
|
3980
4180
|
await buildTx("payment", { destination: destination.trim(), amount, asset: assetParam(selectedAsset) });
|
|
3981
4181
|
}
|
|
3982
4182
|
function handleSignAndSend() {
|
|
@@ -4014,6 +4214,11 @@ function SendModal({ onClose }) {
|
|
|
4014
4214
|
txTitle,
|
|
4015
4215
|
assets: sortedAssets,
|
|
4016
4216
|
selectedAsset,
|
|
4217
|
+
chains,
|
|
4218
|
+
selectedChain,
|
|
4219
|
+
walletAddress,
|
|
4220
|
+
canSendOnChain,
|
|
4221
|
+
onSelectChain: setSelectedChain,
|
|
4017
4222
|
amount,
|
|
4018
4223
|
destination,
|
|
4019
4224
|
formError,
|
|
@@ -4440,11 +4645,19 @@ function SwapModal({ onClose }) {
|
|
|
4440
4645
|
const assetRecords = enabledAssets.step === "loaded" ? enabledAssets.data.assets : [];
|
|
4441
4646
|
const isLoadingData = walletBalance.step === "loading" || enabledAssets.step === "loading";
|
|
4442
4647
|
const sellOptions = balances.filter(
|
|
4443
|
-
(b) => b.
|
|
4444
|
-
).map((b) => ({
|
|
4648
|
+
(b) => (b.chain === void 0 || b.chain === "STELLAR") && (b.type === "native" || (b.type === "credit_alphanum4" || b.type === "credit_alphanum12") && !b.trustlineRemoved)
|
|
4649
|
+
).map((b) => ({
|
|
4650
|
+
ref: toRef(b),
|
|
4651
|
+
code: b.code,
|
|
4652
|
+
issuer: b.issuer,
|
|
4653
|
+
available: b.available ?? void 0,
|
|
4654
|
+
enabledInApp: b.enabledInApp
|
|
4655
|
+
}));
|
|
4445
4656
|
const buyKeyOfSell = selectedSell ? `${selectedSell.code}:${selectedSell.issuer ?? "native"}` : "";
|
|
4446
4657
|
const optKey = (o) => `${o.code}:${o.issuer ?? "native"}`;
|
|
4447
|
-
const enabledBuy = assetRecords.
|
|
4658
|
+
const enabledBuy = assetRecords.filter(
|
|
4659
|
+
(a) => (a.chain === void 0 || a.chain === "STELLAR") && (a.type === "native" || a.type === "credit_alphanum4" || a.type === "credit_alphanum12")
|
|
4660
|
+
).map((a) => ({
|
|
4448
4661
|
ref: toRef(a),
|
|
4449
4662
|
code: a.code,
|
|
4450
4663
|
issuer: a.issuer,
|
|
@@ -4745,15 +4958,13 @@ function EarnModal({ onClose }) {
|
|
|
4745
4958
|
if (!selectedOpportunity) return null;
|
|
4746
4959
|
const balances = walletBalance.step === "loaded" ? walletBalance.data.balances : [];
|
|
4747
4960
|
const issuer = selectedOpportunity.asset.issuer;
|
|
4748
|
-
const rec = balances.find(
|
|
4749
|
-
(b) => issuer === null ? b.type === "native" : b.code === assetCode && b.issuer === issuer
|
|
4750
|
-
);
|
|
4961
|
+
const rec = balances.find((b) => issuer === null ? b.type === "native" : b.code === assetCode && b.issuer === issuer);
|
|
4751
4962
|
return rec ? rec.available : null;
|
|
4752
4963
|
})();
|
|
4753
4964
|
const depositAssetRecord = (() => {
|
|
4754
4965
|
if (!selectedOpportunity?.asset.issuer || enabledAssets.step !== "loaded") return void 0;
|
|
4755
4966
|
return enabledAssets.data.assets.find(
|
|
4756
|
-
(a) => a.code === assetCode && a.issuer === selectedOpportunity.asset.issuer
|
|
4967
|
+
(a) => (a.chain === void 0 || a.chain === "STELLAR") && a.code === assetCode && a.issuer === selectedOpportunity.asset.issuer
|
|
4757
4968
|
);
|
|
4758
4969
|
})();
|
|
4759
4970
|
const depositNeedsTrustline = tab === "deposit" && !smartUnsupported && !!selectedOpportunity?.asset.issuer && !depositAssetRecord?.trustlineEstablished;
|
|
@@ -4809,10 +5020,7 @@ function EarnModal({ onClose }) {
|
|
|
4809
5020
|
}
|
|
4810
5021
|
setStep("tx");
|
|
4811
5022
|
if (tab === "deposit" && depositNeedsTrustline && selectedOpportunity?.asset.issuer) {
|
|
4812
|
-
const tl = await setTrustline(
|
|
4813
|
-
{ code: assetCode, issuer: selectedOpportunity.asset.issuer },
|
|
4814
|
-
depositAssetRecord?.sponsored ? { sponsored: true } : void 0
|
|
4815
|
-
);
|
|
5023
|
+
const tl = await setTrustline({ code: assetCode, issuer: selectedOpportunity.asset.issuer });
|
|
4816
5024
|
if (tl.status === "error") {
|
|
4817
5025
|
setFormError(`Trustline for ${assetCode} failed: ${tl.details ?? "unknown error"}`);
|
|
4818
5026
|
setStep("form");
|
|
@@ -5427,6 +5635,12 @@ function TransactionModal({ onClose }) {
|
|
|
5427
5635
|
) });
|
|
5428
5636
|
}
|
|
5429
5637
|
var PAGE_SIZE = 10;
|
|
5638
|
+
function explorerUrlFor(chain, hash, network) {
|
|
5639
|
+
if (chain === "SOLANA") {
|
|
5640
|
+
return `https://explorer.solana.com/tx/${hash}${network === "testnet" ? "?cluster=devnet" : ""}`;
|
|
5641
|
+
}
|
|
5642
|
+
return `https://stellar.expert/explorer/${network === "testnet" ? "testnet" : "public"}/tx/${hash}`;
|
|
5643
|
+
}
|
|
5430
5644
|
function StatusBadge({ status }) {
|
|
5431
5645
|
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-hist-item-badge", "data-status": status, children: status });
|
|
5432
5646
|
}
|
|
@@ -5465,6 +5679,10 @@ function TxHistoryModalTemplate({
|
|
|
5465
5679
|
accentColor,
|
|
5466
5680
|
txHistory,
|
|
5467
5681
|
offset,
|
|
5682
|
+
chains,
|
|
5683
|
+
selectedChain,
|
|
5684
|
+
walletAddress,
|
|
5685
|
+
onSelectChain,
|
|
5468
5686
|
onRefresh,
|
|
5469
5687
|
onPrev,
|
|
5470
5688
|
onNext,
|
|
@@ -5540,6 +5758,11 @@ function TxHistoryModalTemplate({
|
|
|
5540
5758
|
/* @__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" }) }) })
|
|
5541
5759
|
] })
|
|
5542
5760
|
] }),
|
|
5761
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChainSelect, { value: selectedChain, options: chains, onChange: onSelectChain, disabled: isLoading }),
|
|
5762
|
+
walletAddress && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-address-row", children: [
|
|
5763
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-address", children: cropAddress(walletAddress) }),
|
|
5764
|
+
/* @__PURE__ */ jsxRuntime.jsx(CopyButton, { value: walletAddress, label: "Copy wallet address" })
|
|
5765
|
+
] }),
|
|
5543
5766
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-list", children: [
|
|
5544
5767
|
txHistory.step === "idle" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "Click Refresh to load transactions." }),
|
|
5545
5768
|
isLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-loading-block", children: [
|
|
@@ -5550,7 +5773,7 @@ function TxHistoryModalTemplate({
|
|
|
5550
5773
|
txHistory.step === "loaded" && records.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No transactions yet." }),
|
|
5551
5774
|
records.map((record) => {
|
|
5552
5775
|
const hash = typeof record.hash === "string" && record.hash.length > 0 ? record.hash : void 0;
|
|
5553
|
-
const explorerUrl = hash ?
|
|
5776
|
+
const explorerUrl = hash ? explorerUrlFor(record.chain, hash, record.network) : void 0;
|
|
5554
5777
|
const asset = typeof record.details?.asset === "string" ? record.details.asset : void 0;
|
|
5555
5778
|
const colon = asset ? asset.indexOf(":") : -1;
|
|
5556
5779
|
const trustline = record.operation === "change_trust" && asset && colon > 0 ? {
|
|
@@ -5584,10 +5807,11 @@ function TxHistoryModalTemplate({
|
|
|
5584
5807
|
"\xB7 ",
|
|
5585
5808
|
record.details.sponsored ? "Sponsored" : "Self-paid"
|
|
5586
5809
|
] }),
|
|
5587
|
-
record.
|
|
5810
|
+
record.fee && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
5588
5811
|
"\xB7 ",
|
|
5589
|
-
record.
|
|
5590
|
-
"
|
|
5812
|
+
record.fee.amount,
|
|
5813
|
+
" ",
|
|
5814
|
+
record.fee.unit
|
|
5591
5815
|
] })
|
|
5592
5816
|
] }),
|
|
5593
5817
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-item-footer", children: [
|
|
@@ -5603,7 +5827,7 @@ function TxHistoryModalTemplate({
|
|
|
5603
5827
|
href: explorerUrl,
|
|
5604
5828
|
target: "_blank",
|
|
5605
5829
|
rel: "noopener noreferrer",
|
|
5606
|
-
"aria-label": "View on
|
|
5830
|
+
"aria-label": "View on block explorer",
|
|
5607
5831
|
children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "12", height: "12", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
|
|
5608
5832
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5609
5833
|
"path",
|
|
@@ -5652,19 +5876,29 @@ function TxHistoryModalTemplate({
|
|
|
5652
5876
|
}
|
|
5653
5877
|
var PAGE_SIZE2 = 10;
|
|
5654
5878
|
function TxHistoryModal({ onClose }) {
|
|
5655
|
-
const { getClient, styles, txHistory } = usePollar();
|
|
5879
|
+
const { getClient, styles, txHistory, wallets } = usePollar();
|
|
5656
5880
|
const { theme = "light", accentColor = "#005DB4" } = styles;
|
|
5657
5881
|
const [offset, setOffset] = react.useState(0);
|
|
5882
|
+
const { chains } = useChains();
|
|
5883
|
+
const [selectedChain, setSelectedChain] = react.useState(null);
|
|
5884
|
+
react.useEffect(() => {
|
|
5885
|
+
if (selectedChain === null && chains.length > 0) setSelectedChain(chains[0]);
|
|
5886
|
+
}, [chains, selectedChain]);
|
|
5887
|
+
const walletAddress = addressForChain(wallets, selectedChain);
|
|
5658
5888
|
const load = react.useCallback(
|
|
5659
|
-
(nextOffset) => {
|
|
5889
|
+
(nextOffset, chain) => {
|
|
5660
5890
|
setOffset(nextOffset);
|
|
5661
|
-
void getClient().fetchTxHistory({ limit: PAGE_SIZE2, offset: nextOffset });
|
|
5891
|
+
void getClient().fetchTxHistory({ limit: PAGE_SIZE2, offset: nextOffset, chain });
|
|
5662
5892
|
},
|
|
5663
5893
|
[getClient]
|
|
5664
5894
|
);
|
|
5665
5895
|
react.useEffect(() => {
|
|
5666
|
-
load(0);
|
|
5667
|
-
}, [load]);
|
|
5896
|
+
if (selectedChain) load(0, selectedChain);
|
|
5897
|
+
}, [selectedChain, load]);
|
|
5898
|
+
const onSelectChain = (chain) => setSelectedChain(chain);
|
|
5899
|
+
const paged = (nextOffset) => {
|
|
5900
|
+
if (selectedChain) load(nextOffset, selectedChain);
|
|
5901
|
+
};
|
|
5668
5902
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5669
5903
|
TxHistoryModalTemplate,
|
|
5670
5904
|
{
|
|
@@ -5672,47 +5906,48 @@ function TxHistoryModal({ onClose }) {
|
|
|
5672
5906
|
accentColor,
|
|
5673
5907
|
txHistory,
|
|
5674
5908
|
offset,
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5909
|
+
chains,
|
|
5910
|
+
selectedChain,
|
|
5911
|
+
walletAddress,
|
|
5912
|
+
onSelectChain,
|
|
5913
|
+
onRefresh: () => paged(offset),
|
|
5914
|
+
onPrev: () => paged(Math.max(0, offset - PAGE_SIZE2)),
|
|
5915
|
+
onNext: () => paged(offset + PAGE_SIZE2),
|
|
5678
5916
|
onClose
|
|
5679
5917
|
}
|
|
5680
5918
|
) });
|
|
5681
5919
|
}
|
|
5682
|
-
function formatBalance2(balance) {
|
|
5920
|
+
function formatBalance2(balance, decimals = 7) {
|
|
5921
|
+
if (balance === null) return "\u2014";
|
|
5922
|
+
const digits = Math.min(decimals, 7);
|
|
5683
5923
|
const n = parseFloat(balance);
|
|
5684
|
-
return isNaN(n) ? balance : n.toLocaleString(void 0, { minimumFractionDigits:
|
|
5924
|
+
return isNaN(n) ? balance : n.toLocaleString(void 0, { minimumFractionDigits: digits, maximumFractionDigits: digits });
|
|
5685
5925
|
}
|
|
5686
|
-
function
|
|
5687
|
-
if (
|
|
5688
|
-
return
|
|
5689
|
-
|
|
5690
|
-
var CHAIN_TAG = {
|
|
5691
|
-
STELLAR: { label: "Stellar", color: "#7d00ff" },
|
|
5692
|
-
POLYGON: { label: "Polygon", color: "#8247e5" },
|
|
5693
|
-
SOLANA: { label: "Solana", color: "#14f195" }
|
|
5694
|
-
};
|
|
5695
|
-
function ChainTag({ chain }) {
|
|
5696
|
-
const tag = CHAIN_TAG[chain] ?? { label: chain, color: "#6b7280" };
|
|
5697
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-bal-chain-tag", style: { "--pollar-chain-color": tag.color }, children: tag.label });
|
|
5926
|
+
function faucetFor(record) {
|
|
5927
|
+
if (record.type === "native") return { url: "https://faucet.solana.com/", label: "Get test SOL" };
|
|
5928
|
+
if (record.code === "USDC") return { url: "https://faucet.circle.com/", label: "Get test USDC" };
|
|
5929
|
+
return null;
|
|
5698
5930
|
}
|
|
5699
|
-
function BalanceItem({ record,
|
|
5931
|
+
function BalanceItem({ record, faucet }) {
|
|
5700
5932
|
const balanceDiffers = record.balance !== record.available;
|
|
5701
5933
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-bal-item", children: [
|
|
5702
5934
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-bal-asset-info", children: [
|
|
5703
|
-
/* @__PURE__ */ jsxRuntime.
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
] }),
|
|
5707
|
-
record.issuer && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-bal-issuer", children: [
|
|
5708
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-bal-issuer-addr", children: cropAddress2(record.issuer) }),
|
|
5935
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-bal-asset-code-row", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-bal-asset", children: record.code }) }),
|
|
5936
|
+
record.issuer && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-issuer", children: [
|
|
5937
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-issuer-addr", children: cropAddress(record.issuer) }),
|
|
5709
5938
|
/* @__PURE__ */ jsxRuntime.jsx(CopyButton, { value: record.issuer, label: "Copy issuer address", className: "pollar-copy-btn-sm" })
|
|
5939
|
+
] }),
|
|
5940
|
+
faucet && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-bal-faucet-hint", children: [
|
|
5941
|
+
"Need more?",
|
|
5942
|
+
" ",
|
|
5943
|
+
/* @__PURE__ */ jsxRuntime.jsx("a", { href: faucet.url, target: "_blank", rel: "noopener noreferrer", children: faucet.label }),
|
|
5944
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-bal-faucet-net", children: " (devnet)" })
|
|
5710
5945
|
] })
|
|
5711
5946
|
] }),
|
|
5712
5947
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-bal-amounts", children: [
|
|
5713
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-bal-amount", children: formatBalance2(record.balance) }),
|
|
5948
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-bal-amount", children: formatBalance2(record.balance, record.decimals) }),
|
|
5714
5949
|
balanceDiffers && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-bal-available", children: [
|
|
5715
|
-
formatBalance2(record.available),
|
|
5950
|
+
formatBalance2(record.available, record.decimals),
|
|
5716
5951
|
" available"
|
|
5717
5952
|
] })
|
|
5718
5953
|
] })
|
|
@@ -5723,6 +5958,10 @@ function WalletBalanceModalTemplate({
|
|
|
5723
5958
|
accentColor,
|
|
5724
5959
|
walletBalance,
|
|
5725
5960
|
walletAddress,
|
|
5961
|
+
chains,
|
|
5962
|
+
selectedChain,
|
|
5963
|
+
network,
|
|
5964
|
+
onSelectChain,
|
|
5726
5965
|
onRefresh,
|
|
5727
5966
|
onClose
|
|
5728
5967
|
}) {
|
|
@@ -5745,8 +5984,11 @@ function WalletBalanceModalTemplate({
|
|
|
5745
5984
|
"--pollar-card-border-radius": "10px"
|
|
5746
5985
|
};
|
|
5747
5986
|
const isLoading = walletBalance.step === "loading";
|
|
5748
|
-
const data = walletBalance.step === "loaded" ? walletBalance.data : null;
|
|
5987
|
+
const data = useStickyData(walletBalance.step === "loaded" ? walletBalance.data : null);
|
|
5988
|
+
const balances = (data?.balances ?? []).filter((b) => resolveChain(b.chain) === selectedChain);
|
|
5989
|
+
const showFaucets = selectedChain === "SOLANA" && network === "testnet";
|
|
5749
5990
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-card pollar-bal-modal", "data-theme": theme, style: cssVars, onClick: (e) => e.stopPropagation(), children: [
|
|
5991
|
+
isLoading && data && /* @__PURE__ */ jsxRuntime.jsx(BusyOverlay, { label: "Refreshing balances\u2026" }),
|
|
5750
5992
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
|
|
5751
5993
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Wallet Balance" }),
|
|
5752
5994
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
|
|
@@ -5785,11 +6027,12 @@ function WalletBalanceModalTemplate({
|
|
|
5785
6027
|
/* @__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" }) }) })
|
|
5786
6028
|
] })
|
|
5787
6029
|
] }),
|
|
5788
|
-
|
|
5789
|
-
|
|
6030
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChainSelect, { value: selectedChain, options: chains, onChange: onSelectChain, disabled: isLoading }),
|
|
6031
|
+
walletAddress && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-address-row", children: [
|
|
6032
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-address", children: cropAddress(walletAddress) }),
|
|
5790
6033
|
/* @__PURE__ */ jsxRuntime.jsx(CopyButton, { value: walletAddress, label: "Copy wallet address" })
|
|
5791
6034
|
] }),
|
|
5792
|
-
isLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-loading-block", children: [
|
|
6035
|
+
isLoading && !data && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-loading-block", children: [
|
|
5793
6036
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-spinner" }),
|
|
5794
6037
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Loading\u2026" })
|
|
5795
6038
|
] }),
|
|
@@ -5799,15 +6042,27 @@ function WalletBalanceModalTemplate({
|
|
|
5799
6042
|
data.network,
|
|
5800
6043
|
"."
|
|
5801
6044
|
] }),
|
|
5802
|
-
data?.exists &&
|
|
5803
|
-
data?.exists &&
|
|
6045
|
+
data?.exists && balances.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No balances found on this network." }),
|
|
6046
|
+
data?.exists && balances.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-bal-list", children: balances.map((b) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6047
|
+
BalanceItem,
|
|
6048
|
+
{
|
|
6049
|
+
record: b,
|
|
6050
|
+
faucet: showFaucets ? faucetFor(b) : null
|
|
6051
|
+
},
|
|
6052
|
+
(b.chain ?? "") + b.code + (b.issuer ?? "")
|
|
6053
|
+
)) }),
|
|
5804
6054
|
/* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
|
|
5805
6055
|
] });
|
|
5806
6056
|
}
|
|
5807
6057
|
function WalletBalanceModal({ onClose }) {
|
|
5808
|
-
const { walletBalance, refreshWalletBalance,
|
|
5809
|
-
const walletAddress = wallet?.address ?? "";
|
|
6058
|
+
const { walletBalance, refreshWalletBalance, wallets, network, styles } = usePollar();
|
|
5810
6059
|
const { theme = "light", accentColor = "#005DB4" } = styles;
|
|
6060
|
+
const { chains } = useChains();
|
|
6061
|
+
const [selectedChain, setSelectedChain] = react.useState(null);
|
|
6062
|
+
react.useEffect(() => {
|
|
6063
|
+
if (selectedChain === null && chains.length > 0) setSelectedChain(chains[0]);
|
|
6064
|
+
}, [chains, selectedChain]);
|
|
6065
|
+
const walletAddress = addressForChain(wallets, selectedChain);
|
|
5811
6066
|
react.useEffect(() => {
|
|
5812
6067
|
void refreshWalletBalance();
|
|
5813
6068
|
}, [refreshWalletBalance]);
|
|
@@ -5818,6 +6073,10 @@ function WalletBalanceModal({ onClose }) {
|
|
|
5818
6073
|
accentColor,
|
|
5819
6074
|
walletBalance,
|
|
5820
6075
|
walletAddress,
|
|
6076
|
+
chains,
|
|
6077
|
+
selectedChain,
|
|
6078
|
+
network,
|
|
6079
|
+
onSelectChain: setSelectedChain,
|
|
5821
6080
|
onRefresh: () => refreshWalletBalance(),
|
|
5822
6081
|
onClose
|
|
5823
6082
|
}
|
|
@@ -5922,6 +6181,9 @@ function PollarProvider({
|
|
|
5922
6181
|
);
|
|
5923
6182
|
const [configRetry, setConfigRetry] = react.useState(0);
|
|
5924
6183
|
const retryConfig = react.useCallback(() => setConfigRetry((n) => n + 1), []);
|
|
6184
|
+
const appConfigKey = appConfigProp === void 0 ? "" : JSON.stringify(appConfigProp);
|
|
6185
|
+
const appConfigPropRef = react.useRef(appConfigProp);
|
|
6186
|
+
appConfigPropRef.current = appConfigProp;
|
|
5925
6187
|
react.useEffect(() => {
|
|
5926
6188
|
return pollarClient.onTransactionStateChange(setTransaction);
|
|
5927
6189
|
}, [pollarClient]);
|
|
@@ -5985,7 +6247,9 @@ function PollarProvider({
|
|
|
5985
6247
|
setModalErrorLogger(pollarClient.getLogger());
|
|
5986
6248
|
}, [pollarClient]);
|
|
5987
6249
|
react.useEffect(() => {
|
|
5988
|
-
|
|
6250
|
+
const localConfig = appConfigPropRef.current;
|
|
6251
|
+
if (localConfig !== void 0) {
|
|
6252
|
+
setResolvedConfig(localConfig ?? DEFAULT_APP_CONFIG);
|
|
5989
6253
|
setConfigStatus("ready");
|
|
5990
6254
|
return;
|
|
5991
6255
|
}
|
|
@@ -6007,7 +6271,7 @@ function PollarProvider({
|
|
|
6007
6271
|
return () => {
|
|
6008
6272
|
cancelled = true;
|
|
6009
6273
|
};
|
|
6010
|
-
}, [pollarClient,
|
|
6274
|
+
}, [pollarClient, appConfigKey, configRetry]);
|
|
6011
6275
|
const [loginModalOpen, setLoginModalOpen] = react.useState(false);
|
|
6012
6276
|
const [transactionModalOpen, setTransactionModalOpen] = react.useState(false);
|
|
6013
6277
|
const [kycModalOpen, setKycModalOpen] = react.useState(false);
|
|
@@ -6034,6 +6298,7 @@ function PollarProvider({
|
|
|
6034
6298
|
return {
|
|
6035
6299
|
// session
|
|
6036
6300
|
wallet: pollarClient.getWallet(),
|
|
6301
|
+
wallets: pollarClient.getWallets(),
|
|
6037
6302
|
isAuthenticated: !!walletAddress,
|
|
6038
6303
|
verified,
|
|
6039
6304
|
// client
|
|
@@ -6050,6 +6315,7 @@ function PollarProvider({
|
|
|
6050
6315
|
submitTx: (signedXdr) => pollarClient.submitTx(signedXdr),
|
|
6051
6316
|
buildAndSignAndSubmitTx: (operation, params, options) => pollarClient.buildAndSignAndSubmitTx(operation, params, options),
|
|
6052
6317
|
runTx: (operation, params, options) => pollarClient.runTx(operation, params, options),
|
|
6318
|
+
sendPayment: (params) => pollarClient.sendPayment(params),
|
|
6053
6319
|
openTxModal: () => setTransactionModalOpen(true),
|
|
6054
6320
|
// tx history
|
|
6055
6321
|
txHistory,
|
|
@@ -6534,7 +6800,8 @@ function WalletButton() {
|
|
|
6534
6800
|
openDistributionRulesModal,
|
|
6535
6801
|
tx: transaction
|
|
6536
6802
|
} = usePollar();
|
|
6537
|
-
const
|
|
6803
|
+
const { primaryAddress } = useChains();
|
|
6804
|
+
const walletAddress = primaryAddress || (wallet?.address ?? "");
|
|
6538
6805
|
const walletType = wallet?.custody === "external" ? wallet.provider : null;
|
|
6539
6806
|
const [open, setOpen] = react.useState(false);
|
|
6540
6807
|
const [copied, setCopied] = react.useState(false);
|
|
@@ -6656,6 +6923,7 @@ function WalletButton() {
|
|
|
6656
6923
|
);
|
|
6657
6924
|
}
|
|
6658
6925
|
|
|
6926
|
+
exports.ChainSelect = ChainSelect;
|
|
6659
6927
|
exports.DistributionRulesModal = DistributionRulesModal;
|
|
6660
6928
|
exports.DistributionRulesModalTemplate = DistributionRulesModalTemplate;
|
|
6661
6929
|
exports.EarnModal = EarnModal;
|
|
@@ -6684,7 +6952,11 @@ exports.WalletBalanceModal = WalletBalanceModal;
|
|
|
6684
6952
|
exports.WalletBalanceModalTemplate = WalletBalanceModalTemplate;
|
|
6685
6953
|
exports.WalletButton = WalletButton;
|
|
6686
6954
|
exports.WalletButtonTemplate = WalletButtonTemplate;
|
|
6955
|
+
exports.addressForChain = addressForChain;
|
|
6956
|
+
exports.chainsOf = chainsOf;
|
|
6687
6957
|
exports.createPollarAdapterHook = createPollarAdapterHook;
|
|
6958
|
+
exports.resolveChain = resolveChain;
|
|
6959
|
+
exports.useChains = useChains;
|
|
6688
6960
|
exports.usePollar = usePollar;
|
|
6689
6961
|
//# sourceMappingURL=index.js.map
|
|
6690
6962
|
//# sourceMappingURL=index.js.map
|