@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.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { AUTH_ERROR_CODES, WalletType, PollarClient, isInteractiveAuthAdapter } from '@pollar/core';
|
|
3
|
-
import { forwardRef, createContext, useState, useCallback, useEffect,
|
|
2
|
+
import { AUTH_ERROR_CODES, WalletType, PollarClient, isInteractiveAuthAdapter, toBaseUnits } from '@pollar/core';
|
|
3
|
+
import { forwardRef, createContext, useState, useCallback, useEffect, useMemo, useRef, useContext, Component } from 'react';
|
|
4
4
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
5
5
|
import { startAuthentication, startRegistration } from '@simplewebauthn/browser';
|
|
6
6
|
|
|
@@ -1033,7 +1033,7 @@ var PollarModalFooter = () => {
|
|
|
1033
1033
|
/* @__PURE__ */ jsx("span", { className: "pollar-footer-name", children: "Pollar" }),
|
|
1034
1034
|
/* @__PURE__ */ jsxs("span", { className: "pollar-footer-version", children: [
|
|
1035
1035
|
"v",
|
|
1036
|
-
"0.11.
|
|
1036
|
+
"0.11.2"
|
|
1037
1037
|
] })
|
|
1038
1038
|
] })
|
|
1039
1039
|
] });
|
|
@@ -1099,6 +1099,36 @@ function ModalStatusBanner({ message, status, onCancel, onRetry }) {
|
|
|
1099
1099
|
status === "ERROR" && onRetry && /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-status-cancel", onClick: onRetry, children: "Retry" })
|
|
1100
1100
|
] });
|
|
1101
1101
|
}
|
|
1102
|
+
function cropAddress(address) {
|
|
1103
|
+
if (address.length <= 16) return address;
|
|
1104
|
+
return `${address.slice(0, 8)}...${address.slice(-8)}`;
|
|
1105
|
+
}
|
|
1106
|
+
function useStickyData(data) {
|
|
1107
|
+
const lastRef = useRef(null);
|
|
1108
|
+
if (data !== null) lastRef.current = data;
|
|
1109
|
+
return data ?? lastRef.current;
|
|
1110
|
+
}
|
|
1111
|
+
function BusyOverlay({ label = "Loading\u2026" }) {
|
|
1112
|
+
return /* @__PURE__ */ jsx("div", { className: "pollar-busy-overlay", "aria-busy": "true", "aria-live": "polite", children: /* @__PURE__ */ jsxs("div", { className: "pollar-busy-overlay-inner", children: [
|
|
1113
|
+
/* @__PURE__ */ jsx("div", { className: "pollar-spinner" }),
|
|
1114
|
+
/* @__PURE__ */ jsx("span", { children: label })
|
|
1115
|
+
] }) });
|
|
1116
|
+
}
|
|
1117
|
+
function Toggle({ checked, onChange, disabled = false, busy = false, label }) {
|
|
1118
|
+
return /* @__PURE__ */ jsx(
|
|
1119
|
+
"button",
|
|
1120
|
+
{
|
|
1121
|
+
type: "button",
|
|
1122
|
+
role: "switch",
|
|
1123
|
+
"aria-checked": checked,
|
|
1124
|
+
"aria-label": label,
|
|
1125
|
+
className: `pollar-switch${checked ? " pollar-switch-on" : ""}${busy ? " pollar-switch-busy" : ""}`,
|
|
1126
|
+
onClick: onChange,
|
|
1127
|
+
disabled: disabled || busy,
|
|
1128
|
+
children: /* @__PURE__ */ jsx("span", { className: "pollar-switch-knob", children: busy && /* @__PURE__ */ jsx("span", { className: "pollar-spinner pollar-spinner-sm pollar-spinner-current" }) })
|
|
1129
|
+
}
|
|
1130
|
+
);
|
|
1131
|
+
}
|
|
1102
1132
|
var PERIOD_LABEL = {
|
|
1103
1133
|
DAY: "every 24h",
|
|
1104
1134
|
DAY_CALENDAR: "daily",
|
|
@@ -1326,9 +1356,66 @@ function DistributionRulesModal({ onClose }) {
|
|
|
1326
1356
|
}
|
|
1327
1357
|
) });
|
|
1328
1358
|
}
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1359
|
+
var CHAIN_LABEL = {
|
|
1360
|
+
STELLAR: "Stellar",
|
|
1361
|
+
POLYGON: "Polygon",
|
|
1362
|
+
SOLANA: "Solana"
|
|
1363
|
+
};
|
|
1364
|
+
function resolveChain(chain) {
|
|
1365
|
+
return chain ?? "STELLAR";
|
|
1366
|
+
}
|
|
1367
|
+
function chainsOf(wallets, order) {
|
|
1368
|
+
const held = [];
|
|
1369
|
+
for (const w of wallets) {
|
|
1370
|
+
const chain = resolveChain(w.chain);
|
|
1371
|
+
if (!held.includes(chain)) held.push(chain);
|
|
1372
|
+
}
|
|
1373
|
+
if (!order || order.length === 0) return held;
|
|
1374
|
+
return order.filter((c) => held.includes(c));
|
|
1375
|
+
}
|
|
1376
|
+
function addressForChain(wallets, chain) {
|
|
1377
|
+
if (!chain) return "";
|
|
1378
|
+
return wallets.find((w) => resolveChain(w.chain) === chain)?.address ?? "";
|
|
1379
|
+
}
|
|
1380
|
+
function ChainSelect({ label = "Network", value, options, onChange, disabled = false }) {
|
|
1381
|
+
if (options.length < 2) return null;
|
|
1382
|
+
return /* @__PURE__ */ jsxs("div", { className: "pollar-send-field pollar-chain-field", children: [
|
|
1383
|
+
/* @__PURE__ */ jsx("label", { className: "pollar-send-label", children: label }),
|
|
1384
|
+
/* @__PURE__ */ jsxs(
|
|
1385
|
+
"select",
|
|
1386
|
+
{
|
|
1387
|
+
className: "pollar-input pollar-send-select",
|
|
1388
|
+
value: value ?? "",
|
|
1389
|
+
disabled,
|
|
1390
|
+
onChange: (e) => onChange(e.target.value),
|
|
1391
|
+
children: [
|
|
1392
|
+
value === null && /* @__PURE__ */ jsx("option", { value: "", disabled: true, hidden: true }),
|
|
1393
|
+
options.map((chain) => /* @__PURE__ */ jsx("option", { value: chain, children: CHAIN_LABEL[chain] ?? chain }, chain))
|
|
1394
|
+
]
|
|
1395
|
+
}
|
|
1396
|
+
)
|
|
1397
|
+
] });
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
// src/useChains.ts
|
|
1401
|
+
function useChains() {
|
|
1402
|
+
const { wallets, appConfig, configStatus } = usePollar();
|
|
1403
|
+
const configured = appConfig?.application?.chains;
|
|
1404
|
+
const ready = configStatus === "ready";
|
|
1405
|
+
return useMemo(() => {
|
|
1406
|
+
if (!ready) {
|
|
1407
|
+
const fallback = chainsOf(wallets);
|
|
1408
|
+
return {
|
|
1409
|
+
chains: [],
|
|
1410
|
+
primaryChain: null,
|
|
1411
|
+
primaryAddress: addressForChain(wallets, fallback[0] ?? null),
|
|
1412
|
+
ready: false
|
|
1413
|
+
};
|
|
1414
|
+
}
|
|
1415
|
+
const chains = chainsOf(wallets, configured);
|
|
1416
|
+
const primaryChain = chains[0] ?? null;
|
|
1417
|
+
return { chains, primaryChain, primaryAddress: addressForChain(wallets, primaryChain), ready: true };
|
|
1418
|
+
}, [wallets, configured, ready]);
|
|
1332
1419
|
}
|
|
1333
1420
|
function cssVarsFor(theme, accentColor) {
|
|
1334
1421
|
const isDark = theme === "dark";
|
|
@@ -1353,14 +1440,18 @@ function cssVarsFor(theme, accentColor) {
|
|
|
1353
1440
|
function assetKey(record) {
|
|
1354
1441
|
return record.code + (record.issuer ?? "");
|
|
1355
1442
|
}
|
|
1443
|
+
function rowKey(record) {
|
|
1444
|
+
return (record.chain ?? "") + assetKey(record);
|
|
1445
|
+
}
|
|
1356
1446
|
function AssetItem({
|
|
1357
1447
|
record,
|
|
1358
1448
|
busy,
|
|
1359
1449
|
disabled,
|
|
1360
1450
|
onToggle
|
|
1361
1451
|
}) {
|
|
1362
|
-
const established = record.trustlineEstablished;
|
|
1452
|
+
const established = record.trustlineEstablished ?? false;
|
|
1363
1453
|
const isNative = record.type === "native";
|
|
1454
|
+
const isStellar = resolveChain(record.chain) === "STELLAR";
|
|
1364
1455
|
return /* @__PURE__ */ jsxs("div", { className: "pollar-asset-item", children: [
|
|
1365
1456
|
/* @__PURE__ */ jsxs("div", { className: "pollar-asset-info", children: [
|
|
1366
1457
|
/* @__PURE__ */ jsxs("div", { className: "pollar-asset-code-row", children: [
|
|
@@ -1368,17 +1459,22 @@ function AssetItem({
|
|
|
1368
1459
|
record.enabledInApp && /* @__PURE__ */ jsx("span", { className: "pollar-asset-tag", children: "App" })
|
|
1369
1460
|
] }),
|
|
1370
1461
|
record.name && /* @__PURE__ */ jsx("span", { className: "pollar-asset-name", children: record.name }),
|
|
1371
|
-
|
|
1462
|
+
record.issuer && /* @__PURE__ */ jsxs("span", { className: "pollar-issuer", children: [
|
|
1463
|
+
/* @__PURE__ */ jsx("span", { className: "pollar-issuer-addr", children: cropAddress(record.issuer) }),
|
|
1464
|
+
/* @__PURE__ */ jsx(CopyButton, { value: record.issuer, label: "Copy issuer address", className: "pollar-copy-btn-sm" })
|
|
1465
|
+
] }),
|
|
1466
|
+
isStellar && !isNative && record.enabledInApp && /* @__PURE__ */ jsx("span", { className: "pollar-asset-sponsor", children: record.sponsored ? "Reserve sponsored by the app" : "You pay the reserve (~0.5 XLM)" })
|
|
1372
1467
|
] }),
|
|
1373
|
-
/* @__PURE__ */ jsxs("div", { className: "pollar-asset-actions", children: [
|
|
1374
|
-
/* @__PURE__ */ jsx("span", { className:
|
|
1375
|
-
|
|
1376
|
-
|
|
1468
|
+
isStellar && /* @__PURE__ */ jsxs("div", { className: "pollar-asset-actions", children: [
|
|
1469
|
+
/* @__PURE__ */ jsx("span", { className: "pollar-asset-trustline-label", children: "Trustline" }),
|
|
1470
|
+
/* @__PURE__ */ jsx(
|
|
1471
|
+
Toggle,
|
|
1377
1472
|
{
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
disabled:
|
|
1381
|
-
|
|
1473
|
+
checked: established,
|
|
1474
|
+
busy,
|
|
1475
|
+
disabled: isNative || disabled,
|
|
1476
|
+
onChange: () => onToggle(record),
|
|
1477
|
+
label: `${established ? "Disable" : "Enable"} ${record.code} trustline`
|
|
1382
1478
|
}
|
|
1383
1479
|
)
|
|
1384
1480
|
] })
|
|
@@ -1389,6 +1485,9 @@ function EnabledAssetsModalTemplate({
|
|
|
1389
1485
|
accentColor,
|
|
1390
1486
|
enabledAssets,
|
|
1391
1487
|
walletAddress,
|
|
1488
|
+
chains,
|
|
1489
|
+
selectedChain,
|
|
1490
|
+
onSelectChain,
|
|
1392
1491
|
busyKey,
|
|
1393
1492
|
actionError,
|
|
1394
1493
|
onRefresh,
|
|
@@ -1398,8 +1497,10 @@ function EnabledAssetsModalTemplate({
|
|
|
1398
1497
|
}) {
|
|
1399
1498
|
const cssVars = cssVarsFor(theme, accentColor);
|
|
1400
1499
|
const isLoading = enabledAssets.step === "loading";
|
|
1401
|
-
const data = enabledAssets.step === "loaded" ? enabledAssets.data : null;
|
|
1500
|
+
const data = useStickyData(enabledAssets.step === "loaded" ? enabledAssets.data : null);
|
|
1402
1501
|
const busy = busyKey !== null;
|
|
1502
|
+
const assets = (data?.assets ?? []).filter((a) => resolveChain(a.chain) === selectedChain);
|
|
1503
|
+
const isStellarSelected = selectedChain === "STELLAR";
|
|
1403
1504
|
return /* @__PURE__ */ jsxs(
|
|
1404
1505
|
"div",
|
|
1405
1506
|
{
|
|
@@ -1408,8 +1509,9 @@ function EnabledAssetsModalTemplate({
|
|
|
1408
1509
|
style: cssVars,
|
|
1409
1510
|
onClick: (e) => e.stopPropagation(),
|
|
1410
1511
|
children: [
|
|
1512
|
+
isLoading && data && /* @__PURE__ */ jsx(BusyOverlay, { label: "Refreshing assets\u2026" }),
|
|
1411
1513
|
/* @__PURE__ */ jsxs("div", { className: "pollar-modal-header", children: [
|
|
1412
|
-
/* @__PURE__ */ jsx("h2", { className: "pollar-modal-title", children: "
|
|
1514
|
+
/* @__PURE__ */ jsx("h2", { className: "pollar-modal-title", children: "Assets" }),
|
|
1413
1515
|
/* @__PURE__ */ jsxs("div", { className: "pollar-modal-header-actions", children: [
|
|
1414
1516
|
/* @__PURE__ */ jsx(
|
|
1415
1517
|
"button",
|
|
@@ -1446,8 +1548,12 @@ function EnabledAssetsModalTemplate({
|
|
|
1446
1548
|
/* @__PURE__ */ jsx("button", { className: "pollar-modal-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M2 2l12 12M14 2L2 14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) })
|
|
1447
1549
|
] })
|
|
1448
1550
|
] }),
|
|
1449
|
-
|
|
1450
|
-
|
|
1551
|
+
/* @__PURE__ */ jsx(ChainSelect, { value: selectedChain, options: chains, onChange: onSelectChain, disabled: isLoading || busy }),
|
|
1552
|
+
walletAddress && /* @__PURE__ */ jsxs("div", { className: "pollar-address-row", children: [
|
|
1553
|
+
/* @__PURE__ */ jsx("span", { className: "pollar-address", children: cropAddress(walletAddress) }),
|
|
1554
|
+
/* @__PURE__ */ jsx(CopyButton, { value: walletAddress, label: "Copy wallet address" })
|
|
1555
|
+
] }),
|
|
1556
|
+
isLoading && !data && /* @__PURE__ */ jsxs("div", { className: "pollar-loading-block", children: [
|
|
1451
1557
|
/* @__PURE__ */ jsx("div", { className: "pollar-spinner" }),
|
|
1452
1558
|
/* @__PURE__ */ jsx("span", { children: "Loading\u2026" })
|
|
1453
1559
|
] }),
|
|
@@ -1458,8 +1564,8 @@ function EnabledAssetsModalTemplate({
|
|
|
1458
1564
|
data.network,
|
|
1459
1565
|
"."
|
|
1460
1566
|
] }),
|
|
1461
|
-
data &&
|
|
1462
|
-
data &&
|
|
1567
|
+
data && assets.length === 0 && /* @__PURE__ */ jsx("div", { className: "pollar-modal-empty", children: "No assets found on this network." }),
|
|
1568
|
+
data && assets.length > 0 && /* @__PURE__ */ jsx("div", { className: "pollar-asset-list", children: assets.map((a) => /* @__PURE__ */ jsx(
|
|
1463
1569
|
AssetItem,
|
|
1464
1570
|
{
|
|
1465
1571
|
record: a,
|
|
@@ -1467,9 +1573,9 @@ function EnabledAssetsModalTemplate({
|
|
|
1467
1573
|
disabled: busy && busyKey !== assetKey(a),
|
|
1468
1574
|
onToggle: onToggleTrustline
|
|
1469
1575
|
},
|
|
1470
|
-
|
|
1576
|
+
rowKey(a)
|
|
1471
1577
|
)) }),
|
|
1472
|
-
/* @__PURE__ */ jsx("button", { className: "pollar-asset-add-custom", onClick: onAddCustom, disabled: busy, children: "+ Add custom trustline" }),
|
|
1578
|
+
isStellarSelected && /* @__PURE__ */ jsx("button", { className: "pollar-asset-add-custom", onClick: onAddCustom, disabled: busy, children: "+ Add custom trustline" }),
|
|
1473
1579
|
/* @__PURE__ */ jsx(PollarModalFooter, {})
|
|
1474
1580
|
]
|
|
1475
1581
|
}
|
|
@@ -1583,9 +1689,14 @@ function assetKey2(record) {
|
|
|
1583
1689
|
return record.code + (record.issuer ?? "");
|
|
1584
1690
|
}
|
|
1585
1691
|
function EnabledAssetsModal({ onClose }) {
|
|
1586
|
-
const { enabledAssets, refreshAssets, setTrustline,
|
|
1587
|
-
const walletAddress = wallet?.address ?? "";
|
|
1692
|
+
const { enabledAssets, refreshAssets, setTrustline, wallets, styles } = usePollar();
|
|
1588
1693
|
const { theme = "light", accentColor = "#005DB4" } = styles;
|
|
1694
|
+
const { chains } = useChains();
|
|
1695
|
+
const [selectedChain, setSelectedChain] = useState(null);
|
|
1696
|
+
useEffect(() => {
|
|
1697
|
+
if (selectedChain === null && chains.length > 0) setSelectedChain(chains[0]);
|
|
1698
|
+
}, [chains, selectedChain]);
|
|
1699
|
+
const walletAddress = addressForChain(wallets, selectedChain);
|
|
1589
1700
|
const [view, setView] = useState("list");
|
|
1590
1701
|
const [busyKey, setBusyKey] = useState(null);
|
|
1591
1702
|
const [actionError, setActionError] = useState(null);
|
|
@@ -1614,7 +1725,7 @@ function EnabledAssetsModal({ onClose }) {
|
|
|
1614
1725
|
void runAction(
|
|
1615
1726
|
assetKey2(record),
|
|
1616
1727
|
{ code: record.code, issuer: record.issuer ?? "" },
|
|
1617
|
-
{ ...removing ? { limit: "0" } : {}
|
|
1728
|
+
{ ...removing ? { limit: "0" } : {} }
|
|
1618
1729
|
);
|
|
1619
1730
|
},
|
|
1620
1731
|
[runAction]
|
|
@@ -1624,7 +1735,7 @@ function EnabledAssetsModal({ onClose }) {
|
|
|
1624
1735
|
const ok = await runAction(
|
|
1625
1736
|
"custom",
|
|
1626
1737
|
{ code: input.code, issuer: input.issuer },
|
|
1627
|
-
{ ...input.limit ? { limit: input.limit } : {},
|
|
1738
|
+
{ ...input.limit ? { limit: input.limit } : {}, skipSponsorship: true }
|
|
1628
1739
|
);
|
|
1629
1740
|
if (ok) setView("list");
|
|
1630
1741
|
},
|
|
@@ -1637,6 +1748,9 @@ function EnabledAssetsModal({ onClose }) {
|
|
|
1637
1748
|
accentColor,
|
|
1638
1749
|
enabledAssets,
|
|
1639
1750
|
walletAddress,
|
|
1751
|
+
chains,
|
|
1752
|
+
selectedChain,
|
|
1753
|
+
onSelectChain: setSelectedChain,
|
|
1640
1754
|
busyKey,
|
|
1641
1755
|
actionError,
|
|
1642
1756
|
onRefresh: () => refreshAssets(),
|
|
@@ -3355,10 +3469,18 @@ var QRCode = forwardRef(function QRCode2({ bgColor = "#FFFFFF", fgColor = "#0000
|
|
|
3355
3469
|
}
|
|
3356
3470
|
);
|
|
3357
3471
|
});
|
|
3472
|
+
var CHAIN_NAME = {
|
|
3473
|
+
STELLAR: "Stellar",
|
|
3474
|
+
POLYGON: "Polygon",
|
|
3475
|
+
SOLANA: "Solana"
|
|
3476
|
+
};
|
|
3358
3477
|
function ReceiveModalTemplate({
|
|
3359
3478
|
theme,
|
|
3360
3479
|
accentColor,
|
|
3361
3480
|
walletAddress,
|
|
3481
|
+
chains,
|
|
3482
|
+
selectedChain,
|
|
3483
|
+
onSelectChain,
|
|
3362
3484
|
copied,
|
|
3363
3485
|
onCopy,
|
|
3364
3486
|
onClose
|
|
@@ -3381,6 +3503,7 @@ function ReceiveModalTemplate({
|
|
|
3381
3503
|
"--pollar-input-border-radius": "0.5rem",
|
|
3382
3504
|
"--pollar-card-border-radius": "10px"
|
|
3383
3505
|
};
|
|
3506
|
+
const chainName = selectedChain ? CHAIN_NAME[selectedChain] ?? selectedChain : "wallet";
|
|
3384
3507
|
return /* @__PURE__ */ jsxs(
|
|
3385
3508
|
"div",
|
|
3386
3509
|
{
|
|
@@ -3393,9 +3516,16 @@ function ReceiveModalTemplate({
|
|
|
3393
3516
|
/* @__PURE__ */ jsx("h2", { className: "pollar-modal-title", children: "Receive" }),
|
|
3394
3517
|
/* @__PURE__ */ jsx("div", { className: "pollar-modal-header-actions", children: /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-modal-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M2 2l12 12M14 2L2 14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) }) })
|
|
3395
3518
|
] }),
|
|
3519
|
+
/* @__PURE__ */ jsx(ChainSelect, { value: selectedChain, options: chains, onChange: onSelectChain }),
|
|
3396
3520
|
walletAddress ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3397
3521
|
/* @__PURE__ */ jsx("div", { className: "pollar-receive-qr", children: /* @__PURE__ */ jsx(QRCode, { value: walletAddress, size: 180, fgColor: isDark ? "#ffffff" : "#111827", bgColor: "transparent" }) }),
|
|
3398
|
-
/* @__PURE__ */
|
|
3522
|
+
/* @__PURE__ */ jsxs("p", { className: "pollar-receive-instructions", children: [
|
|
3523
|
+
"Share your ",
|
|
3524
|
+
chainName,
|
|
3525
|
+
" address to receive any asset. Only send ",
|
|
3526
|
+
chainName,
|
|
3527
|
+
" assets to this address. Funds sent from another network are lost."
|
|
3528
|
+
] }),
|
|
3399
3529
|
/* @__PURE__ */ jsxs("div", { className: "pollar-receive-address-row", children: [
|
|
3400
3530
|
/* @__PURE__ */ jsx("span", { className: "pollar-receive-address", children: walletAddress }),
|
|
3401
3531
|
/* @__PURE__ */ jsx("button", { type: "button", className: "pollar-receive-copy-btn", onClick: onCopy, "aria-label": "Copy address", children: copied ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -3436,11 +3566,16 @@ function ReceiveModalTemplate({
|
|
|
3436
3566
|
);
|
|
3437
3567
|
}
|
|
3438
3568
|
function ReceiveModal({ onClose }) {
|
|
3439
|
-
const {
|
|
3440
|
-
const walletAddress = wallet?.address ?? "";
|
|
3569
|
+
const { wallets, styles } = usePollar();
|
|
3441
3570
|
const { theme = "light", accentColor = "#005DB4" } = styles;
|
|
3442
3571
|
const [copied, setCopied] = useState(false);
|
|
3443
3572
|
const copyTimerRef = useRef(null);
|
|
3573
|
+
const { chains } = useChains();
|
|
3574
|
+
const [selectedChain, setSelectedChain] = useState(null);
|
|
3575
|
+
useEffect(() => {
|
|
3576
|
+
if (selectedChain === null && chains.length > 0) setSelectedChain(chains[0]);
|
|
3577
|
+
}, [chains, selectedChain]);
|
|
3578
|
+
const walletAddress = addressForChain(wallets, selectedChain);
|
|
3444
3579
|
useEffect(
|
|
3445
3580
|
() => () => {
|
|
3446
3581
|
if (copyTimerRef.current !== null) clearTimeout(copyTimerRef.current);
|
|
@@ -3464,6 +3599,12 @@ function ReceiveModal({ onClose }) {
|
|
|
3464
3599
|
theme,
|
|
3465
3600
|
accentColor,
|
|
3466
3601
|
walletAddress,
|
|
3602
|
+
chains,
|
|
3603
|
+
selectedChain,
|
|
3604
|
+
onSelectChain: (chain) => {
|
|
3605
|
+
setCopied(false);
|
|
3606
|
+
setSelectedChain(chain);
|
|
3607
|
+
},
|
|
3467
3608
|
copied,
|
|
3468
3609
|
onCopy: handleCopy,
|
|
3469
3610
|
onClose
|
|
@@ -3709,6 +3850,7 @@ function TxStatusView({
|
|
|
3709
3850
|
] });
|
|
3710
3851
|
}
|
|
3711
3852
|
function formatBalance(balance) {
|
|
3853
|
+
if (balance === null) return "\u2014";
|
|
3712
3854
|
const n = parseFloat(balance);
|
|
3713
3855
|
return isNaN(n) ? balance : n.toLocaleString(void 0, { maximumFractionDigits: 7 });
|
|
3714
3856
|
}
|
|
@@ -3722,6 +3864,11 @@ function SendModalTemplate({
|
|
|
3722
3864
|
txTitle,
|
|
3723
3865
|
assets,
|
|
3724
3866
|
selectedAsset,
|
|
3867
|
+
chains,
|
|
3868
|
+
selectedChain,
|
|
3869
|
+
walletAddress,
|
|
3870
|
+
canSendOnChain,
|
|
3871
|
+
onSelectChain,
|
|
3725
3872
|
amount,
|
|
3726
3873
|
destination,
|
|
3727
3874
|
formError,
|
|
@@ -3765,7 +3912,7 @@ function SendModalTemplate({
|
|
|
3765
3912
|
"--pollar-card-border-radius": "10px"
|
|
3766
3913
|
};
|
|
3767
3914
|
const selectedKey = selectedAsset ? assetKey3(selectedAsset) : "";
|
|
3768
|
-
const canSubmit = !!selectedAsset && !!amount && !!destination.trim() && !isLoadingBalance;
|
|
3915
|
+
const canSubmit = canSendOnChain && !!selectedAsset && !!amount && !!destination.trim() && !isLoadingBalance;
|
|
3769
3916
|
const title = step === "form" ? "Send" : txTitle;
|
|
3770
3917
|
return /* @__PURE__ */ jsxs(
|
|
3771
3918
|
"div",
|
|
@@ -3817,6 +3964,12 @@ function SendModalTemplate({
|
|
|
3817
3964
|
] })
|
|
3818
3965
|
] }),
|
|
3819
3966
|
step === "form" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3967
|
+
/* @__PURE__ */ jsx(ChainSelect, { value: selectedChain, options: chains, onChange: onSelectChain, disabled: isLoadingBalance }),
|
|
3968
|
+
walletAddress && /* @__PURE__ */ jsxs("div", { className: "pollar-address-row", children: [
|
|
3969
|
+
/* @__PURE__ */ jsx("span", { className: "pollar-address", children: cropAddress(walletAddress) }),
|
|
3970
|
+
/* @__PURE__ */ jsx(CopyButton, { value: walletAddress, label: "Copy wallet address" })
|
|
3971
|
+
] }),
|
|
3972
|
+
!canSendOnChain && /* @__PURE__ */ jsx("div", { className: "pollar-modal-empty", children: "Sending is not available on this network yet." }),
|
|
3820
3973
|
/* @__PURE__ */ jsx(
|
|
3821
3974
|
AssetSelect,
|
|
3822
3975
|
{
|
|
@@ -3827,7 +3980,9 @@ function SendModalTemplate({
|
|
|
3827
3980
|
options: assets.map((a) => ({
|
|
3828
3981
|
key: assetKey3(a),
|
|
3829
3982
|
code: a.code,
|
|
3830
|
-
available
|
|
3983
|
+
// Unreadable (null) drops the "— X available" suffix instead of
|
|
3984
|
+
// claiming a zero balance.
|
|
3985
|
+
available: a.available ?? void 0,
|
|
3831
3986
|
enabledInApp: a.enabledInApp
|
|
3832
3987
|
})),
|
|
3833
3988
|
onChange: (key) => {
|
|
@@ -3906,9 +4061,11 @@ function SendModal({ onClose }) {
|
|
|
3906
4061
|
walletBalance,
|
|
3907
4062
|
refreshWalletBalance,
|
|
3908
4063
|
buildTx,
|
|
4064
|
+
sendPayment,
|
|
3909
4065
|
signAndSubmitTx,
|
|
3910
4066
|
tx: transaction,
|
|
3911
4067
|
wallet,
|
|
4068
|
+
wallets,
|
|
3912
4069
|
network,
|
|
3913
4070
|
styles
|
|
3914
4071
|
} = usePollar();
|
|
@@ -3922,6 +4079,14 @@ function SendModal({ onClose }) {
|
|
|
3922
4079
|
const [copied, setCopied] = useState(false);
|
|
3923
4080
|
const [formError, setFormError] = useState("");
|
|
3924
4081
|
const copyTimerRef = useRef(null);
|
|
4082
|
+
const { chains } = useChains();
|
|
4083
|
+
const [selectedChain, setSelectedChain] = useState(null);
|
|
4084
|
+
useEffect(() => {
|
|
4085
|
+
if (selectedChain === null && chains.length > 0) setSelectedChain(chains[0]);
|
|
4086
|
+
}, [chains, selectedChain]);
|
|
4087
|
+
const walletAddress = addressForChain(wallets, selectedChain);
|
|
4088
|
+
const canSendOnChain = selectedChain === "STELLAR" || selectedChain === "SOLANA";
|
|
4089
|
+
const isBaseUnitChain = selectedChain === "SOLANA";
|
|
3925
4090
|
useEffect(() => {
|
|
3926
4091
|
void refreshWalletBalance();
|
|
3927
4092
|
}, [refreshWalletBalance]);
|
|
@@ -3932,18 +4097,24 @@ function SendModal({ onClose }) {
|
|
|
3932
4097
|
[]
|
|
3933
4098
|
);
|
|
3934
4099
|
const balanceData = walletBalance.step === "loaded" ? walletBalance.data : null;
|
|
3935
|
-
const allAssets = (balanceData?.balances ?? []).filter((b) => b.chain ===
|
|
4100
|
+
const allAssets = (balanceData?.balances ?? []).filter((b) => resolveChain(b.chain) === selectedChain);
|
|
3936
4101
|
const sortedAssets = [
|
|
3937
4102
|
...allAssets.filter((b) => b.enabledInApp),
|
|
3938
|
-
|
|
4103
|
+
// An unreadable balance (null) is not a positive one, so it stays out.
|
|
4104
|
+
...allAssets.filter((b) => !b.enabledInApp && (b.type === "native" || parseFloat(b.balance ?? "0") > 0))
|
|
3939
4105
|
];
|
|
3940
4106
|
useEffect(() => {
|
|
4107
|
+
const stranded = selectedAsset !== null && resolveChain(selectedAsset.chain) !== selectedChain;
|
|
4108
|
+
if (stranded) {
|
|
4109
|
+
setSelectedAsset(sortedAssets[0] ?? null);
|
|
4110
|
+
return;
|
|
4111
|
+
}
|
|
3941
4112
|
if (!selectedAsset && sortedAssets.length > 0) setSelectedAsset(sortedAssets[0]);
|
|
3942
|
-
}, [sortedAssets, selectedAsset]);
|
|
4113
|
+
}, [sortedAssets, selectedAsset, selectedChain]);
|
|
3943
4114
|
const hash = transaction.step === "success" ? transaction.hash : null;
|
|
3944
4115
|
const buildData = "buildData" in transaction ? transaction.buildData : null;
|
|
3945
4116
|
const explorerNetwork = buildData?.summary.network?.toLowerCase().includes("testnet") ? "testnet" : buildData ? "public" : network === "testnet" ? "testnet" : "public";
|
|
3946
|
-
const explorerUrl = hash ? `https://stellar.expert/explorer/${explorerNetwork}/tx/${hash}
|
|
4117
|
+
const explorerUrl = !hash ? null : selectedChain === "SOLANA" ? `https://explorer.solana.com/tx/${hash}${explorerNetwork === "testnet" ? "?cluster=devnet" : ""}` : `https://stellar.expert/explorer/${explorerNetwork}/tx/${hash}`;
|
|
3947
4118
|
const IN_FLIGHT_STEPS3 = [
|
|
3948
4119
|
"building",
|
|
3949
4120
|
"signing",
|
|
@@ -3957,6 +4128,10 @@ function SendModal({ onClose }) {
|
|
|
3957
4128
|
const txTitle = isInProgress ? "Sending\u2026" : transaction.step === "success" ? "Sent!" : transaction.step === "error" ? "Send failed" : "Confirm Send";
|
|
3958
4129
|
async function handleSubmit() {
|
|
3959
4130
|
setFormError("");
|
|
4131
|
+
if (!canSendOnChain) {
|
|
4132
|
+
setFormError("Sending is not available on this network yet.");
|
|
4133
|
+
return;
|
|
4134
|
+
}
|
|
3960
4135
|
if (!selectedAsset) {
|
|
3961
4136
|
setFormError("Select an asset");
|
|
3962
4137
|
return;
|
|
@@ -3966,7 +4141,7 @@ function SendModal({ onClose }) {
|
|
|
3966
4141
|
setFormError("Enter a valid amount");
|
|
3967
4142
|
return;
|
|
3968
4143
|
}
|
|
3969
|
-
if (parsed > parseFloat(selectedAsset.available)) {
|
|
4144
|
+
if (parsed > parseFloat(selectedAsset.available ?? "0")) {
|
|
3970
4145
|
setFormError("Insufficient balance");
|
|
3971
4146
|
return;
|
|
3972
4147
|
}
|
|
@@ -3974,7 +4149,32 @@ function SendModal({ onClose }) {
|
|
|
3974
4149
|
setFormError("Enter a destination address");
|
|
3975
4150
|
return;
|
|
3976
4151
|
}
|
|
4152
|
+
const isNativeAsset = selectedAsset.type === "native";
|
|
4153
|
+
if (isBaseUnitChain && !isNativeAsset && (!selectedAsset.issuer || selectedAsset.decimals === void 0)) {
|
|
4154
|
+
setFormError("This token is missing its mint or decimals and cannot be sent.");
|
|
4155
|
+
return;
|
|
4156
|
+
}
|
|
4157
|
+
let sendAmount = amount;
|
|
4158
|
+
if (isBaseUnitChain) {
|
|
4159
|
+
try {
|
|
4160
|
+
sendAmount = toBaseUnits(amount, selectedAsset.decimals ?? 9);
|
|
4161
|
+
} catch (e) {
|
|
4162
|
+
setFormError(e instanceof Error ? e.message : "Invalid amount");
|
|
4163
|
+
return;
|
|
4164
|
+
}
|
|
4165
|
+
}
|
|
3977
4166
|
setStep("tx");
|
|
4167
|
+
if (selectedChain === "SOLANA") {
|
|
4168
|
+
await sendPayment({
|
|
4169
|
+
chain: "SOLANA",
|
|
4170
|
+
destination: destination.trim(),
|
|
4171
|
+
amount: sendAmount,
|
|
4172
|
+
// Native SOL carries no mint; an SPL token's mint rides in `issuer`,
|
|
4173
|
+
// which the guard above proved is present.
|
|
4174
|
+
...isNativeAsset ? {} : { mint: selectedAsset.issuer }
|
|
4175
|
+
});
|
|
4176
|
+
return;
|
|
4177
|
+
}
|
|
3978
4178
|
await buildTx("payment", { destination: destination.trim(), amount, asset: assetParam(selectedAsset) });
|
|
3979
4179
|
}
|
|
3980
4180
|
function handleSignAndSend() {
|
|
@@ -4012,6 +4212,11 @@ function SendModal({ onClose }) {
|
|
|
4012
4212
|
txTitle,
|
|
4013
4213
|
assets: sortedAssets,
|
|
4014
4214
|
selectedAsset,
|
|
4215
|
+
chains,
|
|
4216
|
+
selectedChain,
|
|
4217
|
+
walletAddress,
|
|
4218
|
+
canSendOnChain,
|
|
4219
|
+
onSelectChain: setSelectedChain,
|
|
4015
4220
|
amount,
|
|
4016
4221
|
destination,
|
|
4017
4222
|
formError,
|
|
@@ -4438,11 +4643,19 @@ function SwapModal({ onClose }) {
|
|
|
4438
4643
|
const assetRecords = enabledAssets.step === "loaded" ? enabledAssets.data.assets : [];
|
|
4439
4644
|
const isLoadingData = walletBalance.step === "loading" || enabledAssets.step === "loading";
|
|
4440
4645
|
const sellOptions = balances.filter(
|
|
4441
|
-
(b) => b.
|
|
4442
|
-
).map((b) => ({
|
|
4646
|
+
(b) => (b.chain === void 0 || b.chain === "STELLAR") && (b.type === "native" || (b.type === "credit_alphanum4" || b.type === "credit_alphanum12") && !b.trustlineRemoved)
|
|
4647
|
+
).map((b) => ({
|
|
4648
|
+
ref: toRef(b),
|
|
4649
|
+
code: b.code,
|
|
4650
|
+
issuer: b.issuer,
|
|
4651
|
+
available: b.available ?? void 0,
|
|
4652
|
+
enabledInApp: b.enabledInApp
|
|
4653
|
+
}));
|
|
4443
4654
|
const buyKeyOfSell = selectedSell ? `${selectedSell.code}:${selectedSell.issuer ?? "native"}` : "";
|
|
4444
4655
|
const optKey = (o) => `${o.code}:${o.issuer ?? "native"}`;
|
|
4445
|
-
const enabledBuy = assetRecords.
|
|
4656
|
+
const enabledBuy = assetRecords.filter(
|
|
4657
|
+
(a) => (a.chain === void 0 || a.chain === "STELLAR") && (a.type === "native" || a.type === "credit_alphanum4" || a.type === "credit_alphanum12")
|
|
4658
|
+
).map((a) => ({
|
|
4446
4659
|
ref: toRef(a),
|
|
4447
4660
|
code: a.code,
|
|
4448
4661
|
issuer: a.issuer,
|
|
@@ -4743,15 +4956,13 @@ function EarnModal({ onClose }) {
|
|
|
4743
4956
|
if (!selectedOpportunity) return null;
|
|
4744
4957
|
const balances = walletBalance.step === "loaded" ? walletBalance.data.balances : [];
|
|
4745
4958
|
const issuer = selectedOpportunity.asset.issuer;
|
|
4746
|
-
const rec = balances.find(
|
|
4747
|
-
(b) => issuer === null ? b.type === "native" : b.code === assetCode && b.issuer === issuer
|
|
4748
|
-
);
|
|
4959
|
+
const rec = balances.find((b) => issuer === null ? b.type === "native" : b.code === assetCode && b.issuer === issuer);
|
|
4749
4960
|
return rec ? rec.available : null;
|
|
4750
4961
|
})();
|
|
4751
4962
|
const depositAssetRecord = (() => {
|
|
4752
4963
|
if (!selectedOpportunity?.asset.issuer || enabledAssets.step !== "loaded") return void 0;
|
|
4753
4964
|
return enabledAssets.data.assets.find(
|
|
4754
|
-
(a) => a.code === assetCode && a.issuer === selectedOpportunity.asset.issuer
|
|
4965
|
+
(a) => (a.chain === void 0 || a.chain === "STELLAR") && a.code === assetCode && a.issuer === selectedOpportunity.asset.issuer
|
|
4755
4966
|
);
|
|
4756
4967
|
})();
|
|
4757
4968
|
const depositNeedsTrustline = tab === "deposit" && !smartUnsupported && !!selectedOpportunity?.asset.issuer && !depositAssetRecord?.trustlineEstablished;
|
|
@@ -4807,10 +5018,7 @@ function EarnModal({ onClose }) {
|
|
|
4807
5018
|
}
|
|
4808
5019
|
setStep("tx");
|
|
4809
5020
|
if (tab === "deposit" && depositNeedsTrustline && selectedOpportunity?.asset.issuer) {
|
|
4810
|
-
const tl = await setTrustline(
|
|
4811
|
-
{ code: assetCode, issuer: selectedOpportunity.asset.issuer },
|
|
4812
|
-
depositAssetRecord?.sponsored ? { sponsored: true } : void 0
|
|
4813
|
-
);
|
|
5021
|
+
const tl = await setTrustline({ code: assetCode, issuer: selectedOpportunity.asset.issuer });
|
|
4814
5022
|
if (tl.status === "error") {
|
|
4815
5023
|
setFormError(`Trustline for ${assetCode} failed: ${tl.details ?? "unknown error"}`);
|
|
4816
5024
|
setStep("form");
|
|
@@ -5425,6 +5633,12 @@ function TransactionModal({ onClose }) {
|
|
|
5425
5633
|
) });
|
|
5426
5634
|
}
|
|
5427
5635
|
var PAGE_SIZE = 10;
|
|
5636
|
+
function explorerUrlFor(chain, hash, network) {
|
|
5637
|
+
if (chain === "SOLANA") {
|
|
5638
|
+
return `https://explorer.solana.com/tx/${hash}${network === "testnet" ? "?cluster=devnet" : ""}`;
|
|
5639
|
+
}
|
|
5640
|
+
return `https://stellar.expert/explorer/${network === "testnet" ? "testnet" : "public"}/tx/${hash}`;
|
|
5641
|
+
}
|
|
5428
5642
|
function StatusBadge({ status }) {
|
|
5429
5643
|
return /* @__PURE__ */ jsx("span", { className: "pollar-hist-item-badge", "data-status": status, children: status });
|
|
5430
5644
|
}
|
|
@@ -5463,6 +5677,10 @@ function TxHistoryModalTemplate({
|
|
|
5463
5677
|
accentColor,
|
|
5464
5678
|
txHistory,
|
|
5465
5679
|
offset,
|
|
5680
|
+
chains,
|
|
5681
|
+
selectedChain,
|
|
5682
|
+
walletAddress,
|
|
5683
|
+
onSelectChain,
|
|
5466
5684
|
onRefresh,
|
|
5467
5685
|
onPrev,
|
|
5468
5686
|
onNext,
|
|
@@ -5538,6 +5756,11 @@ function TxHistoryModalTemplate({
|
|
|
5538
5756
|
/* @__PURE__ */ jsx("button", { className: "pollar-modal-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M2 2l12 12M14 2L2 14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) })
|
|
5539
5757
|
] })
|
|
5540
5758
|
] }),
|
|
5759
|
+
/* @__PURE__ */ jsx(ChainSelect, { value: selectedChain, options: chains, onChange: onSelectChain, disabled: isLoading }),
|
|
5760
|
+
walletAddress && /* @__PURE__ */ jsxs("div", { className: "pollar-address-row", children: [
|
|
5761
|
+
/* @__PURE__ */ jsx("span", { className: "pollar-address", children: cropAddress(walletAddress) }),
|
|
5762
|
+
/* @__PURE__ */ jsx(CopyButton, { value: walletAddress, label: "Copy wallet address" })
|
|
5763
|
+
] }),
|
|
5541
5764
|
/* @__PURE__ */ jsxs("div", { className: "pollar-hist-list", children: [
|
|
5542
5765
|
txHistory.step === "idle" && /* @__PURE__ */ jsx("div", { className: "pollar-modal-empty", children: "Click Refresh to load transactions." }),
|
|
5543
5766
|
isLoading && /* @__PURE__ */ jsxs("div", { className: "pollar-loading-block", children: [
|
|
@@ -5548,7 +5771,7 @@ function TxHistoryModalTemplate({
|
|
|
5548
5771
|
txHistory.step === "loaded" && records.length === 0 && /* @__PURE__ */ jsx("div", { className: "pollar-modal-empty", children: "No transactions yet." }),
|
|
5549
5772
|
records.map((record) => {
|
|
5550
5773
|
const hash = typeof record.hash === "string" && record.hash.length > 0 ? record.hash : void 0;
|
|
5551
|
-
const explorerUrl = hash ?
|
|
5774
|
+
const explorerUrl = hash ? explorerUrlFor(record.chain, hash, record.network) : void 0;
|
|
5552
5775
|
const asset = typeof record.details?.asset === "string" ? record.details.asset : void 0;
|
|
5553
5776
|
const colon = asset ? asset.indexOf(":") : -1;
|
|
5554
5777
|
const trustline = record.operation === "change_trust" && asset && colon > 0 ? {
|
|
@@ -5582,10 +5805,11 @@ function TxHistoryModalTemplate({
|
|
|
5582
5805
|
"\xB7 ",
|
|
5583
5806
|
record.details.sponsored ? "Sponsored" : "Self-paid"
|
|
5584
5807
|
] }),
|
|
5585
|
-
record.
|
|
5808
|
+
record.fee && /* @__PURE__ */ jsxs("span", { children: [
|
|
5586
5809
|
"\xB7 ",
|
|
5587
|
-
record.
|
|
5588
|
-
"
|
|
5810
|
+
record.fee.amount,
|
|
5811
|
+
" ",
|
|
5812
|
+
record.fee.unit
|
|
5589
5813
|
] })
|
|
5590
5814
|
] }),
|
|
5591
5815
|
/* @__PURE__ */ jsxs("div", { className: "pollar-hist-item-footer", children: [
|
|
@@ -5601,7 +5825,7 @@ function TxHistoryModalTemplate({
|
|
|
5601
5825
|
href: explorerUrl,
|
|
5602
5826
|
target: "_blank",
|
|
5603
5827
|
rel: "noopener noreferrer",
|
|
5604
|
-
"aria-label": "View on
|
|
5828
|
+
"aria-label": "View on block explorer",
|
|
5605
5829
|
children: /* @__PURE__ */ jsxs("svg", { width: "12", height: "12", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
|
|
5606
5830
|
/* @__PURE__ */ jsx(
|
|
5607
5831
|
"path",
|
|
@@ -5650,19 +5874,29 @@ function TxHistoryModalTemplate({
|
|
|
5650
5874
|
}
|
|
5651
5875
|
var PAGE_SIZE2 = 10;
|
|
5652
5876
|
function TxHistoryModal({ onClose }) {
|
|
5653
|
-
const { getClient, styles, txHistory } = usePollar();
|
|
5877
|
+
const { getClient, styles, txHistory, wallets } = usePollar();
|
|
5654
5878
|
const { theme = "light", accentColor = "#005DB4" } = styles;
|
|
5655
5879
|
const [offset, setOffset] = useState(0);
|
|
5880
|
+
const { chains } = useChains();
|
|
5881
|
+
const [selectedChain, setSelectedChain] = useState(null);
|
|
5882
|
+
useEffect(() => {
|
|
5883
|
+
if (selectedChain === null && chains.length > 0) setSelectedChain(chains[0]);
|
|
5884
|
+
}, [chains, selectedChain]);
|
|
5885
|
+
const walletAddress = addressForChain(wallets, selectedChain);
|
|
5656
5886
|
const load = useCallback(
|
|
5657
|
-
(nextOffset) => {
|
|
5887
|
+
(nextOffset, chain) => {
|
|
5658
5888
|
setOffset(nextOffset);
|
|
5659
|
-
void getClient().fetchTxHistory({ limit: PAGE_SIZE2, offset: nextOffset });
|
|
5889
|
+
void getClient().fetchTxHistory({ limit: PAGE_SIZE2, offset: nextOffset, chain });
|
|
5660
5890
|
},
|
|
5661
5891
|
[getClient]
|
|
5662
5892
|
);
|
|
5663
5893
|
useEffect(() => {
|
|
5664
|
-
load(0);
|
|
5665
|
-
}, [load]);
|
|
5894
|
+
if (selectedChain) load(0, selectedChain);
|
|
5895
|
+
}, [selectedChain, load]);
|
|
5896
|
+
const onSelectChain = (chain) => setSelectedChain(chain);
|
|
5897
|
+
const paged = (nextOffset) => {
|
|
5898
|
+
if (selectedChain) load(nextOffset, selectedChain);
|
|
5899
|
+
};
|
|
5666
5900
|
return /* @__PURE__ */ jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsx(
|
|
5667
5901
|
TxHistoryModalTemplate,
|
|
5668
5902
|
{
|
|
@@ -5670,47 +5904,48 @@ function TxHistoryModal({ onClose }) {
|
|
|
5670
5904
|
accentColor,
|
|
5671
5905
|
txHistory,
|
|
5672
5906
|
offset,
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5907
|
+
chains,
|
|
5908
|
+
selectedChain,
|
|
5909
|
+
walletAddress,
|
|
5910
|
+
onSelectChain,
|
|
5911
|
+
onRefresh: () => paged(offset),
|
|
5912
|
+
onPrev: () => paged(Math.max(0, offset - PAGE_SIZE2)),
|
|
5913
|
+
onNext: () => paged(offset + PAGE_SIZE2),
|
|
5676
5914
|
onClose
|
|
5677
5915
|
}
|
|
5678
5916
|
) });
|
|
5679
5917
|
}
|
|
5680
|
-
function formatBalance2(balance) {
|
|
5918
|
+
function formatBalance2(balance, decimals = 7) {
|
|
5919
|
+
if (balance === null) return "\u2014";
|
|
5920
|
+
const digits = Math.min(decimals, 7);
|
|
5681
5921
|
const n = parseFloat(balance);
|
|
5682
|
-
return isNaN(n) ? balance : n.toLocaleString(void 0, { minimumFractionDigits:
|
|
5922
|
+
return isNaN(n) ? balance : n.toLocaleString(void 0, { minimumFractionDigits: digits, maximumFractionDigits: digits });
|
|
5683
5923
|
}
|
|
5684
|
-
function
|
|
5685
|
-
if (
|
|
5686
|
-
return
|
|
5687
|
-
|
|
5688
|
-
var CHAIN_TAG = {
|
|
5689
|
-
STELLAR: { label: "Stellar", color: "#7d00ff" },
|
|
5690
|
-
POLYGON: { label: "Polygon", color: "#8247e5" },
|
|
5691
|
-
SOLANA: { label: "Solana", color: "#14f195" }
|
|
5692
|
-
};
|
|
5693
|
-
function ChainTag({ chain }) {
|
|
5694
|
-
const tag = CHAIN_TAG[chain] ?? { label: chain, color: "#6b7280" };
|
|
5695
|
-
return /* @__PURE__ */ jsx("span", { className: "pollar-bal-chain-tag", style: { "--pollar-chain-color": tag.color }, children: tag.label });
|
|
5924
|
+
function faucetFor(record) {
|
|
5925
|
+
if (record.type === "native") return { url: "https://faucet.solana.com/", label: "Get test SOL" };
|
|
5926
|
+
if (record.code === "USDC") return { url: "https://faucet.circle.com/", label: "Get test USDC" };
|
|
5927
|
+
return null;
|
|
5696
5928
|
}
|
|
5697
|
-
function BalanceItem({ record,
|
|
5929
|
+
function BalanceItem({ record, faucet }) {
|
|
5698
5930
|
const balanceDiffers = record.balance !== record.available;
|
|
5699
5931
|
return /* @__PURE__ */ jsxs("div", { className: "pollar-bal-item", children: [
|
|
5700
5932
|
/* @__PURE__ */ jsxs("div", { className: "pollar-bal-asset-info", children: [
|
|
5701
|
-
/* @__PURE__ */
|
|
5702
|
-
|
|
5703
|
-
|
|
5704
|
-
] }),
|
|
5705
|
-
record.issuer && /* @__PURE__ */ jsxs("span", { className: "pollar-bal-issuer", children: [
|
|
5706
|
-
/* @__PURE__ */ jsx("span", { className: "pollar-bal-issuer-addr", children: cropAddress2(record.issuer) }),
|
|
5933
|
+
/* @__PURE__ */ jsx("span", { className: "pollar-bal-asset-code-row", children: /* @__PURE__ */ jsx("span", { className: "pollar-bal-asset", children: record.code }) }),
|
|
5934
|
+
record.issuer && /* @__PURE__ */ jsxs("span", { className: "pollar-issuer", children: [
|
|
5935
|
+
/* @__PURE__ */ jsx("span", { className: "pollar-issuer-addr", children: cropAddress(record.issuer) }),
|
|
5707
5936
|
/* @__PURE__ */ jsx(CopyButton, { value: record.issuer, label: "Copy issuer address", className: "pollar-copy-btn-sm" })
|
|
5937
|
+
] }),
|
|
5938
|
+
faucet && /* @__PURE__ */ jsxs("span", { className: "pollar-bal-faucet-hint", children: [
|
|
5939
|
+
"Need more?",
|
|
5940
|
+
" ",
|
|
5941
|
+
/* @__PURE__ */ jsx("a", { href: faucet.url, target: "_blank", rel: "noopener noreferrer", children: faucet.label }),
|
|
5942
|
+
/* @__PURE__ */ jsx("span", { className: "pollar-bal-faucet-net", children: " (devnet)" })
|
|
5708
5943
|
] })
|
|
5709
5944
|
] }),
|
|
5710
5945
|
/* @__PURE__ */ jsxs("div", { className: "pollar-bal-amounts", children: [
|
|
5711
|
-
/* @__PURE__ */ jsx("span", { className: "pollar-bal-amount", children: formatBalance2(record.balance) }),
|
|
5946
|
+
/* @__PURE__ */ jsx("span", { className: "pollar-bal-amount", children: formatBalance2(record.balance, record.decimals) }),
|
|
5712
5947
|
balanceDiffers && /* @__PURE__ */ jsxs("span", { className: "pollar-bal-available", children: [
|
|
5713
|
-
formatBalance2(record.available),
|
|
5948
|
+
formatBalance2(record.available, record.decimals),
|
|
5714
5949
|
" available"
|
|
5715
5950
|
] })
|
|
5716
5951
|
] })
|
|
@@ -5721,6 +5956,10 @@ function WalletBalanceModalTemplate({
|
|
|
5721
5956
|
accentColor,
|
|
5722
5957
|
walletBalance,
|
|
5723
5958
|
walletAddress,
|
|
5959
|
+
chains,
|
|
5960
|
+
selectedChain,
|
|
5961
|
+
network,
|
|
5962
|
+
onSelectChain,
|
|
5724
5963
|
onRefresh,
|
|
5725
5964
|
onClose
|
|
5726
5965
|
}) {
|
|
@@ -5743,8 +5982,11 @@ function WalletBalanceModalTemplate({
|
|
|
5743
5982
|
"--pollar-card-border-radius": "10px"
|
|
5744
5983
|
};
|
|
5745
5984
|
const isLoading = walletBalance.step === "loading";
|
|
5746
|
-
const data = walletBalance.step === "loaded" ? walletBalance.data : null;
|
|
5985
|
+
const data = useStickyData(walletBalance.step === "loaded" ? walletBalance.data : null);
|
|
5986
|
+
const balances = (data?.balances ?? []).filter((b) => resolveChain(b.chain) === selectedChain);
|
|
5987
|
+
const showFaucets = selectedChain === "SOLANA" && network === "testnet";
|
|
5747
5988
|
return /* @__PURE__ */ jsxs("div", { className: "pollar-modal-card pollar-bal-modal", "data-theme": theme, style: cssVars, onClick: (e) => e.stopPropagation(), children: [
|
|
5989
|
+
isLoading && data && /* @__PURE__ */ jsx(BusyOverlay, { label: "Refreshing balances\u2026" }),
|
|
5748
5990
|
/* @__PURE__ */ jsxs("div", { className: "pollar-modal-header", children: [
|
|
5749
5991
|
/* @__PURE__ */ jsx("h2", { className: "pollar-modal-title", children: "Wallet Balance" }),
|
|
5750
5992
|
/* @__PURE__ */ jsxs("div", { className: "pollar-modal-header-actions", children: [
|
|
@@ -5783,11 +6025,12 @@ function WalletBalanceModalTemplate({
|
|
|
5783
6025
|
/* @__PURE__ */ jsx("button", { className: "pollar-modal-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M2 2l12 12M14 2L2 14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) })
|
|
5784
6026
|
] })
|
|
5785
6027
|
] }),
|
|
5786
|
-
|
|
5787
|
-
|
|
6028
|
+
/* @__PURE__ */ jsx(ChainSelect, { value: selectedChain, options: chains, onChange: onSelectChain, disabled: isLoading }),
|
|
6029
|
+
walletAddress && /* @__PURE__ */ jsxs("div", { className: "pollar-address-row", children: [
|
|
6030
|
+
/* @__PURE__ */ jsx("span", { className: "pollar-address", children: cropAddress(walletAddress) }),
|
|
5788
6031
|
/* @__PURE__ */ jsx(CopyButton, { value: walletAddress, label: "Copy wallet address" })
|
|
5789
6032
|
] }),
|
|
5790
|
-
isLoading && /* @__PURE__ */ jsxs("div", { className: "pollar-loading-block", children: [
|
|
6033
|
+
isLoading && !data && /* @__PURE__ */ jsxs("div", { className: "pollar-loading-block", children: [
|
|
5791
6034
|
/* @__PURE__ */ jsx("div", { className: "pollar-spinner" }),
|
|
5792
6035
|
/* @__PURE__ */ jsx("span", { children: "Loading\u2026" })
|
|
5793
6036
|
] }),
|
|
@@ -5797,15 +6040,27 @@ function WalletBalanceModalTemplate({
|
|
|
5797
6040
|
data.network,
|
|
5798
6041
|
"."
|
|
5799
6042
|
] }),
|
|
5800
|
-
data?.exists &&
|
|
5801
|
-
data?.exists &&
|
|
6043
|
+
data?.exists && balances.length === 0 && /* @__PURE__ */ jsx("div", { className: "pollar-modal-empty", children: "No balances found on this network." }),
|
|
6044
|
+
data?.exists && balances.length > 0 && /* @__PURE__ */ jsx("div", { className: "pollar-bal-list", children: balances.map((b) => /* @__PURE__ */ jsx(
|
|
6045
|
+
BalanceItem,
|
|
6046
|
+
{
|
|
6047
|
+
record: b,
|
|
6048
|
+
faucet: showFaucets ? faucetFor(b) : null
|
|
6049
|
+
},
|
|
6050
|
+
(b.chain ?? "") + b.code + (b.issuer ?? "")
|
|
6051
|
+
)) }),
|
|
5802
6052
|
/* @__PURE__ */ jsx(PollarModalFooter, {})
|
|
5803
6053
|
] });
|
|
5804
6054
|
}
|
|
5805
6055
|
function WalletBalanceModal({ onClose }) {
|
|
5806
|
-
const { walletBalance, refreshWalletBalance,
|
|
5807
|
-
const walletAddress = wallet?.address ?? "";
|
|
6056
|
+
const { walletBalance, refreshWalletBalance, wallets, network, styles } = usePollar();
|
|
5808
6057
|
const { theme = "light", accentColor = "#005DB4" } = styles;
|
|
6058
|
+
const { chains } = useChains();
|
|
6059
|
+
const [selectedChain, setSelectedChain] = useState(null);
|
|
6060
|
+
useEffect(() => {
|
|
6061
|
+
if (selectedChain === null && chains.length > 0) setSelectedChain(chains[0]);
|
|
6062
|
+
}, [chains, selectedChain]);
|
|
6063
|
+
const walletAddress = addressForChain(wallets, selectedChain);
|
|
5809
6064
|
useEffect(() => {
|
|
5810
6065
|
void refreshWalletBalance();
|
|
5811
6066
|
}, [refreshWalletBalance]);
|
|
@@ -5816,6 +6071,10 @@ function WalletBalanceModal({ onClose }) {
|
|
|
5816
6071
|
accentColor,
|
|
5817
6072
|
walletBalance,
|
|
5818
6073
|
walletAddress,
|
|
6074
|
+
chains,
|
|
6075
|
+
selectedChain,
|
|
6076
|
+
network,
|
|
6077
|
+
onSelectChain: setSelectedChain,
|
|
5819
6078
|
onRefresh: () => refreshWalletBalance(),
|
|
5820
6079
|
onClose
|
|
5821
6080
|
}
|
|
@@ -5920,6 +6179,9 @@ function PollarProvider({
|
|
|
5920
6179
|
);
|
|
5921
6180
|
const [configRetry, setConfigRetry] = useState(0);
|
|
5922
6181
|
const retryConfig = useCallback(() => setConfigRetry((n) => n + 1), []);
|
|
6182
|
+
const appConfigKey = appConfigProp === void 0 ? "" : JSON.stringify(appConfigProp);
|
|
6183
|
+
const appConfigPropRef = useRef(appConfigProp);
|
|
6184
|
+
appConfigPropRef.current = appConfigProp;
|
|
5923
6185
|
useEffect(() => {
|
|
5924
6186
|
return pollarClient.onTransactionStateChange(setTransaction);
|
|
5925
6187
|
}, [pollarClient]);
|
|
@@ -5983,7 +6245,9 @@ function PollarProvider({
|
|
|
5983
6245
|
setModalErrorLogger(pollarClient.getLogger());
|
|
5984
6246
|
}, [pollarClient]);
|
|
5985
6247
|
useEffect(() => {
|
|
5986
|
-
|
|
6248
|
+
const localConfig = appConfigPropRef.current;
|
|
6249
|
+
if (localConfig !== void 0) {
|
|
6250
|
+
setResolvedConfig(localConfig ?? DEFAULT_APP_CONFIG);
|
|
5987
6251
|
setConfigStatus("ready");
|
|
5988
6252
|
return;
|
|
5989
6253
|
}
|
|
@@ -6005,7 +6269,7 @@ function PollarProvider({
|
|
|
6005
6269
|
return () => {
|
|
6006
6270
|
cancelled = true;
|
|
6007
6271
|
};
|
|
6008
|
-
}, [pollarClient,
|
|
6272
|
+
}, [pollarClient, appConfigKey, configRetry]);
|
|
6009
6273
|
const [loginModalOpen, setLoginModalOpen] = useState(false);
|
|
6010
6274
|
const [transactionModalOpen, setTransactionModalOpen] = useState(false);
|
|
6011
6275
|
const [kycModalOpen, setKycModalOpen] = useState(false);
|
|
@@ -6032,6 +6296,7 @@ function PollarProvider({
|
|
|
6032
6296
|
return {
|
|
6033
6297
|
// session
|
|
6034
6298
|
wallet: pollarClient.getWallet(),
|
|
6299
|
+
wallets: pollarClient.getWallets(),
|
|
6035
6300
|
isAuthenticated: !!walletAddress,
|
|
6036
6301
|
verified,
|
|
6037
6302
|
// client
|
|
@@ -6048,6 +6313,7 @@ function PollarProvider({
|
|
|
6048
6313
|
submitTx: (signedXdr) => pollarClient.submitTx(signedXdr),
|
|
6049
6314
|
buildAndSignAndSubmitTx: (operation, params, options) => pollarClient.buildAndSignAndSubmitTx(operation, params, options),
|
|
6050
6315
|
runTx: (operation, params, options) => pollarClient.runTx(operation, params, options),
|
|
6316
|
+
sendPayment: (params) => pollarClient.sendPayment(params),
|
|
6051
6317
|
openTxModal: () => setTransactionModalOpen(true),
|
|
6052
6318
|
// tx history
|
|
6053
6319
|
txHistory,
|
|
@@ -6532,7 +6798,8 @@ function WalletButton() {
|
|
|
6532
6798
|
openDistributionRulesModal,
|
|
6533
6799
|
tx: transaction
|
|
6534
6800
|
} = usePollar();
|
|
6535
|
-
const
|
|
6801
|
+
const { primaryAddress } = useChains();
|
|
6802
|
+
const walletAddress = primaryAddress || (wallet?.address ?? "");
|
|
6536
6803
|
const walletType = wallet?.custody === "external" ? wallet.provider : null;
|
|
6537
6804
|
const [open, setOpen] = useState(false);
|
|
6538
6805
|
const [copied, setCopied] = useState(false);
|
|
@@ -6654,6 +6921,6 @@ function WalletButton() {
|
|
|
6654
6921
|
);
|
|
6655
6922
|
}
|
|
6656
6923
|
|
|
6657
|
-
export { DistributionRulesModal, DistributionRulesModalTemplate, EarnModal, EnabledAssetsModal, EnabledAssetsModalTemplate, KycModal, KycModalTemplate, KycStatus, LoginModalTemplate, PollarProvider, RampWidget, RampWidgetTemplate, ReceiveModal, ReceiveModalTemplate, RouteDisplay, SendModal, SendModalTemplate, SessionsModal, SessionsModalTemplate, SwapModal, SwapModalTemplate, TransactionModalTemplate, TxHistoryModalTemplate, TxStatusView, WalletBalanceModal, WalletBalanceModalTemplate, WalletButton, WalletButtonTemplate, createPollarAdapterHook, usePollar };
|
|
6924
|
+
export { ChainSelect, DistributionRulesModal, DistributionRulesModalTemplate, EarnModal, EnabledAssetsModal, EnabledAssetsModalTemplate, KycModal, KycModalTemplate, KycStatus, LoginModalTemplate, PollarProvider, RampWidget, RampWidgetTemplate, ReceiveModal, ReceiveModalTemplate, RouteDisplay, SendModal, SendModalTemplate, SessionsModal, SessionsModalTemplate, SwapModal, SwapModalTemplate, TransactionModalTemplate, TxHistoryModalTemplate, TxStatusView, WalletBalanceModal, WalletBalanceModalTemplate, WalletButton, WalletButtonTemplate, addressForChain, chainsOf, createPollarAdapterHook, resolveChain, useChains, usePollar };
|
|
6658
6925
|
//# sourceMappingURL=index.mjs.map
|
|
6659
6926
|
//# sourceMappingURL=index.mjs.map
|