@pollar/react 0.10.0 → 0.10.1-rc.0
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/dist/index.css +10 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +19 -2
- package/dist/index.d.ts +19 -2
- package/dist/index.js +110 -17
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +110 -17
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1035,7 +1035,7 @@ var PollarModalFooter = () => {
|
|
|
1035
1035
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-footer-name", children: "Pollar" }),
|
|
1036
1036
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-footer-version", children: [
|
|
1037
1037
|
"v",
|
|
1038
|
-
"0.10.0"
|
|
1038
|
+
"0.10.1-rc.0"
|
|
1039
1039
|
] })
|
|
1040
1040
|
] })
|
|
1041
1041
|
] });
|
|
@@ -3507,7 +3507,6 @@ var PROVIDER_LABELS = {
|
|
|
3507
3507
|
soroswap: "Soroswap",
|
|
3508
3508
|
sdex: "Stellar DEX"
|
|
3509
3509
|
};
|
|
3510
|
-
var IMPLEMENTED_PROVIDERS = ["auto", "aquarius"];
|
|
3511
3510
|
function formatAmount2(value) {
|
|
3512
3511
|
const n = parseFloat(value);
|
|
3513
3512
|
return isNaN(n) ? value : n.toLocaleString(void 0, { maximumFractionDigits: 7 });
|
|
@@ -3530,6 +3529,9 @@ function SwapModalTemplate({
|
|
|
3530
3529
|
formError,
|
|
3531
3530
|
isLoadingData,
|
|
3532
3531
|
smartUnsupported,
|
|
3532
|
+
configLoading,
|
|
3533
|
+
swapUnavailable,
|
|
3534
|
+
buyNeedsTrustline,
|
|
3533
3535
|
transaction,
|
|
3534
3536
|
showXdr,
|
|
3535
3537
|
copied,
|
|
@@ -3539,6 +3541,7 @@ function SwapModalTemplate({
|
|
|
3539
3541
|
isInProgress,
|
|
3540
3542
|
onClose,
|
|
3541
3543
|
onBack,
|
|
3544
|
+
onRefresh,
|
|
3542
3545
|
onSelectSell,
|
|
3543
3546
|
onSelectBuy,
|
|
3544
3547
|
onAmountChange,
|
|
@@ -3577,9 +3580,34 @@ function SwapModalTemplate({
|
|
|
3577
3580
|
showBack && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-modal-close", onClick: onBack, "aria-label": "Back", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 3L5 8l5 5", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }),
|
|
3578
3581
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: title })
|
|
3579
3582
|
] }),
|
|
3580
|
-
!isInProgress && /* @__PURE__ */ jsxRuntime.
|
|
3583
|
+
!isInProgress && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
|
|
3584
|
+
step === "form" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3585
|
+
"button",
|
|
3586
|
+
{
|
|
3587
|
+
type: "button",
|
|
3588
|
+
className: "pollar-modal-close",
|
|
3589
|
+
onClick: onRefresh,
|
|
3590
|
+
disabled: configLoading || isLoadingData,
|
|
3591
|
+
"aria-label": "Refresh",
|
|
3592
|
+
title: "Refresh balances and options",
|
|
3593
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3594
|
+
"path",
|
|
3595
|
+
{
|
|
3596
|
+
d: "M13.5 8a5.5 5.5 0 1 1-1.6-3.9M13.5 2.5v3h-3",
|
|
3597
|
+
stroke: "currentColor",
|
|
3598
|
+
strokeWidth: "1.6",
|
|
3599
|
+
strokeLinecap: "round",
|
|
3600
|
+
strokeLinejoin: "round"
|
|
3601
|
+
}
|
|
3602
|
+
) })
|
|
3603
|
+
}
|
|
3604
|
+
),
|
|
3605
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-modal-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2 2l12 12M14 2L2 14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) })
|
|
3606
|
+
] })
|
|
3581
3607
|
] }),
|
|
3582
|
-
step === "form" && /* @__PURE__ */ jsxRuntime.
|
|
3608
|
+
step === "form" && configLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-send-hint", children: "Loading swap options\u2026" }),
|
|
3609
|
+
step === "form" && !configLoading && swapUnavailable && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: "Swap is not available for this app." }),
|
|
3610
|
+
step === "form" && !configLoading && !swapUnavailable && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3583
3611
|
smartUnsupported && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: "Swaps are not yet available for smart (passkey) wallets." }),
|
|
3584
3612
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-send-field", children: [
|
|
3585
3613
|
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "pollar-send-label", children: "You pay" }),
|
|
@@ -3653,13 +3681,7 @@ function SwapModalTemplate({
|
|
|
3653
3681
|
className: "pollar-input pollar-send-select",
|
|
3654
3682
|
value: provider,
|
|
3655
3683
|
onChange: (e) => onProviderChange(e.target.value),
|
|
3656
|
-
children: providers.map((p) => {
|
|
3657
|
-
const implemented = IMPLEMENTED_PROVIDERS.includes(p);
|
|
3658
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("option", { value: p, disabled: !implemented, children: [
|
|
3659
|
-
PROVIDER_LABELS[p],
|
|
3660
|
-
implemented ? "" : " (coming soon)"
|
|
3661
|
-
] }, p);
|
|
3662
|
-
})
|
|
3684
|
+
children: providers.map((p) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: p, children: PROVIDER_LABELS[p] }, p))
|
|
3663
3685
|
}
|
|
3664
3686
|
)
|
|
3665
3687
|
] }),
|
|
@@ -3696,8 +3718,13 @@ function SwapModalTemplate({
|
|
|
3696
3718
|
] })
|
|
3697
3719
|
] }),
|
|
3698
3720
|
!quoteLoading && !quoteError && !quote && selectedSell && selectedBuy && !!amount && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-send-hint", children: "No route found for this pair." }),
|
|
3721
|
+
buyNeedsTrustline && selectedBuy && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-swap-trustline-notice", children: [
|
|
3722
|
+
"To receive ",
|
|
3723
|
+
selectedBuy.code,
|
|
3724
|
+
" your wallet needs a trustline. Swapping will create it first (~0.5 XLM reserve, refundable if you later remove it)."
|
|
3725
|
+
] }),
|
|
3699
3726
|
formError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: formError }),
|
|
3700
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-actions", children: /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-btn-primary", onClick: onSwap, disabled: !canSwap, children: "Swap" }) })
|
|
3727
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-actions", children: /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-btn-primary", onClick: onSwap, disabled: !canSwap, children: buyNeedsTrustline ? "Create trustline & swap" : "Swap" }) })
|
|
3701
3728
|
] }),
|
|
3702
3729
|
step === "tx" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3703
3730
|
TxStatusView,
|
|
@@ -3719,14 +3746,18 @@ function SwapModalTemplate({
|
|
|
3719
3746
|
] });
|
|
3720
3747
|
}
|
|
3721
3748
|
var QUOTE_DEBOUNCE_MS = 400;
|
|
3722
|
-
var ALL_PROVIDERS = ["auto", "aquarius", "soroswap", "sdex"];
|
|
3723
3749
|
function toRef(a) {
|
|
3724
3750
|
if (a.type === "native") return { type: "native" };
|
|
3725
3751
|
if (a.type === "credit_alphanum4") return { type: "credit_alphanum4", code: a.code, issuer: a.issuer };
|
|
3726
3752
|
return { type: "credit_alphanum12", code: a.code, issuer: a.issuer };
|
|
3727
3753
|
}
|
|
3754
|
+
function catalogRef(code, issuer) {
|
|
3755
|
+
return code.length <= 4 ? { type: "credit_alphanum4", code, issuer } : { type: "credit_alphanum12", code, issuer };
|
|
3756
|
+
}
|
|
3728
3757
|
function SwapModal({ onClose }) {
|
|
3729
3758
|
const {
|
|
3759
|
+
getSwapConfig,
|
|
3760
|
+
getSwapTokens,
|
|
3730
3761
|
getSwapQuote,
|
|
3731
3762
|
swap,
|
|
3732
3763
|
walletBalance,
|
|
@@ -3746,6 +3777,8 @@ function SwapModal({ onClose }) {
|
|
|
3746
3777
|
const [selectedBuy, setSelectedBuy] = react.useState(null);
|
|
3747
3778
|
const [amount, setAmount] = react.useState("");
|
|
3748
3779
|
const [provider, setProvider] = react.useState("auto");
|
|
3780
|
+
const [venues, setVenues] = react.useState(null);
|
|
3781
|
+
const [catalogTokens, setCatalogTokens] = react.useState([]);
|
|
3749
3782
|
const [quotes, setQuotes] = react.useState([]);
|
|
3750
3783
|
const [quoteLoading, setQuoteLoading] = react.useState(false);
|
|
3751
3784
|
const [quoteError, setQuoteError] = react.useState("");
|
|
@@ -3758,6 +3791,26 @@ function SwapModal({ onClose }) {
|
|
|
3758
3791
|
void refreshWalletBalance();
|
|
3759
3792
|
void refreshAssets();
|
|
3760
3793
|
}, [refreshWalletBalance, refreshAssets]);
|
|
3794
|
+
const loadConfig = react.useCallback(() => {
|
|
3795
|
+
setVenues(null);
|
|
3796
|
+
return getSwapConfig().then(setVenues).catch(() => setVenues([]));
|
|
3797
|
+
}, [getSwapConfig]);
|
|
3798
|
+
react.useEffect(() => {
|
|
3799
|
+
void loadConfig();
|
|
3800
|
+
}, [loadConfig]);
|
|
3801
|
+
const loadCatalog = react.useCallback(
|
|
3802
|
+
() => getSwapTokens().then(setCatalogTokens).catch(() => setCatalogTokens([])),
|
|
3803
|
+
[getSwapTokens]
|
|
3804
|
+
);
|
|
3805
|
+
react.useEffect(() => {
|
|
3806
|
+
void loadCatalog();
|
|
3807
|
+
}, [loadCatalog]);
|
|
3808
|
+
function handleRefresh() {
|
|
3809
|
+
void refreshWalletBalance();
|
|
3810
|
+
void refreshAssets();
|
|
3811
|
+
void loadConfig();
|
|
3812
|
+
void loadCatalog();
|
|
3813
|
+
}
|
|
3761
3814
|
react.useEffect(
|
|
3762
3815
|
() => () => {
|
|
3763
3816
|
if (copyTimerRef.current !== null) clearTimeout(copyTimerRef.current);
|
|
@@ -3769,11 +3822,33 @@ function SwapModal({ onClose }) {
|
|
|
3769
3822
|
const isLoadingData = walletBalance.step === "loading" || enabledAssets.step === "loading";
|
|
3770
3823
|
const sellOptions = balances.filter((b) => parseFloat(b.available) > 0).map((b) => ({ ref: toRef(b), code: b.code, issuer: b.issuer, available: b.available, enabledInApp: b.enabledInApp }));
|
|
3771
3824
|
const buyKeyOfSell = selectedSell ? `${selectedSell.code}:${selectedSell.issuer ?? "native"}` : "";
|
|
3772
|
-
const
|
|
3773
|
-
const
|
|
3825
|
+
const optKey = (o) => `${o.code}:${o.issuer ?? "native"}`;
|
|
3826
|
+
const enabledBuy = assetRecords.map((a) => ({
|
|
3827
|
+
ref: toRef(a),
|
|
3828
|
+
code: a.code,
|
|
3829
|
+
issuer: a.issuer,
|
|
3830
|
+
enabledInApp: a.enabledInApp
|
|
3831
|
+
}));
|
|
3832
|
+
const enabledKeys = new Set(enabledBuy.map(optKey));
|
|
3833
|
+
const catalogBuy = catalogTokens.map((tk) => ({
|
|
3834
|
+
ref: catalogRef(tk.code, tk.issuer),
|
|
3835
|
+
code: tk.code,
|
|
3836
|
+
issuer: tk.issuer,
|
|
3837
|
+
enabledInApp: false
|
|
3838
|
+
})).filter((o) => !enabledKeys.has(optKey(o)));
|
|
3839
|
+
const buyOptions = [...enabledBuy, ...catalogBuy].filter((o) => optKey(o) !== buyKeyOfSell);
|
|
3840
|
+
const buyNeedsTrustline = (() => {
|
|
3841
|
+
if (!selectedBuy || smartUnsupported) return false;
|
|
3842
|
+
if (selectedBuy.ref.type === "native") return false;
|
|
3843
|
+
const rec = assetRecords.find((a) => a.code === selectedBuy.code && a.issuer === selectedBuy.issuer);
|
|
3844
|
+
return !rec?.trustlineEstablished;
|
|
3845
|
+
})();
|
|
3846
|
+
const configLoading = venues === null;
|
|
3847
|
+
const swapUnavailable = venues !== null && venues.length === 0;
|
|
3848
|
+
const providers = venues && venues.length > 0 ? ["auto", ...venues] : [];
|
|
3774
3849
|
const quote = quotes[0] ?? null;
|
|
3775
3850
|
react.useEffect(() => {
|
|
3776
|
-
if (step !== "form" || !selectedSell || !selectedBuy || !amount || parseFloat(amount) <= 0) {
|
|
3851
|
+
if (step !== "form" || swapUnavailable || configLoading || !selectedSell || !selectedBuy || !amount || parseFloat(amount) <= 0) {
|
|
3777
3852
|
setQuotes([]);
|
|
3778
3853
|
setQuoteError("");
|
|
3779
3854
|
setQuoteLoading(false);
|
|
@@ -3805,7 +3880,7 @@ function SwapModal({ onClose }) {
|
|
|
3805
3880
|
cancelled = true;
|
|
3806
3881
|
clearTimeout(t);
|
|
3807
3882
|
};
|
|
3808
|
-
}, [step, selectedSell, selectedBuy, amount, provider, getSwapQuote]);
|
|
3883
|
+
}, [step, swapUnavailable, configLoading, selectedSell, selectedBuy, amount, provider, getSwapQuote]);
|
|
3809
3884
|
const hash = transaction.step === "success" ? transaction.hash : null;
|
|
3810
3885
|
const buildData = "buildData" in transaction ? transaction.buildData : null;
|
|
3811
3886
|
const explorerNetwork = buildData?.summary.network?.toLowerCase().includes("testnet") ? "testnet" : buildData ? "public" : network === "testnet" ? "testnet" : "public";
|
|
@@ -3886,6 +3961,9 @@ function SwapModal({ onClose }) {
|
|
|
3886
3961
|
formError,
|
|
3887
3962
|
isLoadingData,
|
|
3888
3963
|
smartUnsupported,
|
|
3964
|
+
configLoading,
|
|
3965
|
+
swapUnavailable,
|
|
3966
|
+
buyNeedsTrustline,
|
|
3889
3967
|
transaction,
|
|
3890
3968
|
showXdr,
|
|
3891
3969
|
copied,
|
|
@@ -3895,6 +3973,7 @@ function SwapModal({ onClose }) {
|
|
|
3895
3973
|
isInProgress,
|
|
3896
3974
|
onClose,
|
|
3897
3975
|
onBack: handleBack,
|
|
3976
|
+
onRefresh: handleRefresh,
|
|
3898
3977
|
onSelectSell: setSelectedSell,
|
|
3899
3978
|
onSelectBuy: setSelectedBuy,
|
|
3900
3979
|
onAmountChange: setAmount,
|
|
@@ -4608,6 +4687,18 @@ function PollarProvider({
|
|
|
4608
4687
|
const [pollarClient] = react.useState(
|
|
4609
4688
|
() => client instanceof core.PollarClient ? client : new core.PollarClient({ passkey: browserPasskeyCeremony, passkeySign: browserPasskeySigner, ...client })
|
|
4610
4689
|
);
|
|
4690
|
+
const ownsClientRef = react.useRef(!(client instanceof core.PollarClient));
|
|
4691
|
+
const destroyTimerRef = react.useRef(null);
|
|
4692
|
+
react.useEffect(() => {
|
|
4693
|
+
if (!ownsClientRef.current) return;
|
|
4694
|
+
if (destroyTimerRef.current) {
|
|
4695
|
+
clearTimeout(destroyTimerRef.current);
|
|
4696
|
+
destroyTimerRef.current = null;
|
|
4697
|
+
}
|
|
4698
|
+
return () => {
|
|
4699
|
+
destroyTimerRef.current = setTimeout(() => pollarClient.destroy(), 0);
|
|
4700
|
+
};
|
|
4701
|
+
}, [pollarClient]);
|
|
4611
4702
|
const [networkState, setNetworkState] = react.useState(() => pollarClient.getNetworkState());
|
|
4612
4703
|
const [sessionState, setSessionState] = react.useState(null);
|
|
4613
4704
|
const [verified, setVerified] = react.useState(false);
|
|
@@ -4747,6 +4838,8 @@ function PollarProvider({
|
|
|
4747
4838
|
openSendModal: () => setSendModalOpen(true),
|
|
4748
4839
|
openReceiveModal: () => setReceiveModalOpen(true),
|
|
4749
4840
|
// swap
|
|
4841
|
+
getSwapConfig: () => pollarClient.getSwapConfig(),
|
|
4842
|
+
getSwapTokens: () => pollarClient.getSwapTokens(),
|
|
4750
4843
|
getSwapQuote: (params) => pollarClient.getSwapQuote(params),
|
|
4751
4844
|
swap: (quote, opts) => pollarClient.swap(quote, opts),
|
|
4752
4845
|
openSwapModal: () => setSwapModalOpen(true),
|