@pollar/react 0.4.0 → 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.js CHANGED
@@ -12,6 +12,25 @@ 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
+ };
15
34
  var PollarModalFooter = () => {
16
35
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-footer", children: [
17
36
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-footer-protected", children: "Protected by" }),
@@ -20,11 +39,70 @@ var PollarModalFooter = () => {
20
39
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-footer-name", children: "Pollar" }),
21
40
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-footer-version", children: [
22
41
  "v",
23
- "0.4.0"
42
+ "0.4.1"
24
43
  ] })
25
44
  ] })
26
45
  ] });
27
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
+ }
28
106
  function EmailCodeInput({ email, onSubmit }) {
29
107
  const [digits, setDigits] = react.useState(["", "", "", "", "", ""]);
30
108
  const inputRefs = react.useRef([]);
@@ -131,52 +209,6 @@ var GoogleButton = ({ disabled, onClick }) => {
131
209
  ] })
132
210
  ] });
133
211
  };
134
- var LOGIN_CODE_MESSAGES = {
135
- NONE: { text: "" },
136
- LOGOUT: { text: "Logged out" },
137
- CREATE_SESSION_START: { text: "Starting session\u2026" },
138
- CREATE_SESSION_ERROR: { text: "Failed to start session" },
139
- CREATE_SESSION_SUCCESS: { text: "Session ready" },
140
- EMAIL_AUTH_START: { text: "Sending code\u2026" },
141
- EMAIL_AUTH_START_ERROR: { text: "Failed to send code" },
142
- EMAIL_AUTH_START_SUCCESS: { text: "Code sent \u2014 check your inbox" },
143
- EMAIL_AUTH_CODE_ERROR: { text: "Invalid code \u2014 try again" },
144
- EMAIL_AUTH_CODE_SUCCESS: { text: "Code verified!" },
145
- WALLET_AUTH_START: { text: "Connecting wallet\u2026" },
146
- WALLET_AUTH_FREIGHTER_NOT_INSTALLED: { text: "Freighter is not installed" },
147
- WALLET_AUTH_ALBEDO_NOT_INSTALLED: { text: "Albedo is not installed" },
148
- WALLET_AUTH_CONNECTED: { text: "Wallet connected" },
149
- WALLET_AUTH_LOGIN_START: { text: "Signing in with wallet\u2026" },
150
- WALLET_AUTH_LOGIN_START_SUCCESS: { text: "Wallet signed in" },
151
- WALLET_AUTH_LOGIN_START_ERROR: { text: "Failed to sign in with wallet" },
152
- WALLET_AUTH_ERROR: { text: "Unknow wallet error" },
153
- STREAM_POLL_START: { text: "Waiting for authentication\u2026" },
154
- STREAM_POLL_EVENT: { text: "Waiting for authentication\u2026" },
155
- STREAM_POLL_READY: { text: "Authenticated!" },
156
- FETCH_SESSION_START: { text: "Loading session\u2026" },
157
- FETCH_SESSION_SUCCESS: { text: "Welcome back!" },
158
- FETCH_SESSION_ERROR: { text: "Failed to load session" },
159
- ERROR_UNKNOWN: { text: "Something went wrong" },
160
- ABORTED: { text: "Login cancelled" }
161
- };
162
- function LoginStatusBanner({ code, status, onCancel, onRetry }) {
163
- if (!code) return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-status" });
164
- const { text } = LOGIN_CODE_MESSAGES[code] || { text: "" };
165
- const isLoading = status === core.StateStatus.LOADING;
166
- 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: [
167
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
168
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4.5 4.5l5 5M9.5 4.5l-5 5", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round" })
169
- ] }) : status === core.StateStatus.SUCCESS ? /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
170
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
171
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3.5 7l2.5 2.5 4.5-5", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
172
- ] }) : 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;
173
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-status", "data-kind": status, children: [
174
- icon,
175
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: text }),
176
- isLoading && onCancel && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-status-cancel", onClick: onCancel, children: "Cancel" }),
177
- status === core.StateStatus.ERROR && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-status-cancel", onClick: onRetry, children: "Retry" })
178
- ] });
179
- }
180
212
  function LoginModalTemplate({
181
213
  theme,
182
214
  accentColor,
@@ -259,7 +291,7 @@ function LoginModalTemplate({
259
291
  ] })
260
292
  ] })
