@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.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { PollarClient, StellarClient, StateStatus, STATE_VAR_CODES, isValidSession, PollarStateVar, WalletType } from '@pollar/core';
3
- import { createContext, useState, useEffect, useMemo, useContext, useRef } from 'react';
3
+ import { createContext, useState, useEffect, useMemo, useContext, useRef, Component } from 'react';
4
4
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
5
 
6
6
  // src/context.tsx
@@ -10,6 +10,25 @@ var LOGO_POLLAR = "https://pollar.xyz/assets/logo_pollar.png";
10
10
  var LOGO_GITHUB = "https://pollar.xyz/assets/GitHub_Invertocat_White.png";
11
11
  var LOGO_FREIGHTER = "https://pollar.xyz/assets/logo_freighter.png";
12
12
  var LOGO_ALBEDO = "https://pollar.xyz/assets/logo_albedo.svg";
13
+ var ModalErrorBoundary = class extends Component {
14
+ constructor() {
15
+ super(...arguments);
16
+ this.state = { crashed: false };
17
+ }
18
+ static getDerivedStateFromError() {
19
+ return { crashed: true };
20
+ }
21
+ componentDidCatch(error) {
22
+ console.error("[Pollar] Modal crashed:", error);
23
+ }
24
+ render() {
25
+ if (this.state.crashed) {
26
+ this.props.onClose();
27
+ return null;
28
+ }
29
+ return this.props.children;
30
+ }
31
+ };
13
32
  var PollarModalFooter = () => {
14
33
  return /* @__PURE__ */ jsxs("div", { className: "pollar-footer", children: [
15
34
  /* @__PURE__ */ jsx("span", { className: "pollar-footer-protected", children: "Protected by" }),
@@ -18,11 +37,70 @@ var PollarModalFooter = () => {
18
37
  /* @__PURE__ */ jsx("span", { className: "pollar-footer-name", children: "Pollar" }),
19
38
  /* @__PURE__ */ jsxs("span", { className: "pollar-footer-version", children: [
20
39
  "v",
21
- "0.4.0"
40
+ "0.4.1"
22
41
  ] })
23
42
  ] })
24
43
  ] });
25
44
  };
45
+ var LOGIN_CODE_MESSAGES = {
46
+ NONE: { text: "" },
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
+ RESTORED_SESSION_SUCCESS: { text: "Session restored" },
71
+ RESTORED_SESSION_ERROR: { text: "Failed to restore session" },
72
+ SESSION_STORED: { text: "Session saved" },
73
+ ERROR_UNKNOWN: { text: "Something went wrong" },
74
+ ABORTED: { text: "Login cancelled" },
75
+ // transaction
76
+ BUILD_TRANSACTION_START: { text: "Building transaction\u2026" },
77
+ BUILD_TRANSACTION_SUCCESS: { text: "Transaction built, ready to sign and send" },
78
+ BUILD_TRANSACTION_ERROR: { text: "Failed to build transaction" },
79
+ BUILD_TRANSACTION_ERROR_NO_WALLET: { text: "No wallet connected" },
80
+ SIGN_SEND_TRANSACTION_START: { text: "Signing and sending transaction\u2026" },
81
+ SIGN_SEND_TRANSACTION_SUCCESS: { text: "Transaction signed" },
82
+ SIGN_SEND_TRANSACTION_ERROR: { text: "Signing rejected" }
83
+ };
84
+ function ModalStatusBanner({ code, status, onCancel, onRetry }) {
85
+ if (!code) {
86
+ return /* @__PURE__ */ jsx("div", { className: "pollar-status" });
87
+ }
88
+ const { text } = LOGIN_CODE_MESSAGES[code] || { text: "" };
89
+ const isLoading = status === "LOADING";
90
+ const icon = status === "ERROR" ? /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
91
+ /* @__PURE__ */ jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
92
+ /* @__PURE__ */ jsx("path", { d: "M4.5 4.5l5 5M9.5 4.5l-5 5", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round" })
93
+ ] }) : status === "SUCCESS" ? /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
94
+ /* @__PURE__ */ jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
95
+ /* @__PURE__ */ jsx("path", { d: "M3.5 7l2.5 2.5 4.5-5", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
96
+ ] }) : 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;
97
+ return /* @__PURE__ */ jsxs("div", { className: "pollar-status", "data-kind": status, children: [
98
+ icon,
99
+ /* @__PURE__ */ jsx("span", { children: text }),
100
+ isLoading && onCancel && /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-status-cancel", onClick: onCancel, children: "Cancel" }),
101
+ status === StateStatus.ERROR && onRetry && /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-status-cancel", onClick: onRetry, children: "Retry" })
102
+ ] });
103
+ }
26
104
  function EmailCodeInput({ email, onSubmit }) {
27
105
  const [digits, setDigits] = useState(["", "", "", "", "", ""]);
28
106
  const inputRefs = useRef([]);
@@ -129,52 +207,6 @@ var GoogleButton = ({ disabled, onClick }) => {
129
207
  ] })
