@pollar/react 0.4.0 → 0.4.2

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,71 @@ 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.2"
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
+ NO_RESTORED_SESSION: { text: "" },
73
+ RESTORED_SESSION_SUCCESS: { text: "Session restored" },
74
+ RESTORED_SESSION_ERROR: { text: "Failed to restore session" },
75
+ SESSION_STORED: { text: "Session saved" },
76
+ ERROR_UNKNOWN: { text: "Something went wrong" },
77
+ ABORTED: { text: "Login cancelled" },
78
+ // transaction
79
+ BUILD_TRANSACTION_START: { text: "Building transaction\u2026" },
80
+ BUILD_TRANSACTION_SUCCESS: { text: "Transaction built, ready to sign and send" },
81
+ BUILD_TRANSACTION_ERROR: { text: "Failed to build transaction" },
82
+ BUILD_TRANSACTION_ERROR_NO_WALLET: { text: "No wallet connected" },
83
+ SIGN_SEND_TRANSACTION_START: { text: "Signing and sending transaction\u2026" },
84
+ SIGN_SEND_TRANSACTION_SUCCESS: { text: "Transaction signed" },
85
+ SIGN_SEND_TRANSACTION_ERROR: { text: "Signing rejected" }
86
+ };
87
+ function ModalStatusBanner({ code, status, onCancel, onRetry }) {
88
+ if (!code) {
89
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-status" });
90
+ }
91
+ const { text } = LOGIN_CODE_MESSAGES[code] || { text: "" };
92
+ const isLoading = status === "LOADING";
93
+ const icon = status === "ERROR" ? /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
94
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
95
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4.5 4.5l5 5M9.5 4.5l-5 5", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round" })
96
+ ] }) : status === "SUCCESS" ? /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
97
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
98
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3.5 7l2.5 2.5 4.5-5", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
99
+ ] }) : status === "LOADING" ? /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "5.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeDasharray: "22 10" }) }) : null;
100
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-status", "data-kind": status, children: [
101
+ icon,
102
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: text }),
103
+ isLoading && onCancel && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-status-cancel", onClick: onCancel, children: "Cancel" }),
104
+ status === core.StateStatus.ERROR && onRetry && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-status-cancel", onClick: onRetry, children: "Retry" })
105
+ ] });
106
+ }
28
107
  function EmailCodeInput({ email, onSubmit }) {
29
108
  const [digits, setDigits] = react.useState(["", "", "", "", "", ""]);
30
109
  const inputRefs = react.useRef([]);
@@ -131,52 +210,6 @@ var GoogleButton = ({ disabled, onClick }) => {
131
210
  ] })
132
211
  ] });
133
212
  };
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
213
  function LoginModalTemplate({
181
214
  theme,
182
215
  accentColor,
@@ -259,7 +292,7 @@ function LoginModalTemplate({
259
292
  ] })
260
293
  ] })
261
294
  ] }),