261
293
  ] }),
262
- /* @__PURE__ */ jsxRuntime.jsx(LoginStatusBanner, { code: loginStateCode, status, onCancel: () => cancelLoginRef.current?.(), onRetry }),
294
+ /* @__PURE__ */ jsxRuntime.jsx(ModalStatusBanner, { code: loginStateCode, status, onCancel: () => cancelLoginRef.current?.(), onRetry }),
263
295
  /* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
264
296
  ] });
265
297
  }
@@ -359,37 +391,16 @@ function LoginModal({ onClose }) {
359
391
  }
360
392
  ) });
361
393
  }
362
- function phaseFromStateCode(stateCode, submitResult) {
363
- if (stateCode === core.STATE_VAR_CODES.transaction.BUILD_TRANSACTION_ERROR || stateCode === core.STATE_VAR_CODES.transaction.BUILD_TRANSACTION_ERROR_NO_WALLET || stateCode === core.STATE_VAR_CODES.transaction.SIGN_TRANSACTION_ERROR || stateCode === core.STATE_VAR_CODES.transaction.SEND_TRANSACTION_ERROR)
364
- return "error";
365
- if (stateCode === core.STATE_VAR_CODES.transaction.SEND_TRANSACTION_SUCCESS || submitResult) return "success";
366
- if (stateCode === core.STATE_VAR_CODES.transaction.BUILD_TRANSACTION_SUCCESS || stateCode === core.STATE_VAR_CODES.transaction.SIGN_TRANSACTION_START || stateCode === core.STATE_VAR_CODES.transaction.SIGN_TRANSACTION_SUCCESS || stateCode === core.STATE_VAR_CODES.transaction.SEND_TRANSACTION_START)
367
- return "ready";
368
- return "building";
369
- }
370
- var TX_TITLES = {
371
- NONE: "Preparing transaction\u2026",
372
- BUILD_TRANSACTION_START: "Building transaction\u2026",
373
- BUILD_TRANSACTION_SUCCESS: "Confirm Transaction",
374
- BUILD_TRANSACTION_ERROR: "Transaction failed",
375
- BUILD_TRANSACTION_ERROR_NO_WALLET: "No wallet connected",
376
- SIGN_TRANSACTION_START: "Waiting for wallet\u2026",
377
- SIGN_TRANSACTION_SUCCESS: "Signed \u2014 submitting\u2026",
378
- SIGN_TRANSACTION_ERROR: "Signing failed",
379
- SEND_TRANSACTION_START: "Submitting transaction\u2026",
380
- SEND_TRANSACTION_SUCCESS: "Transaction sent",
381
- SEND_TRANSACTION_ERROR: "Transaction failed"
382
- };
383
394
  function TransactionModalTemplate({
384
395
  theme,
385
396
  accentColor,
386
- stateCode,
397
+ transactionStateCode,
398
+ status,
387
399
  buildResult,
388
400
  submitResult,
389
- isLoading,
390
401
  onClose,
391
402
  onSignAndSend,
392
- onRetry
403
+ onRetrySignAndSend
393
404
  }) {
394
405
  const isDark = theme === "dark";
395
406
  const cssVars = {
@@ -405,14 +416,26 @@ function TransactionModalTemplate({
405
416
  "--pollar-success-text": isDark ? "#4ade80" : "#16a34a"
406
417
  };
407
418
  const [showXdr, setShowXdr] = react.useState(false);
408
- const phase = phaseFromStateCode(stateCode, submitResult);
409
- const title = TX_TITLES[stateCode] || "";
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";
410
433
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-modal", "data-theme": theme, style: cssVars, onClick: (e) => e.stopPropagation(), children: [
411
434
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-header", children: [
412
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-tx-title", children: title }),
413
- /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-tx-close", onClick: onClose, disabled: isLoading, "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" }) }) })
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" }) }) })
414
437
  ] }),
415
- buildResult && phase !== "building" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
438
+ isBuilt && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
416
439
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-summary", children: [
417
440
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "pollar-tx-summary-title", children: "Details" }),
418
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)) })
@@ -446,73 +469,122 @@ function TransactionModalTemplate({
446
469
  showXdr && /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "pollar-tx-xdr-content", children: buildResult.unsignedXdr })
447
470
  ] })
448
471
  ] }),
449
- phase === "success" && submitResult && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-result", children: [
472
+ submitResult && transactionStateCode === "SIGN_SEND_TRANSACTION_SUCCESS" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-result", children: [
450
473
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-tx-result-label", children: "Transaction hash" }),
451
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-tx-result-hash", children: submitResult.hash })
452
- ] }),
453
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-status", "data-kind": phase === "error" ? "ERROR" : phase === "success" ? "SUCCESS" : "LOADING", children: [
454
- isLoading && /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "pollar-tx-spinner", width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx(
455
- "circle",
456
- {
457
- cx: "7",
458
- cy: "7",
459
- r: "5.5",
460
- stroke: "currentColor",
461
- strokeWidth: "1.5",
462
- strokeLinecap: "round",
463
- strokeDasharray: "22 10"
464
- }
465
- ) }),
466
- phase === "error" && /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
467
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
468
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4.5 4.5l5 5M9.5 4.5l-5 5", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round" })
469
- ] }),
470
- phase === "success" && /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
471
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
472
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3.5 7l2.5 2.5 4.5-5", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
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
+ ] })
473
530
  ] })
474
531
  ] }),
475
- phase === "ready" && /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-tx-sign-btn", onClick: onSignAndSend, children: "Sign & Send" }),
476
- phase === "error" && /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-tx-sign-btn", onClick: onRetry, children: "Retry" }),
477
- phase === "success" && /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-tx-sign-btn", onClick: onClose, children: "Done" }),
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
+ ),
478
541
  /* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
479
542
  ] });
480
543
  }
481
- var isTxBuildResponse = (data) => {
544
+ var isTxBuildResponseContent = (data) => {
482
545
  if (!data || typeof data !== "object") return false;
483
546
  const d = data;
484
547
  return typeof d.unsignedXdr === "string" && typeof d.networkPassphrase === "string" && typeof d.estimatedFee === "string" && d.summary !== null && typeof d.summary === "object";
485
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
+ };
486
554
  function TransactionModal({ onClose }) {
487
555
  const {
556
+ getClient,
488
557
  styles,
489
558
  state: { transaction }
490
559
  } = usePollar();
491
560
  const { theme = "light", accentColor = "#005DB4" } = styles;
492
- const [submitResult, setSubmitResult] = react.useState(null);
493
- console.log({ transaction });
494
- async function handleSignAndSend() {
495
- }
496
- const isLoading = transaction.status === "LOADING";
497
561
  let buildResult = null;
498
- const stateCode = transaction.code;
499
- if (isTxBuildResponse(transaction.data)) {
500
- buildResult = transaction.data;
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
+ }
501
575
  }
502
- console.log({ transaction, buildResult });
503
576
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
504
577
  TransactionModalTemplate,
505
578
  {
506
579
  theme,
507
580
  accentColor,
508
- stateCode,
581
+ transactionStateCode,
582
+ status: transaction.status,
509
583
  buildResult,
510
584
  submitResult,
511
- isLoading,
512
585
  onClose,
513
586
  onSignAndSend: handleSignAndSend,
514
- onRetry: () => {
515
- }
587
+ onRetrySignAndSend: handleSignAndSend
516
588
  }
517
589
  ) });
518
590
  }
@@ -539,6 +611,13 @@ function PollarProvider({ config, styles: propStyles, children }) {
539
611
  const [stellarClient] = react.useState(() => new core.StellarClient(config.stellarNetwork || "testnet"));
540
612
  const [sessionState, setSessionState] = react.useState(null);
541
613
  const [state, setState] = react.useState({
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
+ },
542
621
  authentication: {
543
622
  var: "authentication",
544
623
  code: core.STATE_VAR_CODES.authentication.NONE,
@@ -629,8 +708,8 @@ function PollarProvider({ config, styles: propStyles, children }) {
629
708
  );
630
709
  return /* @__PURE__ */ jsxRuntime.jsxs(PollarContext.Provider, { value: contextValue, children: [
631
710
  children,
632
- loginModalOpen && /* @__PURE__ */ jsxRuntime.jsx(LoginModal, { onClose: () => setLoginModalOpen(false) }),
633
- transactionModalOpen && /* @__PURE__ */ jsxRuntime.jsx(TransactionModal, { onClose: () => setTransactionModalOpen(false) })
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) }) })
634
713
  ] });
635
714
  }
636
715
  function usePollar() {