130
208
  ] });
131
209
  };
132
- var LOGIN_CODE_MESSAGES = {
133
- NONE: { text: "" },
134
- LOGOUT: { text: "Logged out" },
135
- CREATE_SESSION_START: { text: "Starting session\u2026" },
136
- CREATE_SESSION_ERROR: { text: "Failed to start session" },
137
- CREATE_SESSION_SUCCESS: { text: "Session ready" },
138
- EMAIL_AUTH_START: { text: "Sending code\u2026" },
139
- EMAIL_AUTH_START_ERROR: { text: "Failed to send code" },
140
- EMAIL_AUTH_START_SUCCESS: { text: "Code sent \u2014 check your inbox" },
141
- EMAIL_AUTH_CODE_ERROR: { text: "Invalid code \u2014 try again" },
142
- EMAIL_AUTH_CODE_SUCCESS: { text: "Code verified!" },
143
- WALLET_AUTH_START: { text: "Connecting wallet\u2026" },
144
- WALLET_AUTH_FREIGHTER_NOT_INSTALLED: { text: "Freighter is not installed" },
145
- WALLET_AUTH_ALBEDO_NOT_INSTALLED: { text: "Albedo is not installed" },
146
- WALLET_AUTH_CONNECTED: { text: "Wallet connected" },
147
- WALLET_AUTH_LOGIN_START: { text: "Signing in with wallet\u2026" },
148
- WALLET_AUTH_LOGIN_START_SUCCESS: { text: "Wallet signed in" },
149
- WALLET_AUTH_LOGIN_START_ERROR: { text: "Failed to sign in with wallet" },
150
- WALLET_AUTH_ERROR: { text: "Unknow wallet error" },
151
- STREAM_POLL_START: { text: "Waiting for authentication\u2026" },
152
- STREAM_POLL_EVENT: { text: "Waiting for authentication\u2026" },
153
- STREAM_POLL_READY: { text: "Authenticated!" },
154
- FETCH_SESSION_START: { text: "Loading session\u2026" },
155
- FETCH_SESSION_SUCCESS: { text: "Welcome back!" },
156
- FETCH_SESSION_ERROR: { text: "Failed to load session" },
157
- ERROR_UNKNOWN: { text: "Something went wrong" },
158
- ABORTED: { text: "Login cancelled" }
159
- };
160
- function LoginStatusBanner({ code, status, onCancel, onRetry }) {
161
- if (!code) return /* @__PURE__ */ jsx("div", { className: "pollar-status" });
162
- const { text } = LOGIN_CODE_MESSAGES[code] || { text: "" };
163
- const isLoading = status === StateStatus.LOADING;
164
- const icon = status === StateStatus.ERROR ? /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
165
- /* @__PURE__ */ jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
166
- /* @__PURE__ */ jsx("path", { d: "M4.5 4.5l5 5M9.5 4.5l-5 5", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round" })
167
- ] }) : status === StateStatus.SUCCESS ? /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
168
- /* @__PURE__ */ jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
169
- /* @__PURE__ */ jsx("path", { d: "M3.5 7l2.5 2.5 4.5-5", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
170
- ] }) : status === StateStatus.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;
171
- return /* @__PURE__ */ jsxs("div", { className: "pollar-status", "data-kind": status, children: [
172
- icon,
173
- /* @__PURE__ */ jsx("span", { children: text }),
174
- isLoading && onCancel && /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-status-cancel", onClick: onCancel, children: "Cancel" }),
175
- status === StateStatus.ERROR && /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-status-cancel", onClick: onRetry, children: "Retry" })
176
- ] });
177
- }
178
210
  function LoginModalTemplate({
179
211
  theme,
180
212
  accentColor,
@@ -257,7 +289,7 @@ function LoginModalTemplate({
257
289
  ] })
258
290
  ] })
