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