262
- /* @__PURE__ */ jsxRuntime.jsx(LoginStatusBanner, { code: loginStateCode, status, onCancel: () => cancelLoginRef.current?.(), onRetry }),
295
+ /* @__PURE__ */ jsxRuntime.jsx(ModalStatusBanner, { code: loginStateCode, status, onCancel: () => cancelLoginRef.current?.(), onRetry }),
263
296
  /* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
264
297
  ] });
265
298
  }
@@ -359,37 +392,16 @@ function LoginModal({ onClose }) {
359
392
  }
360
393
  ) });
361
394
  }
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
395
  function TransactionModalTemplate({
384
396
  theme,
385
397
  accentColor,
386
- stateCode,
398
+ transactionStateCode,
399
+ status,
387
400
  buildResult,
388
401
  submitResult,
389
- isLoading,
390
402
  onClose,
391
403
  onSignAndSend,
392
- onRetry
404
+ onRetrySignAndSend
393
405
  }) {
394
406
  const isDark = theme === "dark";
395
407
  const cssVars = {
@@ -405,14 +417,26 @@ function TransactionModalTemplate({
405
417
  "--pollar-success-text": isDark ? "#4ade80" : "#16a34a"
406
418
  };
407
419
  const [showXdr, setShowXdr] = react.useState(false);
408
- const phase = phaseFromStateCode(stateCode, submitResult);
409
- const title = TX_TITLES[stateCode] || "";
420
+ const [copied, setCopied] = react.useState(false);
421
+ function handleCopyHash() {
422
+ if (!submitResult) return;
423
+ navigator.clipboard.writeText(submitResult.hash).then(() => {
424
+ setCopied(true);
425
+ setTimeout(() => setCopied(false), 2e3);
426
+ });
427
+ }
428
+ const explorerNetwork = buildResult?.summary.network?.toLowerCase().includes("testnet") ? "testnet" : "public";
429
+ const explorerUrl = submitResult ? `https://stellar.expert/explorer/${explorerNetwork}/tx/${submitResult.hash}` : null;
430
+ transactionStateCode.includes("ERROR");
431
+ transactionStateCode.includes("SUCCESS");
432
+ const isBuilt = buildResult && transactionStateCode === "BUILD_TRANSACTION_SUCCESS";
433
+ const isDone = submitResult && transactionStateCode === "SIGN_SEND_TRANSACTION_START";
410
434
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-modal", "data-theme": theme, style: cssVars, onClick: (e) => e.stopPropagation(), children: [
411
435
  /* @__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" }) }) })
436
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-tx-title", children: "Transaction" }),
437
+ /* @__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
438
  ] }),
415
- buildResult && phase !== "building" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
439
+ isBuilt && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
416
440
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-summary", children: [
417
441
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "pollar-tx-summary-title", children: "Details" }),
418
442
  /* @__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 +470,122 @@ function TransactionModalTemplate({
446
470
  showXdr && /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "pollar-tx-xdr-content", children: buildResult.unsignedXdr })
447
471
  ] })
448
472
  ] }),
449
- phase === "success" && submitResult && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-result", children: [
473
+ submitResult && transactionStateCode === "SIGN_SEND_TRANSACTION_SUCCESS" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-result", children: [
450
474
  /* @__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" })
475
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-tx-result-hash", children: submitResult.hash }),
476
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-tx-result-actions", children: [
477
+ /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-tx-result-btn", onClick: handleCopyHash, children: copied ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
478
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
479
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
480
+ /* @__PURE__ */ jsxRuntime.jsx(
481
+ "path",
482
+ {
483
+ d: "M3.5 7l2.5 2.5 4.5-5",
484
+ stroke: "white",
485
+ strokeWidth: "1.5",
486
+ strokeLinecap: "round",
487
+ strokeLinejoin: "round"
488
+ }
489
+ )
490
+ ] }),
491
+ "Copied!"
492
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
493
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
494
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1.5", stroke: "currentColor", strokeWidth: "1.5" }),
495
+ /* @__PURE__ */ jsxRuntime.jsx(
496
+ "path",
497
+ {
498
+ d: "M3 9H2a1 1 0 01-1-1V2a1 1 0 011-1h6a1 1 0 011 1v1",
499
+ stroke: "currentColor",
500
+ strokeWidth: "1.5",
501
+ strokeLinecap: "round"
502
+ }
503
+ )
504
+ ] }),
505
+ "Copy hash"
506
+ ] }) }),
507
+ explorerUrl && /* @__PURE__ */ jsxRuntime.jsxs("a", { className: "pollar-tx-result-btn", href: explorerUrl, target: "_blank", rel: "noopener noreferrer", children: [
508
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
509
+ /* @__PURE__ */ jsxRuntime.jsx(
510
+ "path",
511
+ {
512
+ d: "M5 2H2a1 1 0 00-1 1v8a1 1 0 001 1h8a1 1 0 001-1V8",
513
+ stroke: "currentColor",
514
+ strokeWidth: "1.5",
515
+ strokeLinecap: "round"
516
+ }
517
+ ),
518
+ /* @__PURE__ */ jsxRuntime.jsx(
519
+ "path",
520
+ {
521
+ d: "M8 1h4m0 0v4m0-4L6 7",
522
+ stroke: "currentColor",
523
+ strokeWidth: "1.5",
524
+ strokeLinecap: "round",
525
+ strokeLinejoin: "round"
526
+ }
527
+ )
528
+ ] }),
529
+ "View on Explorer"
530
+ ] })
473
531
  ] })