259
291
  ] }),
260
- /* @__PURE__ */ jsx(LoginStatusBanner, { code: loginStateCode, status, onCancel: () => cancelLoginRef.current?.(), onRetry }),
292
+ /* @__PURE__ */ jsx(ModalStatusBanner, { code: loginStateCode, status, onCancel: () => cancelLoginRef.current?.(), onRetry }),
261
293
  /* @__PURE__ */ jsx(PollarModalFooter, {})
262
294
  ] });
263
295
  }
@@ -357,37 +389,16 @@ function LoginModal({ onClose }) {
357
389
  }
358
390
  ) });
359
391
  }
360
- function phaseFromStateCode(stateCode, submitResult) {
361
- if (stateCode === STATE_VAR_CODES.transaction.BUILD_TRANSACTION_ERROR || stateCode === STATE_VAR_CODES.transaction.BUILD_TRANSACTION_ERROR_NO_WALLET || stateCode === STATE_VAR_CODES.transaction.SIGN_TRANSACTION_ERROR || stateCode === STATE_VAR_CODES.transaction.SEND_TRANSACTION_ERROR)
362
- return "error";
363
- if (stateCode === STATE_VAR_CODES.transaction.SEND_TRANSACTION_SUCCESS || submitResult) return "success";
364
- if (stateCode === STATE_VAR_CODES.transaction.BUILD_TRANSACTION_SUCCESS || stateCode === STATE_VAR_CODES.transaction.SIGN_TRANSACTION_START || stateCode === STATE_VAR_CODES.transaction.SIGN_TRANSACTION_SUCCESS || stateCode === STATE_VAR_CODES.transaction.SEND_TRANSACTION_START)
365
- return "ready";
366
- return "building";
367
- }
368
- var TX_TITLES = {
369
- NONE: "Preparing transaction\u2026",
370
- BUILD_TRANSACTION_START: "Building transaction\u2026",
371
- BUILD_TRANSACTION_SUCCESS: "Confirm Transaction",
372
- BUILD_TRANSACTION_ERROR: "Transaction failed",
373
- BUILD_TRANSACTION_ERROR_NO_WALLET: "No wallet connected",
374
- SIGN_TRANSACTION_START: "Waiting for wallet\u2026",
375
- SIGN_TRANSACTION_SUCCESS: "Signed \u2014 submitting\u2026",
376
- SIGN_TRANSACTION_ERROR: "Signing failed",
377
- SEND_TRANSACTION_START: "Submitting transaction\u2026",
378
- SEND_TRANSACTION_SUCCESS: "Transaction sent",
379
- SEND_TRANSACTION_ERROR: "Transaction failed"
380
- };
381
392
  function TransactionModalTemplate({
382
393
  theme,
383
394
  accentColor,
384
- stateCode,
395
+ transactionStateCode,
396
+ status,
385
397
  buildResult,
386
398
  submitResult,
387
- isLoading,
388
399
  onClose,
389
400
  onSignAndSend,
390
- onRetry
401
+ onRetrySignAndSend
391
402
  }) {
392
403
  const isDark = theme === "dark";
393
404
  const cssVars = {
@@ -403,14 +414,26 @@ function TransactionModalTemplate({
403
414
  "--pollar-success-text": isDark ? "#4ade80" : "#16a34a"
404
415
  };
405
416
  const [showXdr, setShowXdr] = useState(false);
406
- const phase = phaseFromStateCode(stateCode, submitResult);
407
- const title = TX_TITLES[stateCode] || "";
417
+ const [copied, setCopied] = useState(false);
418
+ function handleCopyHash() {
419
+ if (!submitResult) return;
420
+ navigator.clipboard.writeText(submitResult.hash).then(() => {
421
+ setCopied(true);
422
+ setTimeout(() => setCopied(false), 2e3);
423
+ });
424
+ }
425
+ const explorerNetwork = buildResult?.summary.network?.toLowerCase().includes("testnet") ? "testnet" : "public";
426
+ const explorerUrl = submitResult ? `https://stellar.expert/explorer/${explorerNetwork}/tx/${submitResult.hash}` : null;
427
+ transactionStateCode.includes("ERROR");
428
+ transactionStateCode.includes("SUCCESS");
429
+ const isBuilt = buildResult && transactionStateCode === "BUILD_TRANSACTION_SUCCESS";
430
+ const isDone = submitResult && transactionStateCode === "SIGN_SEND_TRANSACTION_START";
408
431
  return /* @__PURE__ */ jsxs("div", { className: "pollar-tx-modal", "data-theme": theme, style: cssVars, onClick: (e) => e.stopPropagation(), children: [
409
432
  /* @__PURE__ */ jsxs("div", { className: "pollar-tx-header", children: [
410
- /* @__PURE__ */ jsx("h2", { className: "pollar-tx-title", children: title }),
411
- /* @__PURE__ */ jsx("button", { className: "pollar-tx-close", onClick: onClose, disabled: isLoading, "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" }) }) })
433
+ /* @__PURE__ */ jsx("h2", { className: "pollar-tx-title", children: "Transaction" }),
434
+ /* @__PURE__ */ jsx("button", { className: "pollar-tx-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" }) }) })
412
435
  ] }),
