@pollar/react 0.3.9 → 0.4.1
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 +245 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +7 -3
- package/dist/index.d.ts +7 -3
- package/dist/index.js +333 -81
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +335 -83
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12,6 +12,97 @@ var LOGO_POLLAR = "https://pollar.xyz/assets/logo_pollar.png";
|
|
|
12
12
|
var LOGO_GITHUB = "https://pollar.xyz/assets/GitHub_Invertocat_White.png";
|
|
13
13
|
var LOGO_FREIGHTER = "https://pollar.xyz/assets/logo_freighter.png";
|
|
14
14
|
var LOGO_ALBEDO = "https://pollar.xyz/assets/logo_albedo.svg";
|
|
15
|
+
var ModalErrorBoundary = class extends react.Component {
|
|
16
|
+
constructor() {
|
|
17
|
+
super(...arguments);
|
|
18
|
+
this.state = { crashed: false };
|
|
19
|
+
}
|
|
20
|
+
static getDerivedStateFromError() {
|
|
21
|
+
return { crashed: true };
|
|
22
|
+
}
|
|
23
|
+
componentDidCatch(error) {
|
|
24
|
+
console.error("[Pollar] Modal crashed:", error);
|
|
25
|
+
}
|
|
26
|
+
render() {
|
|
27
|
+
if (this.state.crashed) {
|
|
28
|
+
this.props.onClose();
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return this.props.children;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
var PollarModalFooter = () => {
|
|
35
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-footer", children: [
|
|
36
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-footer-protected", children: "Protected by" }),
|
|
37
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-footer-brand", children: [
|
|
38
|
+
/* @__PURE__ */ jsxRuntime.jsx("img", { src: LOGO_POLLAR, alt: "Pollar", className: "pollar-footer-logo" }),
|
|
39
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-footer-name", children: "Pollar" }),
|
|
40
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-footer-version", children: [
|
|
41
|
+
"v",
|
|
42
|
+
"0.4.1"
|
|
43
|
+
] })
|
|
44
|
+
] })
|
|
45
|
+
] });
|
|
46
|
+
};
|
|
47
|
+
var LOGIN_CODE_MESSAGES = {
|
|
48
|
+
NONE: { text: "" },
|
|
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
|
+
RESTORED_SESSION_SUCCESS: { text: "Session restored" },
|
|
73
|
+
RESTORED_SESSION_ERROR: { text: "Failed to restore session" },
|
|
74
|
+
SESSION_STORED: { text: "Session saved" },
|
|
75
|
+
ERROR_UNKNOWN: { text: "Something went wrong" },
|
|
76
|
+
ABORTED: { text: "Login cancelled" },
|
|
77
|
+
// transaction
|
|
78
|
+
BUILD_TRANSACTION_START: { text: "Building transaction\u2026" },
|
|
79
|
+
BUILD_TRANSACTION_SUCCESS: { text: "Transaction built, ready to sign and send" },
|
|
80
|
+
BUILD_TRANSACTION_ERROR: { text: "Failed to build transaction" },
|
|
81
|
+
BUILD_TRANSACTION_ERROR_NO_WALLET: { text: "No wallet connected" },
|
|
82
|
+
SIGN_SEND_TRANSACTION_START: { text: "Signing and sending transaction\u2026" },
|
|
83
|
+
SIGN_SEND_TRANSACTION_SUCCESS: { text: "Transaction signed" },
|
|
84
|
+
SIGN_SEND_TRANSACTION_ERROR: { text: "Signing rejected" }
|
|
85
|
+
};
|
|
86
|
+
function ModalStatusBanner({ code, status, onCancel, onRetry }) {
|
|
87
|
+
if (!code) {
|
|
88
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-status" });
|
|
89
|
+
}
|
|
90
|
+
const { text } = LOGIN_CODE_MESSAGES[code] || { text: "" };
|
|
91
|
+
const isLoading = status === "LOADING";
|
|
92
|
+
const icon = status === "ERROR" ? /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
|
|
93
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
|
|
94
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4.5 4.5l5 5M9.5 4.5l-5 5", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
95
|
+
] }) : status === "SUCCESS" ? /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
|
|
96
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
|
|
97
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3.5 7l2.5 2.5 4.5-5", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
98
|
+
] }) : 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;
|
|
99
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-status", "data-kind": status, children: [
|
|
100
|
+
icon,
|
|
101
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: text }),
|
|
102
|
+
isLoading && onCancel && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-status-cancel", onClick: onCancel, children: "Cancel" }),
|
|
103
|
+
status === core.StateStatus.ERROR && onRetry && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-status-cancel", onClick: onRetry, children: "Retry" })
|
|
104
|
+
] });
|
|
105
|
+
}
|
|
15
106
|
function EmailCodeInput({ email, onSubmit }) {
|
|
16
107
|
const [digits, setDigits] = react.useState(["", "", "", "", "", ""]);
|
|
17
108
|
const inputRefs = react.useRef([]);
|
|
@@ -118,51 +209,6 @@ var GoogleButton = ({ disabled, onClick }) => {
|
|
|
118
209
|
] })
|
|
119
210
|
] });
|
|
120
211
|
};
|
|
121
|
-
var LOGIN_CODE_MESSAGES = {
|
|
122
|
-
LOGOUT: { text: "Logged out" },
|
|
123
|
-
CREATE_SESSION_START: { text: "Starting session\u2026" },
|
|
124
|
-
CREATE_SESSION_ERROR: { text: "Failed to start session" },
|
|
125
|
-
CREATE_SESSION_SUCCESS: { text: "Session ready" },
|
|
126
|
-
EMAIL_AUTH_START: { text: "Sending code\u2026" },
|
|
127
|
-
EMAIL_AUTH_START_ERROR: { text: "Failed to send code" },
|
|
128
|
-
EMAIL_AUTH_START_SUCCESS: { text: "Code sent \u2014 check your inbox" },
|
|
129
|
-
EMAIL_AUTH_CODE_ERROR: { text: "Invalid code \u2014 try again" },
|
|
130
|
-
EMAIL_AUTH_CODE_SUCCESS: { text: "Code verified!" },
|
|
131
|
-
WALLET_AUTH_START: { text: "Connecting wallet\u2026" },
|
|
132
|
-
WALLET_AUTH_FREIGHTER_NOT_INSTALLED: { text: "Freighter is not installed" },
|
|
133
|
-
WALLET_AUTH_ALBEDO_NOT_INSTALLED: { text: "Albedo is not installed" },
|
|
134
|
-
WALLET_AUTH_CONNECTED: { text: "Wallet connected" },
|
|
135
|
-
WALLET_AUTH_LOGIN_START: { text: "Signing in with wallet\u2026" },
|
|
136
|
-
WALLET_AUTH_LOGIN_START_SUCCESS: { text: "Wallet signed in" },
|
|
137
|
-
WALLET_AUTH_LOGIN_START_ERROR: { text: "Failed to sign in with wallet" },
|
|
138
|
-
WALLET_AUTH_ERROR: { text: "Unknow wallet error" },
|
|
139
|
-
STREAM_POLL_START: { text: "Waiting for authentication\u2026" },
|
|
140
|
-
STREAM_POLL_EVENT: { text: "Waiting for authentication\u2026" },
|
|
141
|
-
STREAM_POLL_READY: { text: "Authenticated!" },
|
|
142
|
-
FETCH_SESSION_START: { text: "Loading session\u2026" },
|
|
143
|
-
FETCH_SESSION_SUCCESS: { text: "Welcome back!" },
|
|
144
|
-
FETCH_SESSION_ERROR: { text: "Failed to load session" },
|
|
145
|
-
ERROR_UNKNOWN: { text: "Something went wrong" },
|
|
146
|
-
ABORTED: { text: "Login cancelled" }
|
|
147
|
-
};
|
|
148
|
-
function LoginStatusBanner({ code, status, onCancel, onRetry }) {
|
|
149
|
-
if (!code) return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-status" });
|
|
150
|
-
const { text } = LOGIN_CODE_MESSAGES[code] || { text: "" };
|
|
151
|
-
const isLoading = status === core.StateStatus.LOADING;
|
|
152
|
-
const icon = status === core.StateStatus.ERROR ? /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
|
|
153
|
-
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
|
|
154
|
-
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4.5 4.5l5 5M9.5 4.5l-5 5", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
155
|
-
] }) : status === core.StateStatus.SUCCESS ? /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
|
|
156
|
-
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
|
|
157
|
-
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3.5 7l2.5 2.5 4.5-5", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
158
|
-
] }) : status === core.StateStatus.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;
|
|
159
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-status", "data-kind": status, children: [
|
|
160
|
-
icon,
|
|
161
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: text }),
|
|
162
|
-
isLoading && onCancel && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-status-cancel", onClick: onCancel, children: "Cancel" }),
|
|
163
|
-
status === core.StateStatus.ERROR && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-status-cancel", onClick: onRetry, children: "Retry" })
|
|
164
|
-
] });
|
|
165
|
-
}
|
|
166
212
|
function LoginModalTemplate({
|
|
167
213
|
theme,
|
|
168
214
|
accentColor,
|
|
@@ -245,22 +291,12 @@ function LoginModalTemplate({
|
|
|
245
291
|
] })
|
|
246
292
|
] })
|
|
247
293
|
] }),
|
|
248
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
249
|
-
/* @__PURE__ */ jsxRuntime.
|
|
250
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-footer-protected", children: "Protected by" }),
|
|
251
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-footer-brand", children: [
|
|
252
|
-
/* @__PURE__ */ jsxRuntime.jsx("img", { src: LOGO_POLLAR, alt: "Pollar", className: "pollar-footer-logo" }),
|
|
253
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-footer-name", children: "Pollar" }),
|
|
254
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-footer-version", children: [
|
|
255
|
-
"v",
|
|
256
|
-
"0.3.9"
|
|
257
|
-
] })
|
|
258
|
-
] })
|
|
259
|
-
] })
|
|
294
|
+
/* @__PURE__ */ jsxRuntime.jsx(ModalStatusBanner, { code: loginStateCode, status, onCancel: () => cancelLoginRef.current?.(), onRetry }),
|
|
295
|
+
/* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
|
|
260
296
|
] });
|
|
261
297
|
}
|
|
262
298
|
function isLoginCode(code) {
|
|
263
|
-
return Object.values(core.STATE_VAR_CODES[core.PollarStateVar.
|
|
299
|
+
return Object.values(core.STATE_VAR_CODES[core.PollarStateVar.AUTHENTICATION]).includes(code);
|
|
264
300
|
}
|
|
265
301
|
function LoginModal({ onClose }) {
|
|
266
302
|
const [email, setEmail] = react.useState("");
|
|
@@ -272,20 +308,20 @@ function LoginModal({ onClose }) {
|
|
|
272
308
|
const [clientSessionId, setClientSessionId] = react.useState(null);
|
|
273
309
|
react.useEffect(() => {
|
|
274
310
|
return getClient().onStateChange((stateEntry) => {
|
|
275
|
-
if (stateEntry.var === core.PollarStateVar.
|
|
311
|
+
if (stateEntry.var === core.PollarStateVar.AUTHENTICATION && isLoginCode(stateEntry.code)) {
|
|
276
312
|
setLoginStateCode(stateEntry.code);
|
|
277
313
|
setStatus(stateEntry.status);
|
|
278
|
-
if (stateEntry.code === core.STATE_VAR_CODES[core.PollarStateVar.
|
|
314
|
+
if (stateEntry.code === core.STATE_VAR_CODES[core.PollarStateVar.AUTHENTICATION].STREAM_POLL_START) {
|
|
279
315
|
const data = stateEntry.data;
|
|
280
316
|
setClientSessionId(data.clientSessionId);
|
|
281
317
|
}
|
|
282
|
-
if (stateEntry.code === core.STATE_VAR_CODES[core.PollarStateVar.
|
|
318
|
+
if (stateEntry.code === core.STATE_VAR_CODES[core.PollarStateVar.AUTHENTICATION].STREAM_POLL_EVENT) {
|
|
283
319
|
const data = stateEntry.data;
|
|
284
320
|
if (data?.status === "AWAITING_EMAIL") {
|
|
285
321
|
setAwaitingEmailCode(true);
|
|
286
322
|
}
|
|
287
323
|
}
|
|
288
|
-
if (stateEntry.code === core.STATE_VAR_CODES[core.PollarStateVar.
|
|
324
|
+
if (stateEntry.code === core.STATE_VAR_CODES[core.PollarStateVar.AUTHENTICATION].FETCH_SESSION_SUCCESS) {
|
|
289
325
|
setAwaitingEmailCode(false);
|
|
290
326
|
setTimeout(onClose, 1e3);
|
|
291
327
|
}
|
|
@@ -355,6 +391,203 @@ function LoginModal({ onClose }) {
|
|
|
355
391
|
}
|
|
356
392
|
) });
|
|
357
393
|
}
|
|
394
|
+
function TransactionModalTemplate({
|
|
395
|
+
theme,
|
|
396
|
+
accentColor,
|
|
397
|
+
transactionStateCode,
|
|
398
|
+
status,
|
|
399
|
+
buildResult,
|
|
400
|
+
submitResult,
|
|
401
|
+
onClose,
|
|
402
|
+
onSignAndSend,
|
|
403
|
+
onRetrySignAndSend
|
|
404
|
+
}) {
|
|
405
|
+
const isDark = theme === "dark";
|
|
406
|
+
const cssVars = {
|
|
407
|
+
"--pollar-accent": accentColor,
|
|
408
|
+
"--pollar-buttons-border-radius": "8px",
|
|
409
|
+
"--pollar-buttons-height": "44px",
|
|
410
|
+
"--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
|
|
411
|
+
"--pollar-border": isDark ? "#374151" : "#e5e7eb",
|
|
412
|
+
"--pollar-text": isDark ? "#ffffff" : "#111827",
|
|
413
|
+
"--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
|
|
414
|
+
"--pollar-input-bg": isDark ? "#374151" : "rgba(0,0,0,0.04)",
|
|
415
|
+
"--pollar-error-text": isDark ? "#f87171" : "#dc2626",
|
|
416
|
+
"--pollar-success-text": isDark ? "#4ade80" : "#16a34a"
|
|
417
|
+
};
|
|
418
|
+
const [showXdr, setShowXdr] = react.useState(false);
|
|
419
|
+
const [copied, setCopied] = react.useState(false);
|
|
420
|
+
function handleCopyHash() {
|
|
421
|
+
if (!submitResult) return;
|
|
422
|
+
navigator.clipboard.writeText(submitResult.hash).then(() => {
|
|
423
|
+
setCopied(true);
|
|
424
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
const explorerNetwork = buildResult?.summary.network?.toLowerCase().includes("testnet") ? "testnet" : "public";
|
|
428
|
+
const explorerUrl = submitResult ? `https://stellar.expert/explorer/${explorerNetwork}/tx/${submitResult.hash}` : null;
|
|
429
|
+
transactionStateCode.includes("ERROR");
|
|
430
|
+
transactionStateCode.includes("SUCCESS");
|
|
431
|
+
const isBuilt = buildResult && transactionStateCode === "BUILD_TRANSACTION_SUCCESS";
|
|
432
|
+
const isDone = submitResult && transactionStateCode === "SIGN_SEND_TRANSACTION_START";
|
|
433
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-modal", "data-theme": theme, style: cssVars, onClick: (e) => e.stopPropagation(), children: [
|
|
434
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-header", children: [
|
|
435
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-tx-title", children: "Transaction" }),
|
|
436
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-tx-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" }) }) })
|
|
437
|
+
] }),
|
|
438
|
+
isBuilt && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
439
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-summary", children: [
|
|
440
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "pollar-tx-summary-title", children: "Details" }),
|
|
441
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "pollar-tx-summary-lines", children: buildResult.summary.lines.map((line, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "pollar-tx-summary-line", children: line }, i)) })
|
|
442
|
+
] }),
|
|
443
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-meta", children: [
|
|
444
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-meta-item", children: [
|
|
445
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-tx-meta-label", children: "Network" }),
|
|
446
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-tx-meta-value", children: buildResult.summary.network })
|
|
447
|
+
] }),
|
|
448
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-meta-item", children: [
|
|
449
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-tx-meta-label", children: "Fee" }),
|
|
450
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-tx-meta-value", children: buildResult.summary.fee })
|
|
451
|
+
] })
|
|
452
|
+
] }),
|
|
453
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-xdr", children: [
|
|
454
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-tx-xdr-toggle", onClick: () => setShowXdr((v) => !v), children: [
|
|
455
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
456
|
+
"svg",
|
|
457
|
+
{
|
|
458
|
+
width: "12",
|
|
459
|
+
height: "12",
|
|
460
|
+
viewBox: "0 0 12 12",
|
|
461
|
+
fill: "none",
|
|
462
|
+
"aria-hidden": true,
|
|
463
|
+
style: { transform: showXdr ? "rotate(90deg)" : "rotate(0deg)", transition: "transform 150ms" },
|
|
464
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4 2l4 4-4 4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
465
|
+
}
|
|
466
|
+
),
|
|
467
|
+
"Raw transaction (XDR)"
|
|
468
|
+
] }),
|
|
469
|
+
showXdr && /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "pollar-tx-xdr-content", children: buildResult.unsignedXdr })
|
|
470
|
+
] })
|
|
471
|
+
] }),
|
|
472
|
+
submitResult && transactionStateCode === "SIGN_SEND_TRANSACTION_SUCCESS" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-result", children: [
|
|
473
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-tx-result-label", children: "Transaction hash" }),
|
|
474
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-tx-result-hash", children: submitResult.hash }),
|
|
475
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-result-actions", children: [
|
|
476
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-tx-result-btn", onClick: handleCopyHash, children: copied ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
477
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
|
|
478
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
|
|
479
|
+
/* @__PURE__ */ jsxRuntime.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
|
+
)
|
|
489
|
+
] }),
|
|
490
|
+
"Copied!"
|
|
491
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
492
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
|
|
493
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1.5", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
494
|
+
/* @__PURE__ */ jsxRuntime.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
|
+
)
|
|
503
|
+
] }),
|
|
504
|
+
"Copy hash"
|
|
505
|
+
] }) }),
|
|
506
|
+
explorerUrl && /* @__PURE__ */ jsxRuntime.jsxs("a", { className: "pollar-tx-result-btn", href: explorerUrl, target: "_blank", rel: "noopener noreferrer", children: [
|
|
507
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
|
|
508
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
509
|
+
"path",
|
|
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__ */ jsxRuntime.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
|
+
)
|
|
527
|
+
] }),
|
|
528
|
+
"View on Explorer"
|
|
529
|
+
] })
|
|
530
|
+
] })
|
|
531
|
+
] }),
|
|
532
|
+
isBuilt && /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-tx-sign-btn", onClick: onSignAndSend, children: "Sign & Send" }),
|
|
533
|
+
isDone && /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-tx-sign-btn", onClick: onClose, children: "Done" }),
|
|
534
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
535
|
+
ModalStatusBanner,
|
|
536
|
+
{
|
|
537
|
+
code: transactionStateCode,
|
|
538
|
+
status
|
|
539
|
+
}
|
|
540
|
+
),
|
|
541
|
+
/* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
|
|
542
|
+
] });
|
|
543
|
+
}
|
|
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
|
+
function TransactionModal({ onClose }) {
|
|
555
|
+
const {
|
|
556
|
+
getClient,
|
|
557
|
+
styles,
|
|
558
|
+
state: { transaction }
|
|
559
|
+
} = usePollar();
|
|
560
|
+
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
|
+
async function handleSignAndSend() {
|
|
572
|
+
if (buildResult) {
|
|
573
|
+
await getClient().submitTx(buildResult.unsignedXdr);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
577
|
+
TransactionModalTemplate,
|
|
578
|
+
{
|
|
579
|
+
theme,
|
|
580
|
+
accentColor,
|
|
581
|
+
transactionStateCode,
|
|
582
|
+
status: transaction.status,
|
|
583
|
+
buildResult,
|
|
584
|
+
submitResult,
|
|
585
|
+
onClose,
|
|
586
|
+
onSignAndSend: handleSignAndSend,
|
|
587
|
+
onRetrySignAndSend: handleSignAndSend
|
|
588
|
+
}
|
|
589
|
+
) });
|
|
590
|
+
}
|
|
358
591
|
var emptyResponse = {
|
|
359
592
|
application: {
|
|
360
593
|
name: ""
|
|
@@ -363,7 +596,7 @@ var emptyResponse = {
|
|
|
363
596
|
};
|
|
364
597
|
async function fetchRemoteConfig(api) {
|
|
365
598
|
try {
|
|
366
|
-
const { data, error } = await api.GET(`/config`);
|
|
599
|
+
const { data, error } = await api.GET(`/applications/config`);
|
|
367
600
|
if (!data || error) {
|
|
368
601
|
return emptyResponse;
|
|
369
602
|
}
|
|
@@ -378,16 +611,23 @@ function PollarProvider({ config, styles: propStyles, children }) {
|
|
|
378
611
|
const [stellarClient] = react.useState(() => new core.StellarClient(config.stellarNetwork || "testnet"));
|
|
379
612
|
const [sessionState, setSessionState] = react.useState(null);
|
|
380
613
|
const [state, setState] = react.useState({
|
|
381
|
-
|
|
382
|
-
var:
|
|
383
|
-
code: core.STATE_VAR_CODES
|
|
614
|
+
network: {
|
|
615
|
+
var: "network",
|
|
616
|
+
code: core.STATE_VAR_CODES.network.NONE,
|
|
617
|
+
status: core.StateStatus.NONE,
|
|
618
|
+
level: "info",
|
|
619
|
+
ts: 0
|
|
620
|
+
},
|
|
621
|
+
authentication: {
|
|
622
|
+
var: "authentication",
|
|
623
|
+
code: core.STATE_VAR_CODES.authentication.NONE,
|
|
384
624
|
status: core.StateStatus.NONE,
|
|
385
625
|
level: "info",
|
|
386
626
|
ts: 0
|
|
387
627
|
},
|
|
388
|
-
|
|
389
|
-
var:
|
|
390
|
-
code: core.STATE_VAR_CODES
|
|
628
|
+
transaction: {
|
|
629
|
+
var: "transaction",
|
|
630
|
+
code: core.STATE_VAR_CODES.transaction.NONE,
|
|
391
631
|
status: core.StateStatus.NONE,
|
|
392
632
|
level: "info",
|
|
393
633
|
ts: 0
|
|
@@ -406,8 +646,8 @@ function PollarProvider({ config, styles: propStyles, children }) {
|
|
|
406
646
|
}
|
|
407
647
|
return prevState;
|
|
408
648
|
});
|
|
409
|
-
if (stateEntry.var ===
|
|
410
|
-
if (stateEntry.code === core.STATE_VAR_CODES
|
|
649
|
+
if (stateEntry.var === "authentication") {
|
|
650
|
+
if ((stateEntry.code === core.STATE_VAR_CODES.authentication.SESSION_STORED || core.STATE_VAR_CODES.authentication.RESTORED_SESSION_SUCCESS) && core.isValidSession(stateEntry.data)) {
|
|
411
651
|
setSessionState((prevState) => {
|
|
412
652
|
if (JSON.stringify(prevState) !== JSON.stringify(stateEntry.data)) {
|
|
413
653
|
return stateEntry.data;
|
|
@@ -415,9 +655,9 @@ function PollarProvider({ config, styles: propStyles, children }) {
|
|
|
415
655
|
return prevState;
|
|
416
656
|
});
|
|
417
657
|
}
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
658
|
+
if (stateEntry.code === core.STATE_VAR_CODES.authentication.LOGOUT) {
|
|
659
|
+
setSessionState(null);
|
|
660
|
+
}
|
|
421
661
|
}
|
|
422
662
|
});
|
|
423
663
|
}, [pollarClient]);
|
|
@@ -433,31 +673,43 @@ function PollarProvider({ config, styles: propStyles, children }) {
|
|
|
433
673
|
setStyles(propStyles ?? {});
|
|
434
674
|
});
|
|
435
675
|
}, [pollarClient]);
|
|
436
|
-
const [
|
|
676
|
+
const [loginModalOpen, setLoginModalOpen] = react.useState(false);
|
|
677
|
+
const [transactionModalOpen, setTransactionModalOpen] = react.useState(false);
|
|
437
678
|
const contextValue = react.useMemo(
|
|
438
679
|
() => ({
|
|
439
680
|
walletAddress: sessionState?.wallet?.publicKey || "",
|
|
440
681
|
getClient: () => pollarClient,
|
|
441
|
-
|
|
442
|
-
|
|
682
|
+
// client
|
|
683
|
+
state,
|
|
443
684
|
login: (options) => pollarClient.login(options),
|
|
444
685
|
logout: () => pollarClient.logout(),
|
|
686
|
+
isAuthenticated: pollarClient.isAuthenticated(),
|
|
687
|
+
buildTx: (operation, params, options) => pollarClient.buildTx(operation, params, options),
|
|
688
|
+
submitTx: (signedXdr) => pollarClient.submitTx(signedXdr),
|
|
689
|
+
// react
|
|
690
|
+
sendTransaction: (operation, params, options) => {
|
|
691
|
+
void pollarClient.buildTx(operation, params, options);
|
|
692
|
+
setTransactionModalOpen(true);
|
|
693
|
+
},
|
|
694
|
+
openTransactionModal: () => setTransactionModalOpen(true),
|
|
695
|
+
openLoginModal: () => setLoginModalOpen(true),
|
|
445
696
|
config: remoteConfig,
|
|
446
|
-
state,
|
|
447
697
|
styles,
|
|
698
|
+
// stellar
|
|
448
699
|
async getBalance(publicKey) {
|
|
449
700
|
const pk = publicKey || sessionState?.wallet?.publicKey;
|
|
450
701
|
if (pk) {
|
|
451
|
-
return stellarClient.getBalances(pk);
|
|
702
|
+
return await stellarClient.getBalances(pk);
|
|
452
703
|
}
|
|
453
|
-
return
|
|
704
|
+
return { success: false, errorCode: "NO_WALLET_FOUND", balances: [] };
|
|
454
705
|
}
|
|
455
706
|
}),
|
|
456
707
|
[sessionState, remoteConfig, styles, pollarClient, state]
|
|
457
708
|
);
|
|
458
709
|
return /* @__PURE__ */ jsxRuntime.jsxs(PollarContext.Provider, { value: contextValue, children: [
|
|
459
710
|
children,
|
|
460
|
-
|
|
711
|
+
loginModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setLoginModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(LoginModal, { onClose: () => setLoginModalOpen(false) }) }),
|
|
712
|
+
transactionModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setTransactionModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(TransactionModal, { onClose: () => setTransactionModalOpen(false) }) })
|
|
461
713
|
] });
|
|
462
714
|
}
|
|
463
715
|
function usePollar() {
|