@pollar/react 0.4.4 → 0.5.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 +786 -138
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +45 -10
- package/dist/index.d.ts +45 -10
- package/dist/index.js +952 -287
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +950 -289
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -39,56 +39,15 @@ var PollarModalFooter = () => {
|
|
|
39
39
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-footer-name", children: "Pollar" }),
|
|
40
40
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-footer-version", children: [
|
|
41
41
|
"v",
|
|
42
|
-
"0.4.
|
|
42
|
+
"0.4.5"
|
|
43
43
|
] })
|
|
44
44
|
] })
|
|
45
45
|
] });
|
|
46
46
|
};
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
LOGOUT: { text: "Logged out" },
|
|
50
|
-
CREATE_SESSION_START: { text: "Starting session\u2026" },
|
|
51
|
-
CREATE_SESSION_ERROR: { text: "Failed to start session" },
|
|
52
|
-
CREATE_SESSION_SUCCESS: { text: "Session ready" },
|
|
53
|
-
EMAIL_AUTH_START: { text: "Sending code\u2026" },
|
|
54
|
-
EMAIL_AUTH_START_ERROR: { text: "Failed to send code" },
|
|
55
|
-
EMAIL_AUTH_START_SUCCESS: { text: "Code sent \u2014 check your inbox" },
|
|
56
|
-
EMAIL_AUTH_CODE_ERROR: { text: "Invalid code \u2014 try again" },
|
|
57
|
-
EMAIL_AUTH_CODE_SUCCESS: { text: "Code verified!" },
|
|
58
|
-
WALLET_AUTH_START: { text: "Connecting wallet\u2026" },
|
|
59
|
-
WALLET_AUTH_FREIGHTER_NOT_INSTALLED: { text: "Freighter is not installed" },
|
|
60
|
-
WALLET_AUTH_ALBEDO_NOT_INSTALLED: { text: "Albedo is not installed" },
|
|
61
|
-
WALLET_AUTH_CONNECTED: { text: "Wallet connected" },
|
|
62
|
-
WALLET_AUTH_LOGIN_START: { text: "Signing in with wallet\u2026" },
|
|
63
|
-
WALLET_AUTH_LOGIN_START_SUCCESS: { text: "Wallet signed in" },
|
|
64
|
-
WALLET_AUTH_LOGIN_START_ERROR: { text: "Failed to sign in with wallet" },
|
|
65
|
-
WALLET_AUTH_ERROR: { text: "Unknow wallet error" },
|
|
66
|
-
STREAM_POLL_START: { text: "Waiting for authentication\u2026" },
|
|
67
|
-
STREAM_POLL_EVENT: { text: "Waiting for authentication\u2026" },
|
|
68
|
-
STREAM_POLL_READY: { text: "Authenticated!" },
|
|
69
|
-
FETCH_SESSION_START: { text: "Loading session\u2026" },
|
|
70
|
-
FETCH_SESSION_SUCCESS: { text: "Welcome back!" },
|
|
71
|
-
FETCH_SESSION_ERROR: { text: "Failed to load session" },
|
|
72
|
-
NO_RESTORED_SESSION: { text: "" },
|
|
73
|
-
RESTORED_SESSION_SUCCESS: { text: "Session restored" },
|
|
74
|
-
RESTORED_SESSION_ERROR: { text: "Failed to restore session" },
|
|
75
|
-
SESSION_STORED: { text: "Session saved" },
|
|
76
|
-
ERROR_UNKNOWN: { text: "Something went wrong" },
|
|
77
|
-
ABORTED: { text: "Login cancelled" },
|
|
78
|
-
// transaction
|
|
79
|
-
BUILD_TRANSACTION_START: { text: "Building transaction\u2026" },
|
|
80
|
-
BUILD_TRANSACTION_SUCCESS: { text: "Transaction built, ready to sign and send" },
|
|
81
|
-
BUILD_TRANSACTION_ERROR: { text: "Failed to build transaction" },
|
|
82
|
-
BUILD_TRANSACTION_ERROR_NO_WALLET: { text: "No wallet connected" },
|
|
83
|
-
SIGN_SEND_TRANSACTION_START: { text: "Signing and sending transaction\u2026" },
|
|
84
|
-
SIGN_SEND_TRANSACTION_SUCCESS: { text: "Transaction signed" },
|
|
85
|
-
SIGN_SEND_TRANSACTION_ERROR: { text: "Signing rejected" }
|
|
86
|
-
};
|
|
87
|
-
function ModalStatusBanner({ code, status, onCancel, onRetry }) {
|
|
88
|
-
if (!code) {
|
|
47
|
+
function ModalStatusBanner({ message, status, onCancel, onRetry }) {
|
|
48
|
+
if (!message && status === "NONE") {
|
|
89
49
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-status" });
|
|
90
50
|
}
|
|
91
|
-
const { text } = LOGIN_CODE_MESSAGES[code] || { text: "" };
|
|
92
51
|
const isLoading = status === "LOADING";
|
|
93
52
|
const icon = status === "ERROR" ? /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
|
|
94
53
|
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
|
|
@@ -99,11 +58,161 @@ function ModalStatusBanner({ code, status, onCancel, onRetry }) {
|
|
|
99
58
|
] }) : status === "LOADING" ? /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "5.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeDasharray: "22 10" }) }) : null;
|
|
100
59
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-status", "data-kind": status, children: [
|
|
101
60
|
icon,
|
|
102
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children:
|
|
61
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: message }),
|
|
103
62
|
isLoading && onCancel && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-status-cancel", onClick: onCancel, children: "Cancel" }),
|
|
104
|
-
status ===
|
|
63
|
+
status === "ERROR" && onRetry && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-status-cancel", onClick: onRetry, children: "Retry" })
|
|
105
64
|
] });
|
|
106
65
|
}
|
|
66
|
+
var STATUS_CONFIG = {
|
|
67
|
+
none: { label: "Not started", color: "#6b7280", dot: false },
|
|
68
|
+
pending: { label: "Pending review", color: "#f59e0b", dot: true },
|
|
69
|
+
approved: { label: "Verified", color: "#10b981", dot: false },
|
|
70
|
+
rejected: { label: "Rejected", color: "#ef4444", dot: false }
|
|
71
|
+
};
|
|
72
|
+
function KycStatus({ status, className }) {
|
|
73
|
+
const config = STATUS_CONFIG[status] ?? STATUS_CONFIG.none;
|
|
74
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
75
|
+
"span",
|
|
76
|
+
{
|
|
77
|
+
className: `pollar-kyc-badge${className ? ` ${className}` : ""}`,
|
|
78
|
+
style: { "--pollar-kyc-color": config.color },
|
|
79
|
+
children: [
|
|
80
|
+
config.dot && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-kyc-badge-dot" }),
|
|
81
|
+
config.label
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
function KycModalTemplate({
|
|
87
|
+
theme,
|
|
88
|
+
accentColor,
|
|
89
|
+
step,
|
|
90
|
+
providers,
|
|
91
|
+
selectedProvider,
|
|
92
|
+
session,
|
|
93
|
+
kycStatus,
|
|
94
|
+
isLoading,
|
|
95
|
+
onSelectProvider,
|
|
96
|
+
onDoneVerifying,
|
|
97
|
+
onClose
|
|
98
|
+
}) {
|
|
99
|
+
const isDark = theme === "dark";
|
|
100
|
+
const cssVars = {
|
|
101
|
+
"--pollar-accent": accentColor,
|
|
102
|
+
"--pollar-buttons-border-radius": "6px",
|
|
103
|
+
"--pollar-buttons-height": "44px",
|
|
104
|
+
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
105
|
+
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
106
|
+
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
107
|
+
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
108
|
+
"--pollar-input-bg": isDark ? "#374151" : "#f9fafb"
|
|
109
|
+
};
|
|
110
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-kyc-modal", style: cssVars, onClick: (e) => e.stopPropagation(), children: [
|
|
111
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-kyc-header", children: [
|
|
112
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-kyc-title", children: "Identity verification" }),
|
|
113
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "pollar-kyc-subtitle", children: [
|
|
114
|
+
step === "select_provider" && "Choose your verification provider",
|
|
115
|
+
step === "verifying" && `Verifying with ${selectedProvider?.name}`,
|
|
116
|
+
step === "polling" && "Waiting for verification result",
|
|
117
|
+
step === "done" && "Verification complete"
|
|
118
|
+
] })
|
|
119
|
+
] }),
|
|
120
|
+
step === "select_provider" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-kyc-providers", children: [
|
|
121
|
+
providers.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { color: "var(--pollar-muted)", textAlign: "center" }, children: "No providers available for your country." }),
|
|
122
|
+
providers.map((p) => /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "pollar-kyc-provider-btn", disabled: isLoading, onClick: () => onSelectProvider(p), children: [
|
|
123
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-kyc-provider-name", children: p.name }),
|
|
124
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-kyc-provider-flow", children: p.flow })
|
|
125
|
+
] }, p.id))
|
|
126
|
+
] }),
|
|
127
|
+
step === "verifying" && selectedProvider && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
128
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-kyc-iframe-wrap", children: session?.kycUrl ? /* @__PURE__ */ jsxRuntime.jsx("iframe", { className: "pollar-kyc-iframe", src: session.kycUrl, title: "KYC verification", allow: "camera; microphone" }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-kyc-iframe-mock", children: [
|
|
129
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u{1F512}" }),
|
|
130
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: selectedProvider.flow === "form" ? "Form-based KYC \u2014 fields will render here once backend is connected" : "KYC iframe will load here once backend is connected" }),
|
|
131
|
+
/* @__PURE__ */ jsxRuntime.jsxs("code", { style: { fontSize: "0.7rem", opacity: 0.6 }, children: [
|
|
132
|
+
"provider: ",
|
|
133
|
+
selectedProvider.id
|
|
134
|
+
] })
|
|
135
|
+
] }) }),
|
|
136
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-actions", children: [
|
|
137
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-secondary", onClick: onClose, children: "Cancel" }),
|
|
138
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-primary", onClick: onDoneVerifying, children: "I've completed verification" })
|
|
139
|
+
] })
|
|
140
|
+
] }),
|
|
141
|
+
step === "polling" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-kyc-polling", children: [
|
|
142
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-spinner" }),
|
|
143
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "pollar-kyc-polling-text", children: "Checking verification status\u2026" })
|
|
144
|
+
] }),
|
|
145
|
+
step === "done" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-kyc-result", children: [
|
|
146
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-kyc-result-icon", children: kycStatus === "approved" ? "\u2705" : "\u274C" }),
|
|
147
|
+
/* @__PURE__ */ jsxRuntime.jsx(KycStatus, { status: kycStatus }),
|
|
148
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "pollar-kyc-result-text", children: kycStatus === "approved" ? "Your identity has been verified successfully." : "Verification was not approved. Please try again." }),
|
|
149
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-actions", children: /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-primary", onClick: onClose, children: "Close" }) })
|
|
150
|
+
] })
|
|
151
|
+
] });
|
|
152
|
+
}
|
|
153
|
+
function KycModal({ onClose, country = "MX", level = "basic", onApproved }) {
|
|
154
|
+
const { getClient, styles } = usePollar();
|
|
155
|
+
const [step, setStep] = react.useState("select_provider");
|
|
156
|
+
const [providers, setProviders] = react.useState([]);
|
|
157
|
+
const [selectedProvider, setSelectedProvider] = react.useState(null);
|
|
158
|
+
const [session, setSession] = react.useState(null);
|
|
159
|
+
const [kycStatus, setKycStatus] = react.useState("none");
|
|
160
|
+
const [isLoading, setIsLoading] = react.useState(false);
|
|
161
|
+
const client = getClient();
|
|
162
|
+
const { theme = "light", accentColor = "#005DB4" } = styles;
|
|
163
|
+
react.useEffect(() => {
|
|
164
|
+
setIsLoading(true);
|
|
165
|
+
client.getKycProviders(country).then((result) => setProviders(result.providers)).catch(() => setProviders([])).finally(() => setIsLoading(false));
|
|
166
|
+
}, [country]);
|
|
167
|
+
async function handleSelectProvider(provider) {
|
|
168
|
+
setSelectedProvider(provider);
|
|
169
|
+
setIsLoading(true);
|
|
170
|
+
try {
|
|
171
|
+
const result = await client.resolveKyc(provider.id, level);
|
|
172
|
+
if (result.alreadyApproved) {
|
|
173
|
+
setKycStatus("approved");
|
|
174
|
+
setStep("done");
|
|
175
|
+
onApproved?.();
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
setSession(result);
|
|
179
|
+
setStep("verifying");
|
|
180
|
+
} catch {
|
|
181
|
+
setStep("select_provider");
|
|
182
|
+
} finally {
|
|
183
|
+
setIsLoading(false);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
async function handleDoneVerifying() {
|
|
187
|
+
if (!selectedProvider) return;
|
|
188
|
+
setStep("polling");
|
|
189
|
+
try {
|
|
190
|
+
const finalStatus = await client.pollKycStatus(selectedProvider.id, { intervalMs: 3e3, timeoutMs: 12e4 });
|
|
191
|
+
setKycStatus(finalStatus);
|
|
192
|
+
setStep("done");
|
|
193
|
+
if (finalStatus === "approved") onApproved?.();
|
|
194
|
+
} catch {
|
|
195
|
+
setKycStatus("rejected");
|
|
196
|
+
setStep("done");
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
200
|
+
KycModalTemplate,
|
|
201
|
+
{
|
|
202
|
+
theme,
|
|
203
|
+
accentColor,
|
|
204
|
+
step,
|
|
205
|
+
providers,
|
|
206
|
+
selectedProvider,
|
|
207
|
+
session,
|
|
208
|
+
kycStatus,
|
|
209
|
+
isLoading,
|
|
210
|
+
onSelectProvider: handleSelectProvider,
|
|
211
|
+
onDoneVerifying: handleDoneVerifying,
|
|
212
|
+
onClose
|
|
213
|
+
}
|
|
214
|
+
) });
|
|
215
|
+
}
|
|
107
216
|
function EmailCodeInput({ email, onSubmit }) {
|
|
108
217
|
const [digits, setDigits] = react.useState(["", "", "", "", "", ""]);
|
|
109
218
|
const inputRefs = react.useRef([]);
|
|
@@ -210,6 +319,38 @@ var GoogleButton = ({ disabled, onClick }) => {
|
|
|
210
319
|
] })
|
|
211
320
|
] });
|
|
212
321
|
};
|
|
322
|
+
var AUTH_STATE_MESSAGES = {
|
|
323
|
+
idle: "",
|
|
324
|
+
creating_session: "Initializing\u2026",
|
|
325
|
+
entering_email: "",
|
|
326
|
+
sending_email: "Sending\u2026",
|
|
327
|
+
entering_code: "Code sent \u2014 check your inbox",
|
|
328
|
+
verifying_email_code: "Verifying\u2026",
|
|
329
|
+
opening_oauth: "Redirecting\u2026",
|
|
330
|
+
connecting_wallet: "Connecting wallet\u2026",
|
|
331
|
+
wallet_not_installed: "Wallet not installed",
|
|
332
|
+
authenticating_wallet: "Signing in with wallet\u2026",
|
|
333
|
+
authenticating: "Authenticating\u2026",
|
|
334
|
+
authenticated: "Welcome!",
|
|
335
|
+
error: ""
|
|
336
|
+
};
|
|
337
|
+
function authStateToStatus(step) {
|
|
338
|
+
const loading = [
|
|
339
|
+
"creating_session",
|
|
340
|
+
"sending_email",
|
|
341
|
+
"verifying_email_code",
|
|
342
|
+
"opening_oauth",
|
|
343
|
+
"connecting_wallet",
|
|
344
|
+
"authenticating_wallet",
|
|
345
|
+
"authenticating"
|
|
346
|
+
];
|
|
347
|
+
const success = ["authenticated", "entering_code"];
|
|
348
|
+
const error = ["error", "wallet_not_installed"];
|
|
349
|
+
if (loading.includes(step)) return "LOADING";
|
|
350
|
+
if (success.includes(step)) return "SUCCESS";
|
|
351
|
+
if (error.includes(step)) return "ERROR";
|
|
352
|
+
return "NONE";
|
|
353
|
+
}
|
|
213
354
|
function LoginModalTemplate({
|
|
214
355
|
theme,
|
|
215
356
|
accentColor,
|
|
@@ -219,17 +360,16 @@ function LoginModalTemplate({
|
|
|
219
360
|
providers,
|
|
220
361
|
appName,
|
|
221
362
|
email = "",
|
|
222
|
-
status,
|
|
223
|
-
error,
|
|
224
363
|
onEmailChange,
|
|
225
364
|
onEmailSubmit,
|
|
226
365
|
onSocialLogin,
|
|
227
366
|
onFreighterConnect,
|
|
228
367
|
onAlbedoConnect,
|
|
229
|
-
|
|
230
|
-
|
|
368
|
+
authState,
|
|
369
|
+
codeInputKey,
|
|
231
370
|
onCodeSubmit,
|
|
232
|
-
|
|
371
|
+
onBack,
|
|
372
|
+
onCancel,
|
|
233
373
|
onRetry
|
|
234
374
|
}) {
|
|
235
375
|
const isDark = theme === "dark";
|
|
@@ -247,16 +387,22 @@ function LoginModalTemplate({
|
|
|
247
387
|
"--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
|
|
248
388
|
"--pollar-error-text": isDark ? "#f87171" : "#dc2626"
|
|
249
389
|
};
|
|
250
|
-
const
|
|
390
|
+
const status = authStateToStatus(authState.step);
|
|
391
|
+
const isLoading = status === "LOADING";
|
|
392
|
+
const isEmailCodeError = authState.step === "error" && (authState.errorCode === core.AUTH_ERROR_CODES.EMAIL_CODE_EXPIRED || authState.errorCode === core.AUTH_ERROR_CODES.EMAIL_CODE_INVALID);
|
|
393
|
+
const awaitingEmailCode = authState.step === "entering_code" || authState.step === "verifying_email_code" || isEmailCodeError;
|
|
394
|
+
const statusMessage = authState.step === "error" ? authState.message : AUTH_STATE_MESSAGES[authState.step];
|
|
251
395
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal", style: cssVars, onClick: (e) => e.stopPropagation(), children: [
|
|
252
396
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-header", children: [
|
|
253
397
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-logo-wrap", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: logoUrl ?? LOGO_POLLAR, alt: "Logo", className: "pollar-logo" }) }),
|
|
254
398
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-title", children: appName }),
|
|
255
399
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "pollar-subtitle", children: "Log in or sign up" })
|
|
256
400
|
] }),
|
|
257
|
-
awaitingEmailCode ? /* @__PURE__ */ jsxRuntime.
|
|
258
|
-
|
|
259
|
-
|
|
401
|
+
awaitingEmailCode ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
402
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-back-btn", onClick: onBack, children: "\u2190 Back" }),
|
|
403
|
+
/* @__PURE__ */ jsxRuntime.jsx(EmailCodeInput, { email, onSubmit: onCodeSubmit ?? (() => {
|
|
404
|
+
}) }, codeInputKey)
|
|
405
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
260
406
|
emailEnabled && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-email-section", children: [
|
|
261
407
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
262
408
|
"input",
|
|
@@ -292,74 +438,68 @@ function LoginModalTemplate({
|
|
|
292
438
|
] })
|
|
293
439
|
] })
|
|
294
440
|
] }),
|
|
295
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
441
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
442
|
+
ModalStatusBanner,
|
|
443
|
+
{
|
|
444
|
+
message: statusMessage,
|
|
445
|
+
status,
|
|
446
|
+
onCancel,
|
|
447
|
+
onRetry: isEmailCodeError ? void 0 : onRetry
|
|
448
|
+
}
|
|
449
|
+
),
|
|
296
450
|
/* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
|
|
297
451
|
] });
|
|
298
452
|
}
|
|
299
|
-
function isLoginCode(code) {
|
|
300
|
-
return Object.values(core.STATE_VAR_CODES[core.PollarStateVar.AUTHENTICATION]).some((c) => code.startsWith(c));
|
|
301
|
-
}
|
|
302
453
|
function LoginModal({ onClose }) {
|
|
303
454
|
const [email, setEmail] = react.useState("");
|
|
304
455
|
const { getClient, styles, config } = usePollar();
|
|
305
|
-
const [
|
|
306
|
-
const [
|
|
307
|
-
const
|
|
308
|
-
const [awaitingEmailCode, setAwaitingEmailCode] = react.useState(false);
|
|
309
|
-
const [clientSessionId, setClientSessionId] = react.useState(null);
|
|
456
|
+
const [authState, setAuthState] = react.useState(() => getClient().getAuthState());
|
|
457
|
+
const [codeInputKey, setCodeInputKey] = react.useState(0);
|
|
458
|
+
const pendingEmail = react.useRef(null);
|
|
310
459
|
react.useEffect(() => {
|
|
311
|
-
return getClient().
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
setAwaitingEmailCode(true);
|
|
323
|
-
setClientSessionId(data?.content?.clientSessionId);
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
if (stateEntry.code === core.STATE_VAR_CODES[core.PollarStateVar.AUTHENTICATION].FETCH_SESSION_SUCCESS) {
|
|
327
|
-
setAwaitingEmailCode(false);
|
|
328
|
-
setTimeout(onClose, 1e3);
|
|
329
|
-
}
|
|
460
|
+
return getClient().onAuthStateChange((next) => {
|
|
461
|
+
setAuthState(next);
|
|
462
|
+
if (next.step === "entering_email" && pendingEmail.current) {
|
|
463
|
+
getClient().sendEmailCode(pendingEmail.current);
|
|
464
|
+
pendingEmail.current = null;
|
|
465
|
+
}
|
|
466
|
+
if (next.step === "error" && next.errorCode === core.AUTH_ERROR_CODES.EMAIL_CODE_INVALID) {
|
|
467
|
+
setCodeInputKey((k) => k + 1);
|
|
468
|
+
}
|
|
469
|
+
if (next.step === "authenticated") {
|
|
470
|
+
setTimeout(onClose, 1e3);
|
|
330
471
|
}
|
|
331
472
|
});
|
|
332
473
|
}, []);
|
|
333
474
|
const { theme = "light", accentColor = "#005DB4", logoUrl, emailEnabled, embeddedWallets, providers } = styles;
|
|
334
475
|
function handleClose() {
|
|
335
476
|
setEmail("");
|
|
336
|
-
|
|
337
|
-
setAwaitingEmailCode(false);
|
|
338
|
-
setClientSessionId(null);
|
|
477
|
+
getClient().cancelLogin();
|
|
339
478
|
onClose();
|
|
340
479
|
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
}
|
|
346
|
-
const { cancelLogin } = getClient().login({ provider: "email", email });
|
|
347
|
-
cancelLoginRef.current = cancelLogin;
|
|
480
|
+
function handleEmailSubmit() {
|
|
481
|
+
if (!email) return;
|
|
482
|
+
pendingEmail.current = email;
|
|
483
|
+
getClient().beginEmailLogin();
|
|
348
484
|
}
|
|
349
485
|
function handleSocialLogin(provider) {
|
|
350
|
-
|
|
351
|
-
cancelLoginRef.current = cancelLogin;
|
|
486
|
+
getClient().login({ provider });
|
|
352
487
|
}
|
|
353
488
|
function handleWalletConnect(type) {
|
|
354
|
-
|
|
355
|
-
cancelLoginRef.current = cancelLogin;
|
|
489
|
+
getClient().loginWallet(type);
|
|
356
490
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
491
|
+
function handleVerifyCode(code) {
|
|
492
|
+
getClient().verifyEmailCode(code);
|
|
493
|
+
}
|
|
494
|
+
function handleBack() {
|
|
495
|
+
setEmail("");
|
|
496
|
+
getClient().cancelLogin();
|
|
360
497
|
}
|
|
361
498
|
function handleRetry() {
|
|
362
499
|
getClient().logout();
|
|
500
|
+
if (styles.emailEnabled) {
|
|
501
|
+
getClient().beginEmailLogin();
|
|
502
|
+
}
|
|
363
503
|
}
|
|
364
504
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: handleClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
365
505
|
LoginModalTemplate,
|
|
@@ -378,31 +518,330 @@ function LoginModal({ onClose }) {
|
|
|
378
518
|
},
|
|
379
519
|
appName: config.application?.name ?? "Pollar",
|
|
380
520
|
email,
|
|
381
|
-
status,
|
|
382
|
-
error,
|
|
383
521
|
onEmailChange: setEmail,
|
|
384
|
-
onEmailSubmit:
|
|
522
|
+
onEmailSubmit: handleEmailSubmit,
|
|
385
523
|
onSocialLogin: handleSocialLogin,
|
|
386
524
|
onFreighterConnect: () => handleWalletConnect(core.WalletType.FREIGHTER),
|
|
387
525
|
onAlbedoConnect: () => handleWalletConnect(core.WalletType.ALBEDO),
|
|
388
|
-
|
|
389
|
-
|
|
526
|
+
authState,
|
|
527
|
+
codeInputKey,
|
|
390
528
|
onCodeSubmit: handleVerifyCode,
|
|
391
|
-
|
|
529
|
+
onBack: handleBack,
|
|
530
|
+
onCancel: () => getClient().cancelLogin(),
|
|
392
531
|
onRetry: handleRetry
|
|
393
532
|
}
|
|
394
533
|
) });
|
|
395
534
|
}
|
|
535
|
+
var RAIL_LABELS = {
|
|
536
|
+
SPEI: "SPEI (Mexico)",
|
|
537
|
+
PIX: "PIX (Brazil)",
|
|
538
|
+
PSE: "PSE (Colombia)",
|
|
539
|
+
ACH: "ACH (US)"
|
|
540
|
+
};
|
|
541
|
+
function RouteDisplay({ quote, onSelect }) {
|
|
542
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
543
|
+
"div",
|
|
544
|
+
{
|
|
545
|
+
className: "pollar-ramp-route-card",
|
|
546
|
+
"data-recommended": quote.recommended,
|
|
547
|
+
role: "button",
|
|
548
|
+
tabIndex: 0,
|
|
549
|
+
onClick: () => onSelect(quote),
|
|
550
|
+
onKeyDown: (e) => e.key === "Enter" && onSelect(quote),
|
|
551
|
+
children: [
|
|
552
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-route-left", children: [
|
|
553
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-ramp-route-provider", children: quote.provider }),
|
|
554
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-ramp-route-meta", children: [
|
|
555
|
+
RAIL_LABELS[quote.rail] ?? quote.rail,
|
|
556
|
+
" \xB7 ",
|
|
557
|
+
quote.protocol,
|
|
558
|
+
" \xB7 ",
|
|
559
|
+
quote.estimatedTime
|
|
560
|
+
] })
|
|
561
|
+
] }),
|
|
562
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-route-right", children: [
|
|
563
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-ramp-route-fee", children: [
|
|
564
|
+
quote.fee,
|
|
565
|
+
"% fee"
|
|
566
|
+
] }),
|
|
567
|
+
quote.recommended && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-ramp-route-badge", children: "Best rate" })
|
|
568
|
+
] })
|
|
569
|
+
]
|
|
570
|
+
}
|
|
571
|
+
);
|
|
572
|
+
}
|
|
573
|
+
var LOADING_STEPS = ["Detecting your country\u2026", "Consulting providers\u2026", "Route found!"];
|
|
574
|
+
var COUNTRY_CURRENCIES = {
|
|
575
|
+
MX: "MXN",
|
|
576
|
+
BR: "BRL",
|
|
577
|
+
CO: "COP",
|
|
578
|
+
CL: "CLP",
|
|
579
|
+
PE: "PEN",
|
|
580
|
+
AR: "ARS"
|
|
581
|
+
};
|
|
582
|
+
function RampWidgetTemplate({
|
|
583
|
+
theme,
|
|
584
|
+
accentColor,
|
|
585
|
+
step,
|
|
586
|
+
direction,
|
|
587
|
+
amount,
|
|
588
|
+
currency,
|
|
589
|
+
country,
|
|
590
|
+
quotes,
|
|
591
|
+
paymentInstructions,
|
|
592
|
+
isLoading,
|
|
593
|
+
onDirectionChange,
|
|
594
|
+
onAmountChange,
|
|
595
|
+
onCurrencyChange,
|
|
596
|
+
onCountryChange,
|
|
597
|
+
onFindRoute,
|
|
598
|
+
onSelectQuote,
|
|
599
|
+
onCopy,
|
|
600
|
+
onClose
|
|
601
|
+
}) {
|
|
602
|
+
const isDark = theme === "dark";
|
|
603
|
+
const cssVars = {
|
|
604
|
+
"--pollar-accent": accentColor,
|
|
605
|
+
"--pollar-buttons-border-radius": "6px",
|
|
606
|
+
"--pollar-buttons-height": "44px",
|
|
607
|
+
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
608
|
+
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
609
|
+
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
610
|
+
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
611
|
+
"--pollar-input-bg": isDark ? "#374151" : "#f9fafb"
|
|
612
|
+
};
|
|
613
|
+
const stepTitle = {
|
|
614
|
+
input: direction === "onramp" ? "Buy crypto" : "Sell crypto",
|
|
615
|
+
loading_quote: "Finding best route",
|
|
616
|
+
select_route: "Select provider",
|
|
617
|
+
payment_instructions: "Payment instructions"
|
|
618
|
+
};
|
|
619
|
+
const stepSubtitle = {
|
|
620
|
+
input: direction === "onramp" ? "Enter the amount you want to deposit" : "Enter the amount you want to withdraw",
|
|
621
|
+
loading_quote: "Comparing providers in real time\u2026",
|
|
622
|
+
select_route: "All prices include fees",
|
|
623
|
+
payment_instructions: "Send the exact amount to complete your transaction"
|
|
624
|
+
};
|
|
625
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-modal", style: cssVars, onClick: (e) => e.stopPropagation(), children: [
|
|
626
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-header", children: [
|
|
627
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-ramp-title", children: stepTitle[step] }),
|
|
628
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "pollar-ramp-subtitle", children: stepSubtitle[step] })
|
|
629
|
+
] }),
|
|
630
|
+
step === "input" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
631
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-tabs", children: [
|
|
632
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-ramp-tab", "data-active": direction === "onramp", onClick: () => onDirectionChange("onramp"), children: "Buy" }),
|
|
633
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-ramp-tab", "data-active": direction === "offramp", onClick: () => onDirectionChange("offramp"), children: "Sell" })
|
|
634
|
+
] }),
|
|
635
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-input-row", children: [
|
|
636
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-field", children: [
|
|
637
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "pollar-ramp-label", children: "Amount" }),
|
|
638
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
639
|
+
"input",
|
|
640
|
+
{
|
|
641
|
+
type: "number",
|
|
642
|
+
className: "pollar-ramp-input",
|
|
643
|
+
placeholder: "0.00",
|
|
644
|
+
value: amount,
|
|
645
|
+
min: "0",
|
|
646
|
+
onChange: (e) => onAmountChange(e.target.value)
|
|
647
|
+
}
|
|
648
|
+
)
|
|
649
|
+
] }),
|
|
650
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-field", style: { maxWidth: 90 }, children: [
|
|
651
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "pollar-ramp-label", children: "Currency" }),
|
|
652
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
653
|
+
"input",
|
|
654
|
+
{
|
|
655
|
+
type: "text",
|
|
656
|
+
className: "pollar-ramp-input",
|
|
657
|
+
placeholder: "MXN",
|
|
658
|
+
value: currency,
|
|
659
|
+
maxLength: 5,
|
|
660
|
+
onChange: (e) => onCurrencyChange(e.target.value.toUpperCase())
|
|
661
|
+
}
|
|
662
|
+
)
|
|
663
|
+
] })
|
|
664
|
+
] }),
|
|
665
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-field", children: [
|
|
666
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "pollar-ramp-label", children: "Country" }),
|
|
667
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
668
|
+
"select",
|
|
669
|
+
{
|
|
670
|
+
className: "pollar-ramp-input",
|
|
671
|
+
value: country,
|
|
672
|
+
onChange: (e) => {
|
|
673
|
+
const c = e.target.value;
|
|
674
|
+
onCountryChange(c);
|
|
675
|
+
if (COUNTRY_CURRENCIES[c]) onCurrencyChange(COUNTRY_CURRENCIES[c]);
|
|
676
|
+
},
|
|
677
|
+
children: [
|
|
678
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "MX", children: "\u{1F1F2}\u{1F1FD} Mexico" }),
|
|
679
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "BR", children: "\u{1F1E7}\u{1F1F7} Brazil" }),
|
|
680
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "CO", children: "\u{1F1E8}\u{1F1F4} Colombia" }),
|
|
681
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "CL", children: "\u{1F1E8}\u{1F1F1} Chile" }),
|
|
682
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "PE", children: "\u{1F1F5}\u{1F1EA} Peru" }),
|
|
683
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "AR", children: "\u{1F1E6}\u{1F1F7} Argentina" })
|
|
684
|
+
]
|
|
685
|
+
}
|
|
686
|
+
)
|
|
687
|
+
] }),
|
|
688
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-actions", children: [
|
|
689
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-secondary", onClick: onClose, children: "Cancel" }),
|
|
690
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-primary", disabled: !amount || isLoading, onClick: onFindRoute, children: "Find best route" })
|
|
691
|
+
] })
|
|
692
|
+
] }),
|
|
693
|
+
step === "loading_quote" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-ramp-loading", children: LOADING_STEPS.map((text, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-loading-row", children: [
|
|
694
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-ramp-loading-dot" }),
|
|
695
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: text })
|
|
696
|
+
] }, i)) }),
|
|
697
|
+
step === "select_route" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
698
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-ramp-route-list", children: quotes.map((q, i) => /* @__PURE__ */ jsxRuntime.jsx(RouteDisplay, { quote: q, onSelect: onSelectQuote }, i)) }),
|
|
699
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-secondary", onClick: onClose, children: "Cancel" })
|
|
700
|
+
] }),
|
|
701
|
+
step === "payment_instructions" && paymentInstructions && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-payment", children: [
|
|
702
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "pollar-ramp-payment-title", children: paymentInstructions.type }),
|
|
703
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-payment-field", children: [
|
|
704
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-ramp-payment-label", children: paymentInstructions.type === "CLABE" ? "CLABE number" : paymentInstructions.type === "PIX" ? "PIX key" : "Account number" }),
|
|
705
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-payment-value", children: [
|
|
706
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { children: paymentInstructions.value }),
|
|
707
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-ramp-copy-btn", onClick: () => onCopy(paymentInstructions.value), children: "Copy" })
|
|
708
|
+
] })
|
|
709
|
+
] }),
|
|
710
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-payment-field", children: [
|
|
711
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-ramp-payment-label", children: "Amount to send" }),
|
|
712
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-ramp-payment-value", children: [
|
|
713
|
+
/* @__PURE__ */ jsxRuntime.jsxs("code", { children: [
|
|
714
|
+
paymentInstructions.amount.toLocaleString(),
|
|
715
|
+
" ",
|
|
716
|
+
paymentInstructions.currency
|
|
717
|
+
] }),
|
|
718
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
719
|
+
"button",
|
|
720
|
+
{
|
|
721
|
+
type: "button",
|
|
722
|
+
className: "pollar-ramp-copy-btn",
|
|
723
|
+
onClick: () => onCopy(`${paymentInstructions.amount} ${paymentInstructions.currency}`),
|
|
724
|
+
children: "Copy"
|
|
725
|
+
}
|
|
726
|
+
)
|
|
727
|
+
] })
|
|
728
|
+
] }),
|
|
729
|
+
paymentInstructions.expiresAt && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "pollar-ramp-payment-note", children: [
|
|
730
|
+
"Instructions expire at ",
|
|
731
|
+
new Date(paymentInstructions.expiresAt).toLocaleTimeString()
|
|
732
|
+
] }),
|
|
733
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-btn-primary", onClick: onClose, children: "Done" })
|
|
734
|
+
] })
|
|
735
|
+
] });
|
|
736
|
+
}
|
|
737
|
+
var MOCK_DEFAULT_QUOTES = [
|
|
738
|
+
{ quoteId: "meld-default", provider: "Meld", fee: 1.2, feeCurrency: "USD", rate: 1, rail: "ACH", protocol: "REST", estimatedTime: "~20 min", recommended: true }
|
|
739
|
+
];
|
|
740
|
+
var MOCK_QUOTES = {
|
|
741
|
+
MX: [
|
|
742
|
+
{ quoteId: "etherfuse-mx", provider: "Etherfuse", fee: 0.5, feeCurrency: "MXN", rate: 17.2, rail: "SPEI", protocol: "SEP-24", estimatedTime: "~10 min", recommended: true },
|
|
743
|
+
{ quoteId: "alfredpay-mx", provider: "AlfredPay", fee: 0.8, feeCurrency: "MXN", rate: 17.1, rail: "SPEI", protocol: "REST", estimatedTime: "~15 min", recommended: false }
|
|
744
|
+
],
|
|
745
|
+
BR: [{ quoteId: "abroad-br", provider: "Abroad", fee: 0.6, feeCurrency: "BRL", rate: 5.1, rail: "PIX", protocol: "REST", estimatedTime: "~5 min", recommended: true }],
|
|
746
|
+
CO: [
|
|
747
|
+
{ quoteId: "abroad-co", provider: "Abroad", fee: 0.7, feeCurrency: "COP", rate: 4100, rail: "PSE", protocol: "REST", estimatedTime: "~10 min", recommended: true },
|
|
748
|
+
{ quoteId: "koywe-co", provider: "Koywe", fee: 0.9, feeCurrency: "COP", rate: 4095, rail: "PSE", protocol: "REST", estimatedTime: "~15 min", recommended: false }
|
|
749
|
+
],
|
|
750
|
+
DEFAULT: MOCK_DEFAULT_QUOTES
|
|
751
|
+
};
|
|
752
|
+
var MOCK_PAYMENT = {
|
|
753
|
+
type: "CLABE",
|
|
754
|
+
value: "646180157088723456",
|
|
755
|
+
amount: 1e3,
|
|
756
|
+
currency: "MXN",
|
|
757
|
+
expiresAt: new Date(Date.now() + 30 * 60 * 1e3).toISOString()
|
|
758
|
+
};
|
|
759
|
+
function RampWidget({ onClose }) {
|
|
760
|
+
const { getClient, walletAddress, styles } = usePollar();
|
|
761
|
+
const [step, setStep] = react.useState("input");
|
|
762
|
+
const [direction, setDirection] = react.useState("onramp");
|
|
763
|
+
const [amount, setAmount] = react.useState("");
|
|
764
|
+
const [currency, setCurrency] = react.useState("MXN");
|
|
765
|
+
const [country, setCountry] = react.useState("MX");
|
|
766
|
+
const [quotes, setQuotes] = react.useState([]);
|
|
767
|
+
const [paymentInstructions, setPaymentInstructions] = react.useState(null);
|
|
768
|
+
const [isLoading, setIsLoading] = react.useState(false);
|
|
769
|
+
const client = getClient();
|
|
770
|
+
const { theme = "light", accentColor = "#005DB4" } = styles;
|
|
771
|
+
async function handleFindRoute() {
|
|
772
|
+
setStep("loading_quote");
|
|
773
|
+
setIsLoading(true);
|
|
774
|
+
try {
|
|
775
|
+
const result = await client.getRampsQuote({
|
|
776
|
+
country,
|
|
777
|
+
amount: Number(amount),
|
|
778
|
+
currency,
|
|
779
|
+
direction
|
|
780
|
+
});
|
|
781
|
+
if (result.quotes) setQuotes(result.quotes);
|
|
782
|
+
} catch {
|
|
783
|
+
await new Promise((r) => setTimeout(r, 1500));
|
|
784
|
+
setQuotes(MOCK_QUOTES[country] ?? MOCK_DEFAULT_QUOTES);
|
|
785
|
+
} finally {
|
|
786
|
+
setIsLoading(false);
|
|
787
|
+
setStep("select_route");
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
async function handleSelectQuote(quote) {
|
|
791
|
+
if (!walletAddress) return;
|
|
792
|
+
setIsLoading(true);
|
|
793
|
+
const body = {
|
|
794
|
+
quoteId: `${quote.provider}-${Date.now()}`,
|
|
795
|
+
amount: Number(amount),
|
|
796
|
+
currency,
|
|
797
|
+
country,
|
|
798
|
+
walletAddress
|
|
799
|
+
};
|
|
800
|
+
try {
|
|
801
|
+
const result = await client.createOnRamp(body);
|
|
802
|
+
setPaymentInstructions(result.paymentInstructions);
|
|
803
|
+
} catch {
|
|
804
|
+
await new Promise((r) => setTimeout(r, 800));
|
|
805
|
+
setPaymentInstructions({ ...MOCK_PAYMENT, currency });
|
|
806
|
+
} finally {
|
|
807
|
+
setIsLoading(false);
|
|
808
|
+
setStep("payment_instructions");
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
function handleCopy(value) {
|
|
812
|
+
navigator.clipboard.writeText(value).catch(() => {
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
816
|
+
RampWidgetTemplate,
|
|
817
|
+
{
|
|
818
|
+
theme,
|
|
819
|
+
accentColor,
|
|
820
|
+
step,
|
|
821
|
+
direction,
|
|
822
|
+
amount,
|
|
823
|
+
currency,
|
|
824
|
+
country,
|
|
825
|
+
quotes,
|
|
826
|
+
paymentInstructions,
|
|
827
|
+
isLoading,
|
|
828
|
+
onDirectionChange: setDirection,
|
|
829
|
+
onAmountChange: setAmount,
|
|
830
|
+
onCurrencyChange: setCurrency,
|
|
831
|
+
onCountryChange: setCountry,
|
|
832
|
+
onFindRoute: handleFindRoute,
|
|
833
|
+
onSelectQuote: handleSelectQuote,
|
|
834
|
+
onCopy: handleCopy,
|
|
835
|
+
onClose
|
|
836
|
+
}
|
|
837
|
+
) });
|
|
838
|
+
}
|
|
396
839
|
function TransactionModalTemplate({
|
|
397
840
|
theme,
|
|
398
841
|
accentColor,
|
|
399
|
-
|
|
400
|
-
status,
|
|
401
|
-
buildResult,
|
|
402
|
-
submitResult,
|
|
842
|
+
transaction,
|
|
403
843
|
onClose,
|
|
404
|
-
onSignAndSend
|
|
405
|
-
onRetrySignAndSend
|
|
844
|
+
onSignAndSend
|
|
406
845
|
}) {
|
|
407
846
|
const isDark = theme === "dark";
|
|
408
847
|
const cssVars = {
|
|
@@ -419,37 +858,49 @@ function TransactionModalTemplate({
|
|
|
419
858
|
};
|
|
420
859
|
const [showXdr, setShowXdr] = react.useState(false);
|
|
421
860
|
const [copied, setCopied] = react.useState(false);
|
|
861
|
+
const buildData = "buildData" in transaction ? transaction.buildData : null;
|
|
862
|
+
const hash = transaction.step === "success" ? transaction.hash : null;
|
|
863
|
+
const errorDetails = transaction.step === "error" ? transaction.details ?? null : null;
|
|
864
|
+
const isBuilt = transaction.step === "built";
|
|
865
|
+
const isSigning = transaction.step === "signing";
|
|
866
|
+
const isSuccess = transaction.step === "success";
|
|
867
|
+
const isError = transaction.step === "error";
|
|
868
|
+
const showDetails = buildData !== null && (isBuilt || isSigning || isSuccess);
|
|
869
|
+
const explorerNetwork = buildData?.summary.network?.toLowerCase().includes("testnet") ? "testnet" : "public";
|
|
870
|
+
const explorerUrl = hash ? `https://stellar.expert/explorer/${explorerNetwork}/tx/${hash}` : null;
|
|
422
871
|
function handleCopyHash() {
|
|
423
|
-
if (!
|
|
424
|
-
navigator.clipboard.writeText(
|
|
872
|
+
if (!hash) return;
|
|
873
|
+
navigator.clipboard.writeText(hash).then(() => {
|
|
425
874
|
setCopied(true);
|
|
426
875
|
setTimeout(() => setCopied(false), 2e3);
|
|
427
876
|
});
|
|
428
877
|
}
|
|
429
|
-
const
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
878
|
+
const statusMessage = {
|
|
879
|
+
idle: "",
|
|
880
|
+
building: "Building transaction\u2026",
|
|
881
|
+
built: "Ready to sign and send",
|
|
882
|
+
signing: "Signing and sending transaction\u2026",
|
|
883
|
+
success: "Transaction sent successfully",
|
|
884
|
+
error: "Transaction failed"
|
|
885
|
+
};
|
|
435
886
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-modal", "data-theme": theme, style: cssVars, onClick: (e) => e.stopPropagation(), children: [
|
|
436
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-
|
|
437
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-
|
|
438
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-
|
|
887
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
|
|
888
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Transaction" }),
|
|
889
|
+
/* @__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" }) }) })
|
|
439
890
|
] }),
|
|
440
|
-
|
|
891
|
+
showDetails && buildData && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
441
892
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-summary", children: [
|
|
442
893
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "pollar-tx-summary-title", children: "Details" }),
|
|
443
|
-
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "pollar-tx-summary-lines", children:
|
|
894
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "pollar-tx-summary-lines", children: buildData.summary.lines.map((line, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "pollar-tx-summary-line", children: line }, i)) })
|
|
444
895
|
] }),
|
|
445
896
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-meta", children: [
|
|
446
897
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-meta-item", children: [
|
|
447
898
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-tx-meta-label", children: "Network" }),
|
|
448
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-tx-meta-value", children:
|
|
899
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-tx-meta-value", children: buildData.summary.network })
|
|
449
900
|
] }),
|
|
450
901
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-meta-item", children: [
|
|
451
902
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-tx-meta-label", children: "Fee" }),
|
|
452
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-tx-meta-value", children:
|
|
903
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-tx-meta-value", children: buildData.summary.fee })
|
|
453
904
|
] })
|
|
454
905
|
] }),
|
|
455
906
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-xdr", children: [
|
|
@@ -468,111 +919,52 @@ function TransactionModalTemplate({
|
|
|
468
919
|
),
|
|
469
920
|
"Raw transaction (XDR)"
|
|
470
921
|
] }),
|
|
471
|
-
showXdr && /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "pollar-tx-xdr-content", children:
|
|
922
|
+
showXdr && /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "pollar-tx-xdr-content", children: buildData.unsignedXdr })
|
|
472
923
|
] })
|
|
473
924
|
] }),
|
|
474
|
-
|
|
925
|
+
isSuccess && hash && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-result", children: [
|
|
475
926
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-tx-result-label", children: "Transaction hash" }),
|
|
476
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-tx-result-hash", children:
|
|
927
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-tx-result-hash", children: hash }),
|
|
477
928
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-result-actions", children: [
|
|
478
929
|
/* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-tx-result-btn", onClick: handleCopyHash, children: copied ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
479
930
|
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
|
|
480
931
|
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
|
|
481
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
482
|
-
"path",
|
|
483
|
-
{
|
|
484
|
-
d: "M3.5 7l2.5 2.5 4.5-5",
|
|
485
|
-
stroke: "white",
|
|
486
|
-
strokeWidth: "1.5",
|
|
487
|
-
strokeLinecap: "round",
|
|
488
|
-
strokeLinejoin: "round"
|
|
489
|
-
}
|
|
490
|
-
)
|
|
932
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3.5 7l2.5 2.5 4.5-5", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
491
933
|
] }),
|
|
492
934
|
"Copied!"
|
|
493
935
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
494
936
|
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
|
|
495
937
|
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1.5", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
496
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
497
|
-
"path",
|
|
498
|
-
{
|
|
499
|
-
d: "M3 9H2a1 1 0 01-1-1V2a1 1 0 011-1h6a1 1 0 011 1v1",
|
|
500
|
-
stroke: "currentColor",
|
|
501
|
-
strokeWidth: "1.5",
|
|
502
|
-
strokeLinecap: "round"
|
|
503
|
-
}
|
|
504
|
-
)
|
|
938
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3 9H2a1 1 0 01-1-1V2a1 1 0 011-1h6a1 1 0 011 1v1", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
505
939
|
] }),
|
|
506
940
|
"Copy hash"
|
|
507
941
|
] }) }),
|
|
508
942
|
explorerUrl && /* @__PURE__ */ jsxRuntime.jsxs("a", { className: "pollar-tx-result-btn", href: explorerUrl, target: "_blank", rel: "noopener noreferrer", children: [
|
|
509
943
|
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
|
|
510
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
511
|
-
|
|
512
|
-
{
|
|
513
|
-
d: "M5 2H2a1 1 0 00-1 1v8a1 1 0 001 1h8a1 1 0 001-1V8",
|
|
514
|
-
stroke: "currentColor",
|
|
515
|
-
strokeWidth: "1.5",
|
|
516
|
-
strokeLinecap: "round"
|
|
517
|
-
}
|
|
518
|
-
),
|
|
519
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
520
|
-
"path",
|
|
521
|
-
{
|
|
522
|
-
d: "M8 1h4m0 0v4m0-4L6 7",
|
|
523
|
-
stroke: "currentColor",
|
|
524
|
-
strokeWidth: "1.5",
|
|
525
|
-
strokeLinecap: "round",
|
|
526
|
-
strokeLinejoin: "round"
|
|
527
|
-
}
|
|
528
|
-
)
|
|
944
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 2H2a1 1 0 00-1 1v8a1 1 0 001 1h8a1 1 0 001-1V8", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }),
|
|
945
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 1h4m0 0v4m0-4L6 7", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
529
946
|
] }),
|
|
530
947
|
"View on Explorer"
|
|
531
948
|
] })
|
|
532
949
|
] })
|
|
533
950
|
] }),
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
),
|
|
951
|
+
isError && errorDetails && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-error-details", children: [
|
|
952
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "pollar-tx-error-details-label", children: "Error details" }),
|
|
953
|
+
/* @__PURE__ */ jsxRuntime.jsx("pre", { className: "pollar-tx-error-details-content", children: errorDetails })
|
|
954
|
+
] }),
|
|
955
|
+
isBuilt && /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-btn-primary pollar-tx-sign-btn", onClick: onSignAndSend, children: "Sign & Send" }),
|
|
956
|
+
isSigning && /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-btn-primary pollar-tx-sign-btn", disabled: true, children: "Signing & sending\u2026" }),
|
|
957
|
+
isSuccess && /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-btn-primary pollar-tx-sign-btn", onClick: onClose, children: "Done" }),
|
|
958
|
+
/* @__PURE__ */ jsxRuntime.jsx(ModalStatusBanner, { message: statusMessage[transaction.step], status: isError ? "ERROR" : isSigning || transaction.step === "building" ? "LOADING" : isSuccess ? "SUCCESS" : "NONE" }),
|
|
543
959
|
/* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
|
|
544
960
|
] });
|
|
545
961
|
}
|
|
546
|
-
var isTxBuildResponseContent = (data) => {
|
|
547
|
-
if (!data || typeof data !== "object") return false;
|
|
548
|
-
const d = data;
|
|
549
|
-
return typeof d.unsignedXdr === "string" && typeof d.networkPassphrase === "string" && typeof d.estimatedFee === "string" && d.summary !== null && typeof d.summary === "object";
|
|
550
|
-
};
|
|
551
|
-
var isTxSignSendResponseContent = (data) => {
|
|
552
|
-
if (!data || typeof data !== "object") return false;
|
|
553
|
-
const d = data;
|
|
554
|
-
return typeof d.hash === "string" && (d.status === "PENDING" || d.status === "SUCCESS" || d.status === "FAILED");
|
|
555
|
-
};
|
|
556
962
|
function TransactionModal({ onClose }) {
|
|
557
|
-
const {
|
|
558
|
-
getClient,
|
|
559
|
-
styles,
|
|
560
|
-
state: { transaction }
|
|
561
|
-
} = usePollar();
|
|
963
|
+
const { getClient, styles, transaction } = usePollar();
|
|
562
964
|
const { theme = "light", accentColor = "#005DB4" } = styles;
|
|
563
|
-
let buildResult = null;
|
|
564
|
-
const transactionStateCode = transaction.code;
|
|
565
|
-
const content = transaction.data?.content;
|
|
566
|
-
if (isTxBuildResponseContent(content)) {
|
|
567
|
-
buildResult = content;
|
|
568
|
-
}
|
|
569
|
-
let submitResult = null;
|
|
570
|
-
if (isTxSignSendResponseContent(content)) {
|
|
571
|
-
submitResult = content;
|
|
572
|
-
}
|
|
573
965
|
async function handleSignAndSend() {
|
|
574
|
-
if (
|
|
575
|
-
await getClient().
|
|
966
|
+
if (transaction.step === "built") {
|
|
967
|
+
await getClient().signAndSubmitTx(transaction.buildData.unsignedXdr);
|
|
576
968
|
}
|
|
577
969
|
}
|
|
578
970
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -580,91 +972,275 @@ function TransactionModal({ onClose }) {
|
|
|
580
972
|
{
|
|
581
973
|
theme,
|
|
582
974
|
accentColor,
|
|
583
|
-
|
|
584
|
-
status: transaction.status,
|
|
585
|
-
buildResult,
|
|
586
|
-
submitResult,
|
|
975
|
+
transaction,
|
|
587
976
|
onClose,
|
|
588
|
-
onSignAndSend: handleSignAndSend
|
|
589
|
-
|
|
977
|
+
onSignAndSend: handleSignAndSend
|
|
978
|
+
}
|
|
979
|
+
) });
|
|
980
|
+
}
|
|
981
|
+
var PAGE_SIZE = 10;
|
|
982
|
+
function StatusBadge({ status }) {
|
|
983
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-hist-item-badge", "data-status": status, children: status });
|
|
984
|
+
}
|
|
985
|
+
function formatDate(iso) {
|
|
986
|
+
return new Date(iso).toLocaleDateString(void 0, { month: "short", day: "numeric", year: "numeric" });
|
|
987
|
+
}
|
|
988
|
+
function TxHistoryModalTemplate({
|
|
989
|
+
theme,
|
|
990
|
+
accentColor,
|
|
991
|
+
txHistory,
|
|
992
|
+
offset,
|
|
993
|
+
onRefresh,
|
|
994
|
+
onPrev,
|
|
995
|
+
onNext,
|
|
996
|
+
onClose
|
|
997
|
+
}) {
|
|
998
|
+
const isDark = theme === "dark";
|
|
999
|
+
const cssVars = {
|
|
1000
|
+
"--pollar-accent": accentColor,
|
|
1001
|
+
"--pollar-buttons-border-radius": "8px",
|
|
1002
|
+
"--pollar-buttons-height": "44px",
|
|
1003
|
+
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
1004
|
+
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
1005
|
+
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
1006
|
+
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
1007
|
+
"--pollar-input-bg": isDark ? "#374151" : "rgba(0,0,0,0.04)",
|
|
1008
|
+
"--pollar-error-text": isDark ? "#f87171" : "#dc2626",
|
|
1009
|
+
"--pollar-success-text": isDark ? "#4ade80" : "#16a34a"
|
|
1010
|
+
};
|
|
1011
|
+
const isLoading = txHistory.step === "loading";
|
|
1012
|
+
const records = txHistory.step === "loaded" ? txHistory.data.records : [];
|
|
1013
|
+
const total = txHistory.step === "loaded" ? txHistory.data.total : 0;
|
|
1014
|
+
const hasPrev = offset > 0;
|
|
1015
|
+
const hasNext = offset + PAGE_SIZE < total;
|
|
1016
|
+
const showPagination = txHistory.step === "loaded" && total > PAGE_SIZE;
|
|
1017
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-modal", "data-theme": theme, style: cssVars, onClick: (e) => e.stopPropagation(), children: [
|
|
1018
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
|
|
1019
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Transaction History" }),
|
|
1020
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
|
|
1021
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-modal-refresh-btn", onClick: onRefresh, disabled: isLoading, children: [
|
|
1022
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1023
|
+
"svg",
|
|
1024
|
+
{
|
|
1025
|
+
className: `pollar-modal-refresh-icon${isLoading ? " spinning" : ""}`,
|
|
1026
|
+
width: "13",
|
|
1027
|
+
height: "13",
|
|
1028
|
+
viewBox: "0 0 13 13",
|
|
1029
|
+
fill: "none",
|
|
1030
|
+
"aria-hidden": true,
|
|
1031
|
+
children: [
|
|
1032
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1033
|
+
"path",
|
|
1034
|
+
{
|
|
1035
|
+
d: "M11.5 6.5a5 5 0 11-1.5-3.536",
|
|
1036
|
+
stroke: "currentColor",
|
|
1037
|
+
strokeWidth: "1.5",
|
|
1038
|
+
strokeLinecap: "round"
|
|
1039
|
+
}
|
|
1040
|
+
),
|
|
1041
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 1v3h-3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
1042
|
+
]
|
|
1043
|
+
}
|
|
1044
|
+
),
|
|
1045
|
+
"Refresh"
|
|
1046
|
+
] }),
|
|
1047
|
+
/* @__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" }) }) })
|
|
1048
|
+
] })
|
|
1049
|
+
] }),
|
|
1050
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-list", children: [
|
|
1051
|
+
txHistory.step === "idle" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "Click Refresh to load transactions." }),
|
|
1052
|
+
isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "Loading\u2026" }),
|
|
1053
|
+
txHistory.step === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: txHistory.message }),
|
|
1054
|
+
txHistory.step === "loaded" && records.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No transactions yet." }),
|
|
1055
|
+
records.map((record) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-item", children: [
|
|
1056
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-hist-item-summary", children: record.summary }),
|
|
1057
|
+
/* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: record.status }),
|
|
1058
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-hist-item-meta", children: [
|
|
1059
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: record.operation }),
|
|
1060
|
+
record.feeXlm && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
1061
|
+
"\xB7 ",
|
|
1062
|
+
record.feeXlm,
|
|
1063
|
+
" XLM"
|
|
1064
|
+
] }),
|
|
1065
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
1066
|
+
"\xB7 ",
|
|
1067
|
+
formatDate(record.createdAt)
|
|
1068
|
+
] })
|
|
1069
|
+
] })
|
|
1070
|
+
] }, record.id))
|
|
1071
|
+
] }),
|
|
1072
|
+
showPagination && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-pagination", children: [
|
|
1073
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-hist-pagination-info", children: [
|
|
1074
|
+
offset + 1,
|
|
1075
|
+
"\u2013",
|
|
1076
|
+
Math.min(offset + PAGE_SIZE, total),
|
|
1077
|
+
" of ",
|
|
1078
|
+
total
|
|
1079
|
+
] }),
|
|
1080
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-hist-pagination-btns", children: [
|
|
1081
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-hist-page-btn", onClick: onPrev, disabled: !hasPrev, children: "\u2190 Prev" }),
|
|
1082
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-hist-page-btn", onClick: onNext, disabled: !hasNext, children: "Next \u2192" })
|
|
1083
|
+
] })
|
|
1084
|
+
] }),
|
|
1085
|
+
/* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
|
|
1086
|
+
] });
|
|
1087
|
+
}
|
|
1088
|
+
var PAGE_SIZE2 = 10;
|
|
1089
|
+
function TxHistoryModal({ onClose }) {
|
|
1090
|
+
const { getClient, styles, txHistory } = usePollar();
|
|
1091
|
+
const { theme = "light", accentColor = "#005DB4" } = styles;
|
|
1092
|
+
const [offset, setOffset] = react.useState(0);
|
|
1093
|
+
function load(nextOffset) {
|
|
1094
|
+
setOffset(nextOffset);
|
|
1095
|
+
void getClient().fetchTxHistory({ limit: PAGE_SIZE2, offset: nextOffset });
|
|
1096
|
+
}
|
|
1097
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1098
|
+
TxHistoryModalTemplate,
|
|
1099
|
+
{
|
|
1100
|
+
theme,
|
|
1101
|
+
accentColor,
|
|
1102
|
+
txHistory,
|
|
1103
|
+
offset,
|
|
1104
|
+
onRefresh: () => load(offset),
|
|
1105
|
+
onPrev: () => load(Math.max(0, offset - PAGE_SIZE2)),
|
|
1106
|
+
onNext: () => load(offset + PAGE_SIZE2),
|
|
1107
|
+
onClose
|
|
590
1108
|
}
|
|
591
1109
|
) });
|
|
592
1110
|
}
|
|
1111
|
+
function formatBalance(balance) {
|
|
1112
|
+
const n = parseFloat(balance);
|
|
1113
|
+
return isNaN(n) ? balance : n.toLocaleString(void 0, { maximumFractionDigits: 7 });
|
|
1114
|
+
}
|
|
1115
|
+
function cropAddress(address) {
|
|
1116
|
+
if (address.length <= 16) return address;
|
|
1117
|
+
return `${address.slice(0, 8)}...${address.slice(-8)}`;
|
|
1118
|
+
}
|
|
1119
|
+
function BalanceItem({ record }) {
|
|
1120
|
+
const balanceDiffers = record.balance !== record.available;
|
|
1121
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-bal-item", children: [
|
|
1122
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-bal-asset", children: record.code }),
|
|
1123
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-bal-amounts", children: [
|
|
1124
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-bal-amount", children: formatBalance(record.balance) }),
|
|
1125
|
+
balanceDiffers && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-bal-available", children: [
|
|
1126
|
+
formatBalance(record.available),
|
|
1127
|
+
" available"
|
|
1128
|
+
] })
|
|
1129
|
+
] })
|
|
1130
|
+
] });
|
|
1131
|
+
}
|
|
1132
|
+
function WalletBalanceModal({ onClose }) {
|
|
1133
|
+
const { getBalance, walletAddress, styles } = usePollar();
|
|
1134
|
+
const { theme = "light", accentColor = "#005DB4" } = styles;
|
|
1135
|
+
const isDark = theme === "dark";
|
|
1136
|
+
const cssVars = {
|
|
1137
|
+
"--pollar-accent": accentColor,
|
|
1138
|
+
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
1139
|
+
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
1140
|
+
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
1141
|
+
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
1142
|
+
"--pollar-input-bg": isDark ? "#374151" : "rgba(0,0,0,0.04)",
|
|
1143
|
+
"--pollar-error-text": isDark ? "#f87171" : "#dc2626"
|
|
1144
|
+
};
|
|
1145
|
+
const [status, setStatus] = react.useState("loading");
|
|
1146
|
+
const [data, setData] = react.useState(null);
|
|
1147
|
+
async function load() {
|
|
1148
|
+
setStatus("loading");
|
|
1149
|
+
const result = await getBalance();
|
|
1150
|
+
if (result) {
|
|
1151
|
+
setData(result);
|
|
1152
|
+
setStatus("loaded");
|
|
1153
|
+
} else {
|
|
1154
|
+
setStatus("error");
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
react.useEffect(() => {
|
|
1158
|
+
void load();
|
|
1159
|
+
}, []);
|
|
1160
|
+
const isLoading = status === "loading";
|
|
1161
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-bal-modal", "data-theme": theme, style: cssVars, onClick: (e) => e.stopPropagation(), children: [
|
|
1162
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
|
|
1163
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Wallet Balance" }),
|
|
1164
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
|
|
1165
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-modal-refresh-btn", onClick: load, disabled: isLoading, children: [
|
|
1166
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1167
|
+
"svg",
|
|
1168
|
+
{
|
|
1169
|
+
className: `pollar-modal-refresh-icon${isLoading ? " spinning" : ""}`,
|
|
1170
|
+
width: "13",
|
|
1171
|
+
height: "13",
|
|
1172
|
+
viewBox: "0 0 13 13",
|
|
1173
|
+
fill: "none",
|
|
1174
|
+
"aria-hidden": true,
|
|
1175
|
+
children: [
|
|
1176
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M11.5 6.5a5 5 0 11-1.5-3.536", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }),
|
|
1177
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 1v3h-3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
1178
|
+
]
|
|
1179
|
+
}
|
|
1180
|
+
),
|
|
1181
|
+
"Refresh"
|
|
1182
|
+
] }),
|
|
1183
|
+
/* @__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" }) }) })
|
|
1184
|
+
] })
|
|
1185
|
+
] }),
|
|
1186
|
+
walletAddress && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-bal-address", children: cropAddress(walletAddress) }),
|
|
1187
|
+
isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "Loading\u2026" }),
|
|
1188
|
+
status === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: "Failed to load balances. Check your connection." }),
|
|
1189
|
+
status === "loaded" && data && !data.exists && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-empty", children: [
|
|
1190
|
+
"Account not found on ",
|
|
1191
|
+
data.network,
|
|
1192
|
+
"."
|
|
1193
|
+
] }),
|
|
1194
|
+
status === "loaded" && data?.exists && data.balances.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No balances found." }),
|
|
1195
|
+
status === "loaded" && data?.exists && data.balances.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-bal-list", children: data.balances.map((b) => /* @__PURE__ */ jsxRuntime.jsx(BalanceItem, { record: b }, b.code + (b.issuer ?? ""))) }),
|
|
1196
|
+
/* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
|
|
1197
|
+
] }) });
|
|
1198
|
+
}
|
|
593
1199
|
var emptyResponse = {
|
|
594
1200
|
application: {
|
|
595
1201
|
name: ""
|
|
596
1202
|
},
|
|
597
1203
|
styles: {}
|
|
598
1204
|
};
|
|
599
|
-
async function fetchRemoteConfig(
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
if (!data || error) {
|
|
603
|
-
return emptyResponse;
|
|
604
|
-
}
|
|
605
|
-
return data.content;
|
|
606
|
-
} catch {
|
|
607
|
-
return emptyResponse;
|
|
608
|
-
}
|
|
1205
|
+
async function fetchRemoteConfig(client) {
|
|
1206
|
+
const content = await client.getAppConfig();
|
|
1207
|
+
return content ?? emptyResponse;
|
|
609
1208
|
}
|
|
610
1209
|
var PollarContext = react.createContext(null);
|
|
611
1210
|
function PollarProvider({ config, styles: propStyles, children }) {
|
|
612
1211
|
const [pollarClient] = react.useState(() => new core.PollarClient(config));
|
|
613
|
-
const [
|
|
1212
|
+
const [networkState, setNetworkState] = react.useState(() => pollarClient.getNetworkState());
|
|
1213
|
+
const stellarClient = react.useMemo(() => {
|
|
1214
|
+
const network = networkState.step === "connected" ? networkState.network : "testnet";
|
|
1215
|
+
return new core.StellarClient(network);
|
|
1216
|
+
}, [networkState]);
|
|
614
1217
|
const [sessionState, setSessionState] = react.useState(null);
|
|
615
|
-
const [
|
|
616
|
-
|
|
617
|
-
var: "network",
|
|
618
|
-
code: core.STATE_VAR_CODES.network.NONE,
|
|
619
|
-
status: core.StateStatus.NONE,
|
|
620
|
-
level: "info",
|
|
621
|
-
ts: 0
|
|
622
|
-
},
|
|
623
|
-
authentication: {
|
|
624
|
-
var: "authentication",
|
|
625
|
-
code: core.STATE_VAR_CODES.authentication.NONE,
|
|
626
|
-
status: core.StateStatus.NONE,
|
|
627
|
-
level: "info",
|
|
628
|
-
ts: 0
|
|
629
|
-
},
|
|
630
|
-
transaction: {
|
|
631
|
-
var: "transaction",
|
|
632
|
-
code: core.STATE_VAR_CODES.transaction.NONE,
|
|
633
|
-
status: core.StateStatus.NONE,
|
|
634
|
-
level: "info",
|
|
635
|
-
ts: 0
|
|
636
|
-
}
|
|
637
|
-
});
|
|
1218
|
+
const [transaction, setTransaction] = react.useState({ step: "idle" });
|
|
1219
|
+
const [txHistory, setTxHistory] = react.useState({ step: "idle" });
|
|
638
1220
|
const [remoteConfig, setRemoteConfig] = react.useState(emptyResponse);
|
|
639
1221
|
const [styles, setStyles] = react.useState(propStyles ?? {});
|
|
640
1222
|
react.useEffect(() => {
|
|
641
|
-
return pollarClient.
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
return prevState;
|
|
658
|
-
});
|
|
659
|
-
}
|
|
660
|
-
if (stateEntry.code === core.STATE_VAR_CODES.authentication.LOGOUT) {
|
|
661
|
-
setSessionState(null);
|
|
662
|
-
}
|
|
1223
|
+
return pollarClient.onTransactionStateChange(setTransaction);
|
|
1224
|
+
}, [pollarClient]);
|
|
1225
|
+
react.useEffect(() => {
|
|
1226
|
+
return pollarClient.onTxHistoryStateChange(setTxHistory);
|
|
1227
|
+
}, [pollarClient]);
|
|
1228
|
+
react.useEffect(() => {
|
|
1229
|
+
return pollarClient.onNetworkStateChange((state) => {
|
|
1230
|
+
setNetworkState(state);
|
|
1231
|
+
});
|
|
1232
|
+
}, [pollarClient]);
|
|
1233
|
+
react.useEffect(() => {
|
|
1234
|
+
return pollarClient.onAuthStateChange((authState) => {
|
|
1235
|
+
if (authState.step === "authenticated") {
|
|
1236
|
+
setSessionState((prev) => JSON.stringify(prev) !== JSON.stringify(authState.session) ? authState.session : prev);
|
|
1237
|
+
} else if (authState.step === "idle") {
|
|
1238
|
+
setSessionState(null);
|
|
663
1239
|
}
|
|
664
1240
|
});
|
|
665
1241
|
}, [pollarClient]);
|
|
666
1242
|
react.useEffect(() => {
|
|
667
|
-
fetchRemoteConfig(pollarClient
|
|
1243
|
+
fetchRemoteConfig(pollarClient).then((fetched) => {
|
|
668
1244
|
setRemoteConfig(fetched);
|
|
669
1245
|
setStyles({
|
|
670
1246
|
...fetched.styles,
|
|
@@ -675,43 +1251,62 @@ function PollarProvider({ config, styles: propStyles, children }) {
|
|
|
675
1251
|
setStyles(propStyles ?? {});
|
|
676
1252
|
});
|
|
677
1253
|
}, [pollarClient]);
|
|
1254
|
+
react.useEffect(() => {
|
|
1255
|
+
if (transaction.step !== "idle") {
|
|
1256
|
+
setTransactionModalOpen(true);
|
|
1257
|
+
}
|
|
1258
|
+
}, [transaction.step]);
|
|
678
1259
|
const [loginModalOpen, setLoginModalOpen] = react.useState(false);
|
|
679
1260
|
const [transactionModalOpen, setTransactionModalOpen] = react.useState(false);
|
|
1261
|
+
const [kycModalOpen, setKycModalOpen] = react.useState(false);
|
|
1262
|
+
const [kycModalOptions, setKycModalOptions] = react.useState({});
|
|
1263
|
+
const [rampWidgetOpen, setRampWidgetOpen] = react.useState(false);
|
|
1264
|
+
const [txHistoryModalOpen, setTxHistoryModalOpen] = react.useState(false);
|
|
1265
|
+
const [walletBalanceModalOpen, setWalletBalanceModalOpen] = react.useState(false);
|
|
680
1266
|
const contextValue = react.useMemo(
|
|
681
1267
|
() => ({
|
|
682
1268
|
walletAddress: sessionState?.wallet?.publicKey || "",
|
|
683
1269
|
getClient: () => pollarClient,
|
|
684
|
-
|
|
685
|
-
state,
|
|
1270
|
+
transaction,
|
|
686
1271
|
login: (options) => pollarClient.login(options),
|
|
687
1272
|
logout: () => pollarClient.logout(),
|
|
688
|
-
isAuthenticated:
|
|
1273
|
+
isAuthenticated: !!sessionState?.wallet?.publicKey,
|
|
689
1274
|
buildTx: (operation, params, options) => pollarClient.buildTx(operation, params, options),
|
|
690
|
-
|
|
691
|
-
// react
|
|
692
|
-
sendTransaction: (operation, params, options) => {
|
|
693
|
-
void pollarClient.buildTx(operation, params, options);
|
|
694
|
-
setTransactionModalOpen(true);
|
|
695
|
-
},
|
|
1275
|
+
signAndSubmitTx: (signedXdr) => pollarClient.signAndSubmitTx(signedXdr),
|
|
696
1276
|
openTransactionModal: () => setTransactionModalOpen(true),
|
|
697
1277
|
openLoginModal: () => setLoginModalOpen(true),
|
|
1278
|
+
openKycModal: (options = {}) => {
|
|
1279
|
+
setKycModalOptions(options);
|
|
1280
|
+
setKycModalOpen(true);
|
|
1281
|
+
},
|
|
1282
|
+
openRampWidget: () => setRampWidgetOpen(true),
|
|
1283
|
+
txHistory,
|
|
1284
|
+
openTxHistoryModal: () => setTxHistoryModalOpen(true),
|
|
1285
|
+
openWalletBalanceModal: () => setWalletBalanceModalOpen(true),
|
|
1286
|
+
network: networkState.step === "connected" ? networkState.network : "testnet",
|
|
1287
|
+
setNetwork: (network) => pollarClient.setNetwork(network),
|
|
698
1288
|
config: remoteConfig,
|
|
699
1289
|
styles,
|
|
700
|
-
|
|
701
|
-
async getBalance(publicKey) {
|
|
702
|
-
const pk = publicKey || sessionState?.wallet?.publicKey;
|
|
703
|
-
if (pk) {
|
|
704
|
-
return await stellarClient.getBalances(pk);
|
|
705
|
-
}
|
|
706
|
-
return { success: false, errorCode: "NO_WALLET_FOUND", balances: [] };
|
|
707
|
-
}
|
|
1290
|
+
getBalance: (publicKey) => pollarClient.getWalletBalance(publicKey)
|
|
708
1291
|
}),
|
|
709
|
-
[sessionState, remoteConfig, styles, pollarClient,
|
|
1292
|
+
[sessionState, remoteConfig, styles, pollarClient, transaction, txHistory, networkState, stellarClient]
|
|
710
1293
|
);
|
|
711
1294
|
return /* @__PURE__ */ jsxRuntime.jsxs(PollarContext.Provider, { value: contextValue, children: [
|
|
712
1295
|
children,
|
|
713
1296
|
loginModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setLoginModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(LoginModal, { onClose: () => setLoginModalOpen(false) }) }),
|
|
714
|
-
transactionModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setTransactionModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(TransactionModal, { onClose: () => setTransactionModalOpen(false) }) })
|
|
1297
|
+
transactionModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setTransactionModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(TransactionModal, { onClose: () => setTransactionModalOpen(false) }) }),
|
|
1298
|
+
kycModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setKycModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1299
|
+
KycModal,
|
|
1300
|
+
{
|
|
1301
|
+
onClose: () => setKycModalOpen(false),
|
|
1302
|
+
...kycModalOptions.country !== void 0 && { country: kycModalOptions.country },
|
|
1303
|
+
...kycModalOptions.level !== void 0 && { level: kycModalOptions.level },
|
|
1304
|
+
...kycModalOptions.onApproved !== void 0 && { onApproved: kycModalOptions.onApproved }
|
|
1305
|
+
}
|
|
1306
|
+
) }),
|
|
1307
|
+
rampWidgetOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setRampWidgetOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(RampWidget, { onClose: () => setRampWidgetOpen(false) }) }),
|
|
1308
|
+
txHistoryModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setTxHistoryModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(TxHistoryModal, { onClose: () => setTxHistoryModalOpen(false) }) }),
|
|
1309
|
+
walletBalanceModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setWalletBalanceModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(WalletBalanceModal, { onClose: () => setWalletBalanceModalOpen(false) }) })
|
|
715
1310
|
] });
|
|
716
1311
|
}
|
|
717
1312
|
function usePollar() {
|
|
@@ -729,7 +1324,7 @@ function ButtonLogo() {
|
|
|
729
1324
|
return /* @__PURE__ */ jsxRuntime.jsx("img", { src: LOGO_POLLAR, alt: "Pollar", width: 22, height: 22, className: "wallet-btn-logo" });
|
|
730
1325
|
}
|
|
731
1326
|
function WalletButton() {
|
|
732
|
-
const { getClient, walletAddress, styles, openLoginModal } = usePollar();
|
|
1327
|
+
const { getClient, walletAddress, styles, openLoginModal, openTxHistoryModal, openWalletBalanceModal } = usePollar();
|
|
733
1328
|
const [open, setOpen] = react.useState(false);
|
|
734
1329
|
const [copied, setCopied] = react.useState(false);
|
|
735
1330
|
const wrapperRef = react.useRef(null);
|
|
@@ -801,6 +1396,72 @@ function WalletButton() {
|
|
|
801
1396
|
),
|
|
802
1397
|
copied ? "Copied!" : "Copy address"
|
|
803
1398
|
] }),
|
|
1399
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1400
|
+
"button",
|
|
1401
|
+
{
|
|
1402
|
+
className: "wallet-dropdown-item",
|
|
1403
|
+
style: { color: itemColor },
|
|
1404
|
+
onClick: () => {
|
|
1405
|
+
setOpen(false);
|
|
1406
|
+
openWalletBalanceModal();
|
|
1407
|
+
},
|
|
1408
|
+
children: [
|
|
1409
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1410
|
+
"svg",
|
|
1411
|
+
{
|
|
1412
|
+
width: "14",
|
|
1413
|
+
height: "14",
|
|
1414
|
+
viewBox: "0 0 24 24",
|
|
1415
|
+
fill: "none",
|
|
1416
|
+
stroke: "currentColor",
|
|
1417
|
+
strokeWidth: "2",
|
|
1418
|
+
strokeLinecap: "round",
|
|
1419
|
+
strokeLinejoin: "round",
|
|
1420
|
+
children: [
|
|
1421
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "1", y: "4", width: "22", height: "16", rx: "2", ry: "2" }),
|
|
1422
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "16", cy: "12", r: "2" }),
|
|
1423
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M22 8H12" })
|
|
1424
|
+
]
|
|
1425
|
+
}
|
|
1426
|
+
),
|
|
1427
|
+
"Wallet balance"
|
|
1428
|
+
]
|
|
1429
|
+
}
|
|
1430
|
+
),
|
|
1431
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1432
|
+
"button",
|
|
1433
|
+
{
|
|
1434
|
+
className: "wallet-dropdown-item",
|
|
1435
|
+
style: { color: itemColor },
|
|
1436
|
+
onClick: () => {
|
|
1437
|
+
setOpen(false);
|
|
1438
|
+
openTxHistoryModal();
|
|
1439
|
+
},
|
|
1440
|
+
children: [
|
|
1441
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1442
|
+
"svg",
|
|
1443
|
+
{
|
|
1444
|
+
width: "14",
|
|
1445
|
+
height: "14",
|
|
1446
|
+
viewBox: "0 0 24 24",
|
|
1447
|
+
fill: "none",
|
|
1448
|
+
stroke: "currentColor",
|
|
1449
|
+
strokeWidth: "2",
|
|
1450
|
+
strokeLinecap: "round",
|
|
1451
|
+
strokeLinejoin: "round",
|
|
1452
|
+
children: [
|
|
1453
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
|
|
1454
|
+
/* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "14,2 14,8 20,8" }),
|
|
1455
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "16", y1: "13", x2: "8", y2: "13" }),
|
|
1456
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "16", y1: "17", x2: "8", y2: "17" }),
|
|
1457
|
+
/* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "10,9 9,9 8,9" })
|
|
1458
|
+
]
|
|
1459
|
+
}
|
|
1460
|
+
),
|
|
1461
|
+
"Transaction history"
|
|
1462
|
+
]
|
|
1463
|
+
}
|
|
1464
|
+
),
|
|
804
1465
|
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "wallet-dropdown-item danger", onClick: handleLogout, children: [
|
|
805
1466
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
806
1467
|
"svg",
|
|
@@ -826,7 +1487,11 @@ function WalletButton() {
|
|
|
826
1487
|
] });
|
|
827
1488
|
}
|
|
828
1489
|
|
|
1490
|
+
exports.KycModal = KycModal;
|
|
1491
|
+
exports.KycStatus = KycStatus;
|
|
829
1492
|
exports.PollarProvider = PollarProvider;
|
|
1493
|
+
exports.RampWidget = RampWidget;
|
|
1494
|
+
exports.RouteDisplay = RouteDisplay;
|
|
830
1495
|
exports.WalletButton = WalletButton;
|
|
831
1496
|
exports.usePollar = usePollar;
|
|
832
1497
|
//# sourceMappingURL=index.js.map
|