413
- buildResult && phase !== "building" && /* @__PURE__ */ jsxs(Fragment, { children: [
436
+ isBuilt && /* @__PURE__ */ jsxs(Fragment, { children: [
414
437
  /* @__PURE__ */ jsxs("div", { className: "pollar-tx-summary", children: [
415
438
  /* @__PURE__ */ jsx("p", { className: "pollar-tx-summary-title", children: "Details" }),
416
439
  /* @__PURE__ */ jsx("ul", { className: "pollar-tx-summary-lines", children: buildResult.summary.lines.map((line, i) => /* @__PURE__ */ jsx("li", { className: "pollar-tx-summary-line", children: line }, i)) })
@@ -444,73 +467,122 @@ function TransactionModalTemplate({
444
467
  showXdr && /* @__PURE__ */ jsx("pre", { className: "pollar-tx-xdr-content", children: buildResult.unsignedXdr })
445
468
  ] })
446
469
  ] }),
447
- phase === "success" && submitResult && /* @__PURE__ */ jsxs("div", { className: "pollar-tx-result", children: [
470
+ submitResult && transactionStateCode === "SIGN_SEND_TRANSACTION_SUCCESS" && /* @__PURE__ */ jsxs("div", { className: "pollar-tx-result", children: [
448
471
  /* @__PURE__ */ jsx("span", { className: "pollar-tx-result-label", children: "Transaction hash" }),
449
- /* @__PURE__ */ jsx("span", { className: "pollar-tx-result-hash", children: submitResult.hash })
450
- ] }),
451
- /* @__PURE__ */ jsxs("div", { className: "pollar-tx-status", "data-kind": phase === "error" ? "ERROR" : phase === "success" ? "SUCCESS" : "LOADING", children: [
452
- isLoading && /* @__PURE__ */ jsx("svg", { className: "pollar-tx-spinner", width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsx(
453
- "circle",
454
- {
455
- cx: "7",
456
- cy: "7",
457
- r: "5.5",
458
- stroke: "currentColor",
459
- strokeWidth: "1.5",
460
- strokeLinecap: "round",
461
- strokeDasharray: "22 10"
462
- }
463
- ) }),
464
- phase === "error" && /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
465
- /* @__PURE__ */ jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
466
- /* @__PURE__ */ jsx("path", { d: "M4.5 4.5l5 5M9.5 4.5l-5 5", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round" })
467
- ] }),
468
- phase === "success" && /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
469
- /* @__PURE__ */ jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
470
- /* @__PURE__ */ jsx("path", { d: "M3.5 7l2.5 2.5 4.5-5", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
472
+ /* @__PURE__ */ jsx("span", { className: "pollar-tx-result-hash", children: submitResult.hash }),
473
+ /* @__PURE__ */ jsxs("div", { className: "pollar-tx-result-actions", children: [
474
+ /* @__PURE__ */ jsx("button", { className: "pollar-tx-result-btn", onClick: handleCopyHash, children: copied ? /* @__PURE__ */ jsxs(Fragment, { children: [
475
+ /* @__PURE__ */ jsxs("svg", { width: "13", height: "13", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
476
+ /* @__PURE__ */ jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
477
+ /* @__PURE__ */ jsx(
478
+ "path",
479
+ {
480
+ d: "M3.5 7l2.5 2.5 4.5-5",
481
+ stroke: "white",
482
+ strokeWidth: "1.5",
483
+ strokeLinecap: "round",
484
+ strokeLinejoin: "round"
485
+ }
486
+ )
487
+ ] }),
488
+ "Copied!"
489
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
490
+ /* @__PURE__ */ jsxs("svg", { width: "13", height: "13", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
491
+ /* @__PURE__ */ jsx("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1.5", stroke: "currentColor", strokeWidth: "1.5" }),
492
+ /* @__PURE__ */ jsx(
493
+ "path",
494
+ {
495
+ d: "M3 9H2a1 1 0 01-1-1V2a1 1 0 011-1h6a1 1 0 011 1v1",
496
+ stroke: "currentColor",
497
+ strokeWidth: "1.5",
498
+ strokeLinecap: "round"
499
+ }
500
+ )
501
+ ] }),
502
+ "Copy hash"
503
+ ] }) }),
504
+ explorerUrl && /* @__PURE__ */ jsxs("a", { className: "pollar-tx-result-btn", href: explorerUrl, target: "_blank", rel: "noopener noreferrer", children: [
505
+ /* @__PURE__ */ jsxs("svg", { width: "13", height: "13", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
506
+ /* @__PURE__ */ jsx(
507
+ "path",
508
+ {
509
+ d: "M5 2H2a1 1 0 00-1 1v8a1 1 0 001 1h8a1 1 0 001-1V8",
510
+ stroke: "currentColor",
511
+ strokeWidth: "1.5",
512
+ strokeLinecap: "round"
513
+ }
514
+ ),
515
+ /* @__PURE__ */ jsx(
516
+ "path",
517
+ {
518
+ d: "M8 1h4m0 0v4m0-4L6 7",
519
+ stroke: "currentColor",
520
+ strokeWidth: "1.5",
521
+ strokeLinecap: "round",
522
+ strokeLinejoin: "round"
523
+ }
524
+ )
525
+ ] }),
526
+ "View on Explorer"
527
+ ] })
471
528
  ] })
472
529
  ] }),
473
- phase === "ready" && /* @__PURE__ */ jsx("button", { className: "pollar-tx-sign-btn", onClick: onSignAndSend, children: "Sign & Send" }),
474
- phase === "error" && /* @__PURE__ */ jsx("button", { className: "pollar-tx-sign-btn", onClick: onRetry, children: "Retry" }),
475
- phase === "success" && /* @__PURE__ */ jsx("button", { className: "pollar-tx-sign-btn", onClick: onClose, children: "Done" }),
530
+ isBuilt && /* @__PURE__ */ jsx("button", { className: "pollar-tx-sign-btn", onClick: onSignAndSend, children: "Sign & Send" }),
531
+ isDone && /* @__PURE__ */ jsx("button", { className: "pollar-tx-sign-btn", onClick: onClose, children: "Done" }),
532
+ /* @__PURE__ */ jsx(
533
+ ModalStatusBanner,
534
+ {
535
+ code: transactionStateCode,
536
+ status
537
+ }
538
+ ),
476
539
  /* @__PURE__ */ jsx(PollarModalFooter, {})
477
540
  ] });
478
541
  }
479
- var isTxBuildResponse = (data) => {
542
+ var isTxBuildResponseContent = (data) => {
480
543
  if (!data || typeof data !== "object") return false;
481
544
  const d = data;
482
545
  return typeof d.unsignedXdr === "string" && typeof d.networkPassphrase === "string" && typeof d.estimatedFee === "string" && d.summary !== null && typeof d.summary === "object";
483
546
  };
547
+ var isTxSignSendResponseContent = (data) => {
548
+ if (!data || typeof data !== "object") return false;
549
+ const d = data;
550
+ return typeof d.hash === "string" && (d.status === "PENDING" || d.status === "SUCCESS" || d.status === "FAILED");
551
+ };
484
552
  function TransactionModal({ onClose }) {
485
553
  const {
554
+ getClient,
486
555
  styles,
487
556
  state: { transaction }
488
557
  } = usePollar();
489
558
  const { theme = "light", accentColor = "#005DB4" } = styles;
490
- const [submitResult, setSubmitResult] = useState(null);
491
- console.log({ transaction });
492
- async function handleSignAndSend() {
493
- }
494
- const isLoading = transaction.status === "LOADING";
495
559
  let buildResult = null;
496
- const stateCode = transaction.code;
497
- if (isTxBuildResponse(transaction.data)) {
498
- buildResult = transaction.data;
560
+ const transactionStateCode = transaction.code;
561
+ const content = transaction.data?.content;
562
+ if (isTxBuildResponseContent(content)) {
563
+ buildResult = content;
564
+ }
565
+ let submitResult = null;
566
+ if (isTxSignSendResponseContent(content)) {
567
+ submitResult = content;
568
+ }
569
+ async function handleSignAndSend() {
570
+ if (buildResult) {
571
+ await getClient().submitTx(buildResult.unsignedXdr);
572
+ }
499
573
  }
500
- console.log({ transaction, buildResult });
501
574
  return /* @__PURE__ */ jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsx(
502
575
  TransactionModalTemplate,
503
576
  {
504
577
  theme,
505
578
  accentColor,
506
- stateCode,
579
+ transactionStateCode,
580
+ status: transaction.status,
507
581
  buildResult,
508
582
  submitResult,
509
- isLoading,
510
583
  onClose,
511
584
  onSignAndSend: handleSignAndSend,
512
- onRetry: () => {
513
- }
585
+ onRetrySignAndSend: handleSignAndSend
514
586
  }
515
587
  ) });
516
588
  }
@@ -537,6 +609,13 @@ function PollarProvider({ config, styles: propStyles, children }) {
537
609
  const [stellarClient] = useState(() => new StellarClient(config.stellarNetwork || "testnet"));
538
610
  const [sessionState, setSessionState] = useState(null);
539
611
  const [state, setState] = useState({
612
+ network: {
613
+ var: "network",
614
+ code: STATE_VAR_CODES.network.NONE,
615
+ status: StateStatus.NONE,
616
+ level: "info",
617
+ ts: 0
618
+ },
540
619
  authentication: {
541
620
  var: "authentication",
542
621
  code: STATE_VAR_CODES.authentication.NONE,
@@ -627,8 +706,8 @@ function PollarProvider({ config, styles: propStyles, children }) {
627
706
  );
628
707
  return /* @__PURE__ */ jsxs(PollarContext.Provider, { value: contextValue, children: [
629
708
  children,
630
- loginModalOpen && /* @__PURE__ */ jsx(LoginModal, { onClose: () => setLoginModalOpen(false) }),
631
- transactionModalOpen && /* @__PURE__ */ jsx(TransactionModal, { onClose: () => setTransactionModalOpen(false) })
709
+ loginModalOpen && /* @__PURE__ */ jsx(ModalErrorBoundary, { onClose: () => setLoginModalOpen(false), children: /* @__PURE__ */ jsx(LoginModal, { onClose: () => setLoginModalOpen(false) }) }),
710
+ transactionModalOpen && /* @__PURE__ */ jsx(ModalErrorBoundary, { onClose: () => setTransactionModalOpen(false), children: /* @__PURE__ */ jsx(TransactionModal, { onClose: () => setTransactionModalOpen(false) }) })
632
711
  ] });
633
712
  }
634
713
  function usePollar() {