474
532
  ] }),
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" }),
533
+ isBuilt && /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-tx-sign-btn", onClick: onSignAndSend, children: "Sign & Send" }),
534
+ isDone && /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-tx-sign-btn", onClick: onClose, children: "Done" }),
535
+ /* @__PURE__ */ jsxRuntime.jsx(
536
+ ModalStatusBanner,
537
+ {
538
+ code: transactionStateCode,
539
+ status
540
+ }
541
+ ),
478
542
  /* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
479
543
  ] });
480
544
  }
481
- var isTxBuildResponse = (data) => {
545
+ var isTxBuildResponseContent = (data) => {
482
546
  if (!data || typeof data !== "object") return false;
483
547
  const d = data;
484
548
  return typeof d.unsignedXdr === "string" && typeof d.networkPassphrase === "string" && typeof d.estimatedFee === "string" && d.summary !== null && typeof d.summary === "object";
485
549
  };
550
+ var isTxSignSendResponseContent = (data) => {
551
+ if (!data || typeof data !== "object") return false;
552
+ const d = data;
553
+ return typeof d.hash === "string" && (d.status === "PENDING" || d.status === "SUCCESS" || d.status === "FAILED");
554
+ };
486
555
  function TransactionModal({ onClose }) {
487
556
  const {
557
+ getClient,
488
558
  styles,
489
559
  state: { transaction }
490
560
  } = usePollar();
491
561
  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
562
  let buildResult = null;
498
- const stateCode = transaction.code;
499
- if (isTxBuildResponse(transaction.data)) {
500
- buildResult = transaction.data;
563
+ const transactionStateCode = transaction.code;
564
+ const content = transaction.data?.content;
565
+ if (isTxBuildResponseContent(content)) {
566
+ buildResult = content;
567
+ }
568
+ let submitResult = null;
569
+ if (isTxSignSendResponseContent(content)) {
570
+ submitResult = content;
571
+ }
572
+ async function handleSignAndSend() {
573
+ if (buildResult) {
574
+ await getClient().submitTx(buildResult.unsignedXdr);
575
+ }
501
576
  }
502
- console.log({ transaction, buildResult });
503
577
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
504
578
  TransactionModalTemplate,
505
579
  {
506
580
  theme,
507
581
  accentColor,
508
- stateCode,
582
+ transactionStateCode,
583
+ status: transaction.status,
509
584
  buildResult,
510
585
  submitResult,
511
- isLoading,
512
586
  onClose,
513
587
  onSignAndSend: handleSignAndSend,
514
- onRetry: () => {
515
- }
588
+ onRetrySignAndSend: handleSignAndSend
516
589
  }
517
590
  ) });
518
591
  }
@@ -539,6 +612,13 @@ function PollarProvider({ config, styles: propStyles, children }) {
539
612
  const [stellarClient] = react.useState(() => new core.StellarClient(config.stellarNetwork || "testnet"));
540
613
  const [sessionState, setSessionState] = react.useState(null);
541
614
  const [state, setState] = react.useState({
615
+ network: {
616
+ var: "network",
617
+ code: core.STATE_VAR_CODES.network.NONE,
618
+ status: core.StateStatus.NONE,
619
+ level: "info",
620
+ ts: 0
621
+ },
542
622
  authentication: {
543
623
  var: "authentication",
544
624
  code: core.STATE_VAR_CODES.authentication.NONE,
@@ -629,8 +709,8 @@ function PollarProvider({ config, styles: propStyles, children }) {
629
709
  );
630
710
  return /* @__PURE__ */ jsxRuntime.jsxs(PollarContext.Provider, { value: contextValue, children: [
631
711
  children,
632
- loginModalOpen && /* @__PURE__ */ jsxRuntime.jsx(LoginModal, { onClose: () => setLoginModalOpen(false) }),
633
- transactionModalOpen && /* @__PURE__ */ jsxRuntime.jsx(TransactionModal, { onClose: () => setTransactionModalOpen(false) })
712
+ loginModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setLoginModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(LoginModal, { onClose: () => setLoginModalOpen(false) }) }),
713
+ transactionModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setTransactionModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(TransactionModal, { onClose: () => setTransactionModalOpen(false) }) })
634
714
  ] });
635
715
  }
636
716
  function usePollar() {