@pollar/react 0.10.1-rc.2 → 0.10.1-rc.4
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 +54 -4
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +11 -5
- package/dist/index.d.ts +11 -5
- package/dist/index.js +99 -47
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +99 -47
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -309,6 +309,13 @@ interface KycModalTemplateProps {
|
|
|
309
309
|
declare function KycModalTemplate({ theme, accentColor, step, providers, selectedProvider, session, kycStatus, isLoading, onSelectProvider, onDoneVerifying, onClose, }: KycModalTemplateProps): react_jsx_runtime.JSX.Element;
|
|
310
310
|
|
|
311
311
|
type RampStep = 'input' | 'loading_quote' | 'select_route' | 'contact' | 'status' | 'error';
|
|
312
|
+
/** A field a provider declares (via the quote) that the client must collect. */
|
|
313
|
+
interface RampFieldSpec {
|
|
314
|
+
key: string;
|
|
315
|
+
label: string;
|
|
316
|
+
type: 'text' | 'email' | 'tel';
|
|
317
|
+
bankType?: 'CLABE' | 'PIX' | 'PSE' | 'ACH';
|
|
318
|
+
}
|
|
312
319
|
interface RampWidgetTemplateProps {
|
|
313
320
|
theme: string;
|
|
314
321
|
accentColor: string;
|
|
@@ -317,8 +324,8 @@ interface RampWidgetTemplateProps {
|
|
|
317
324
|
amount: string;
|
|
318
325
|
currency: string;
|
|
319
326
|
country: string;
|
|
320
|
-
|
|
321
|
-
|
|
327
|
+
requiredFields: RampFieldSpec[];
|
|
328
|
+
fieldValues: Record<string, string>;
|
|
322
329
|
countries: RampCountry[];
|
|
323
330
|
countriesLoading: boolean;
|
|
324
331
|
refreshing: boolean;
|
|
@@ -334,8 +341,7 @@ interface RampWidgetTemplateProps {
|
|
|
334
341
|
errorMsg: string | null;
|
|
335
342
|
onDirectionChange: (d: RampDirection) => void;
|
|
336
343
|
onAmountChange: (v: string) => void;
|
|
337
|
-
|
|
338
|
-
onFullNameChange: (v: string) => void;
|
|
344
|
+
onFieldChange: (key: string, value: string) => void;
|
|
339
345
|
onCountryChange: (v: string) => void;
|
|
340
346
|
onFindRoute: () => void;
|
|
341
347
|
onSelectQuote: (q: RampQuote) => void;
|
|
@@ -346,7 +352,7 @@ interface RampWidgetTemplateProps {
|
|
|
346
352
|
onRefresh: () => void;
|
|
347
353
|
onClose: () => void;
|
|
348
354
|
}
|
|
349
|
-
declare function RampWidgetTemplate({ theme, accentColor, step, direction, amount, currency, country,
|
|
355
|
+
declare function RampWidgetTemplate({ theme, accentColor, step, direction, amount, currency, country, requiredFields, fieldValues, countries, countriesLoading, refreshing, quotes, isLoading, provider, txStatus, kycUrl, stellarTxHash, depositInstructions, canComplete, completing, errorMsg, onDirectionChange, onAmountChange, onFieldChange, onCountryChange, onFindRoute, onSelectQuote, onContactContinue, onOpenKyc, onCompleteWithdraw, onRetry, onRefresh, onClose, }: RampWidgetTemplateProps): react_jsx_runtime.JSX.Element;
|
|
350
356
|
|
|
351
357
|
interface TransactionModalTemplateProps {
|
|
352
358
|
theme: string;
|
package/dist/index.js
CHANGED
|
@@ -1035,11 +1035,62 @@ var PollarModalFooter = () => {
|
|
|
1035
1035
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-footer-name", children: "Pollar" }),
|
|
1036
1036
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-footer-version", children: [
|
|
1037
1037
|
"v",
|
|
1038
|
-
"0.10.1-rc.
|
|
1038
|
+
"0.10.1-rc.4"
|
|
1039
1039
|
] })
|
|
1040
1040
|
] })
|
|
1041
1041
|
] });
|
|
1042
1042
|
};
|
|
1043
|
+
function CopyButton({ value, label = "Copy", className }) {
|
|
1044
|
+
const [copied, setCopied] = react.useState(false);
|
|
1045
|
+
const timerRef = react.useRef(null);
|
|
1046
|
+
react.useEffect(() => {
|
|
1047
|
+
return () => {
|
|
1048
|
+
if (timerRef.current !== null) clearTimeout(timerRef.current);
|
|
1049
|
+
};
|
|
1050
|
+
}, []);
|
|
1051
|
+
function handleCopy(e) {
|
|
1052
|
+
e.stopPropagation();
|
|
1053
|
+
if (!value || !navigator.clipboard) return;
|
|
1054
|
+
void navigator.clipboard.writeText(value).then(() => {
|
|
1055
|
+
setCopied(true);
|
|
1056
|
+
if (timerRef.current !== null) clearTimeout(timerRef.current);
|
|
1057
|
+
timerRef.current = setTimeout(() => {
|
|
1058
|
+
setCopied(false);
|
|
1059
|
+
timerRef.current = null;
|
|
1060
|
+
}, 1500);
|
|
1061
|
+
});
|
|
1062
|
+
}
|
|
1063
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1064
|
+
"button",
|
|
1065
|
+
{
|
|
1066
|
+
type: "button",
|
|
1067
|
+
className: `pollar-copy-btn${className ? ` ${className}` : ""}`,
|
|
1068
|
+
onClick: handleCopy,
|
|
1069
|
+
"aria-label": copied ? "Copied" : label,
|
|
1070
|
+
children: copied ? /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "13", height: "13", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1071
|
+
"path",
|
|
1072
|
+
{
|
|
1073
|
+
d: "M3.5 7l2.5 2.5 4.5-5",
|
|
1074
|
+
stroke: "currentColor",
|
|
1075
|
+
strokeWidth: "1.5",
|
|
1076
|
+
strokeLinecap: "round",
|
|
1077
|
+
strokeLinejoin: "round"
|
|
1078
|
+
}
|
|
1079
|
+
) }) : /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
|
|
1080
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1.5", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
1081
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1082
|
+
"path",
|
|
1083
|
+
{
|
|
1084
|
+
d: "M3 9H2a1 1 0 01-1-1V2a1 1 0 011-1h6a1 1 0 011 1v1",
|
|
1085
|
+
stroke: "currentColor",
|
|
1086
|
+
strokeWidth: "1.5",
|
|
1087
|
+
strokeLinecap: "round"
|
|
1088
|
+
}
|
|
1089
|
+
)
|
|
1090
|
+
] })
|
|
1091
|
+
}
|
|
1092
|
+
);
|
|
1093
|
+
}
|
|
1043
1094
|
function ModalStatusBanner({ message, status, onCancel, onRetry }) {
|
|
1044
1095
|
if (!message && status === "NONE") {
|
|
1045
1096
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-status" });
|
|
@@ -2506,8 +2557,8 @@ function RampWidgetTemplate({
|
|
|
2506
2557
|
amount,
|
|
2507
2558
|
currency,
|
|
2508
2559
|
country,
|
|
2509
|
-
|
|
2510
|
-
|
|
2560
|
+
requiredFields,
|
|
2561
|
+
fieldValues,
|
|
2511
2562
|
countries,
|
|
2512
2563
|
countriesLoading,
|
|
2513
2564
|
refreshing,
|
|
@@ -2523,8 +2574,7 @@ function RampWidgetTemplate({
|
|
|
2523
2574
|
errorMsg,
|
|
2524
2575
|
onDirectionChange,
|
|
2525
2576
|
onAmountChange,
|
|
2526
|
-
|
|
2527
|
-
onFullNameChange,
|
|
2577
|
+
onFieldChange,
|
|
2528
2578
|
onCountryChange,
|
|
2529
2579
|
onFindRoute,
|
|
2530
2580
|
onSelectQuote,
|
|
@@ -2675,33 +2725,19 @@ function RampWidgetTemplate({
|
|
|
2675
2725
|
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-secondary", onClick: onClose, children: "Cancel" })
|
|
2676
2726
|
] }),
|
|
2677
2727
|
step === "contact" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2678
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-field", children: [
|
|
2679
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "pollar-ramp-label", children:
|
|
2728
|
+
requiredFields.map((f) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-field", children: [
|
|
2729
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "pollar-ramp-label", children: f.label }),
|
|
2680
2730
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2681
2731
|
"input",
|
|
2682
2732
|
{
|
|
2683
|
-
type:
|
|
2733
|
+
type: f.type,
|
|
2684
2734
|
className: "pollar-ramp-input",
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
onChange: (e) =>
|
|
2688
|
-
}
|
|
2689
|
-
)
|
|
2690
|
-
] }),
|
|
2691
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-field", children: [
|
|
2692
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "pollar-ramp-label", children: "Email" }),
|
|
2693
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2694
|
-
"input",
|
|
2695
|
-
{
|
|
2696
|
-
type: "email",
|
|
2697
|
-
className: "pollar-ramp-input",
|
|
2698
|
-
placeholder: "jane@example.com",
|
|
2699
|
-
value: email,
|
|
2700
|
-
autoComplete: "email",
|
|
2701
|
-
onChange: (e) => onEmailChange(e.target.value)
|
|
2735
|
+
value: fieldValues[f.key] ?? "",
|
|
2736
|
+
autoComplete: f.type === "email" ? "email" : "off",
|
|
2737
|
+
onChange: (e) => onFieldChange(f.key, e.target.value)
|
|
2702
2738
|
}
|
|
2703
2739
|
)
|
|
2704
|
-
] }),
|
|
2740
|
+
] }, f.key)),
|
|
2705
2741
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-actions", children: [
|
|
2706
2742
|
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-secondary", onClick: onRetry, children: "Back" }),
|
|
2707
2743
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2709,7 +2745,7 @@ function RampWidgetTemplate({
|
|
|
2709
2745
|
{
|
|
2710
2746
|
type: "button",
|
|
2711
2747
|
className: "pollar-btn-primary",
|
|
2712
|
-
disabled:
|
|
2748
|
+
disabled: requiredFields.some((f) => !(fieldValues[f.key] ?? "").trim()) || isLoading,
|
|
2713
2749
|
onClick: onContactContinue,
|
|
2714
2750
|
children: isLoading ? "Starting\u2026" : "Continue"
|
|
2715
2751
|
}
|
|
@@ -2755,6 +2791,9 @@ function RampWidgetTemplate({
|
|
|
2755
2791
|
] });
|
|
2756
2792
|
}
|
|
2757
2793
|
var TERMINAL = ["completed", "failed"];
|
|
2794
|
+
function requiredFieldsOf(quote) {
|
|
2795
|
+
return quote.requiredFields ?? [];
|
|
2796
|
+
}
|
|
2758
2797
|
function RampWidget({ onClose }) {
|
|
2759
2798
|
const { getClient, signTx, wallet, styles } = usePollar();
|
|
2760
2799
|
const walletAddress = wallet?.address ?? "";
|
|
@@ -2765,8 +2804,8 @@ function RampWidget({ onClose }) {
|
|
|
2765
2804
|
const [amount, setAmount] = react.useState("");
|
|
2766
2805
|
const [currency, setCurrency] = react.useState("");
|
|
2767
2806
|
const [country, setCountry] = react.useState("");
|
|
2768
|
-
const [
|
|
2769
|
-
const
|
|
2807
|
+
const [fieldValues, setFieldValues] = react.useState({});
|
|
2808
|
+
const setFieldValue = (key, value) => setFieldValues((v) => ({ ...v, [key]: value }));
|
|
2770
2809
|
const [countries, setCountries] = react.useState([]);
|
|
2771
2810
|
const [countriesLoading, setCountriesLoading] = react.useState(true);
|
|
2772
2811
|
const [refreshing, setRefreshing] = react.useState(false);
|
|
@@ -2913,8 +2952,9 @@ function RampWidget({ onClose }) {
|
|
|
2913
2952
|
function handleSelectQuote(quote) {
|
|
2914
2953
|
setSelectedQuote(quote);
|
|
2915
2954
|
setErrorMsg(null);
|
|
2916
|
-
const
|
|
2917
|
-
|
|
2955
|
+
const fields = requiredFieldsOf(quote);
|
|
2956
|
+
const missing = fields.some((f) => !(fieldValues[f.key] ?? "").trim());
|
|
2957
|
+
if (fields.length > 0 && missing) {
|
|
2918
2958
|
setStep("contact");
|
|
2919
2959
|
return;
|
|
2920
2960
|
}
|
|
@@ -2927,15 +2967,14 @@ function RampWidget({ onClose }) {
|
|
|
2927
2967
|
setIsLoading(true);
|
|
2928
2968
|
setErrorMsg(null);
|
|
2929
2969
|
try {
|
|
2930
|
-
const base = {
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
};
|
|
2970
|
+
const base = { quoteId: quote.quoteId, amount: Number(amount), currency, country };
|
|
2971
|
+
if (walletAddress) base.walletAddress = walletAddress;
|
|
2972
|
+
for (const f of requiredFieldsOf(quote)) {
|
|
2973
|
+
const val = (fieldValues[f.key] ?? "").trim();
|
|
2974
|
+
if (!val) continue;
|
|
2975
|
+
if (f.bankType) base.bankDetails = { type: f.bankType, value: val };
|
|
2976
|
+
else base[f.key] = val;
|
|
2977
|
+
}
|
|
2939
2978
|
const result = direction === "onramp" ? await client.createOnRamp(base) : await client.createOffRamp(base);
|
|
2940
2979
|
await applyResult(result);
|
|
2941
2980
|
} catch (e) {
|
|
@@ -2980,8 +3019,8 @@ function RampWidget({ onClose }) {
|
|
|
2980
3019
|
amount,
|
|
2981
3020
|
currency,
|
|
2982
3021
|
country,
|
|
2983
|
-
|
|
2984
|
-
|
|
3022
|
+
requiredFields: selectedQuote ? requiredFieldsOf(selectedQuote) : [],
|
|
3023
|
+
fieldValues,
|
|
2985
3024
|
countries,
|
|
2986
3025
|
countriesLoading,
|
|
2987
3026
|
refreshing,
|
|
@@ -2997,8 +3036,7 @@ function RampWidget({ onClose }) {
|
|
|
2997
3036
|
errorMsg,
|
|
2998
3037
|
onDirectionChange: setDirection,
|
|
2999
3038
|
onAmountChange: setAmount,
|
|
3000
|
-
|
|
3001
|
-
onFullNameChange: setFullName,
|
|
3039
|
+
onFieldChange: setFieldValue,
|
|
3002
3040
|
onCountryChange: handleCountryChange,
|
|
3003
3041
|
onFindRoute: handleFindRoute,
|
|
3004
3042
|
onSelectQuote: handleSelectQuote,
|
|
@@ -4650,6 +4688,7 @@ function TxHistoryModalTemplate({
|
|
|
4650
4688
|
txHistory.step === "loaded" && records.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No transactions yet." }),
|
|
4651
4689
|
records.map((record) => {
|
|
4652
4690
|
const explorerUrl = `https://stellar.expert/explorer/${record.network === "testnet" ? "testnet" : "public"}/tx/${record.hash}`;
|
|
4691
|
+
const destination = typeof record.details?.destination === "string" ? record.details.destination : void 0;
|
|
4653
4692
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-item", children: [
|
|
4654
4693
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-hist-item-summary", children: record.summary }),
|
|
4655
4694
|
/* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: record.status }),
|
|
@@ -4668,6 +4707,10 @@ function TxHistoryModalTemplate({
|
|
|
4668
4707
|
"\xB7 ",
|
|
4669
4708
|
formatDate(record.createdAt)
|
|
4670
4709
|
] }),
|
|
4710
|
+
destination && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4711
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "\xB7" }),
|
|
4712
|
+
/* @__PURE__ */ jsxRuntime.jsx(CopyButton, { value: destination, label: "Copy wallet address", className: "pollar-copy-btn-sm" })
|
|
4713
|
+
] }),
|
|
4671
4714
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "\xB7" }),
|
|
4672
4715
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4673
4716
|
"a",
|
|
@@ -4756,7 +4799,7 @@ function TxHistoryModal({ onClose }) {
|
|
|
4756
4799
|
}
|
|
4757
4800
|
function formatBalance2(balance) {
|
|
4758
4801
|
const n = parseFloat(balance);
|
|
4759
|
-
return isNaN(n) ? balance : n.toLocaleString(void 0, { maximumFractionDigits: 7 });
|
|
4802
|
+
return isNaN(n) ? balance : n.toLocaleString(void 0, { minimumFractionDigits: 7, maximumFractionDigits: 7 });
|
|
4760
4803
|
}
|
|
4761
4804
|
function cropAddress2(address) {
|
|
4762
4805
|
if (address.length <= 16) return address;
|
|
@@ -4765,7 +4808,13 @@ function cropAddress2(address) {
|
|
|
4765
4808
|
function BalanceItem({ record }) {
|
|
4766
4809
|
const balanceDiffers = record.balance !== record.available;
|
|
4767
4810
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-bal-item", children: [
|
|
4768
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4811
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-bal-asset-info", children: [
|
|
4812
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-bal-asset", children: record.code }),
|
|
4813
|
+
record.issuer && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-bal-issuer", children: [
|
|
4814
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-bal-issuer-addr", children: cropAddress2(record.issuer) }),
|
|
4815
|
+
/* @__PURE__ */ jsxRuntime.jsx(CopyButton, { value: record.issuer, label: "Copy issuer address", className: "pollar-copy-btn-sm" })
|
|
4816
|
+
] })
|
|
4817
|
+
] }),
|
|
4769
4818
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-bal-amounts", children: [
|
|
4770
4819
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-bal-amount", children: formatBalance2(record.balance) }),
|
|
4771
4820
|
balanceDiffers && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-bal-available", children: [
|
|
@@ -4828,7 +4877,10 @@ function WalletBalanceModalTemplate({
|
|
|
4828
4877
|
/* @__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" }) }) })
|
|
4829
4878
|
] })
|
|
4830
4879
|
] }),
|
|
4831
|
-
walletAddress && /* @__PURE__ */ jsxRuntime.
|
|
4880
|
+
walletAddress && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-bal-address-row", children: [
|
|
4881
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-bal-address", children: cropAddress2(walletAddress) }),
|
|
4882
|
+
/* @__PURE__ */ jsxRuntime.jsx(CopyButton, { value: walletAddress, label: "Copy wallet address" })
|
|
4883
|
+
] }),
|
|
4832
4884
|
isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "Loading\u2026" }),
|
|
4833
4885
|
walletBalance.step === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: walletBalance.message }),
|
|
4834
4886
|
data && !data.exists && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-empty", children: [
|