@yieldfabric/wallet 0.2.0 → 0.2.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.cjs CHANGED
@@ -5353,7 +5353,7 @@ var init_SignupFlow = __esm({
5353
5353
  };
5354
5354
  AvererSidebar = ({ onError }) => {
5355
5355
  const navigate = useWalletNavigate();
5356
- return /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "w-full md:w-[360px] md:h-screen bg-background flex md:flex-col items-start justify-between md:justify-between gap-4 px-6 py-5 md:p-10 border-b md:border-b-0 md:border-r border-border-light/20", children: [
5356
+ return /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "w-full md:w-[360px] md:h-screen bg-background flex md:flex-col items-start justify-between md:justify-between gap-4 px-6 py-5 md:p-10 border-b md:border-b-0 md:border-r border-border-light", children: [
5357
5357
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6 md:gap-10", children: [
5358
5358
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-text-primary", children: /* @__PURE__ */ jsxRuntime.jsx(YieldFabricLockup, { size: 32 }) }),
5359
5359
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "hidden md:block space-y-3 max-w-[260px]", children: [
@@ -8794,6 +8794,16 @@ var WalletCenterContext = React54.createContext(null);
8794
8794
  function WalletCenterProvider({ children }) {
8795
8795
  const [isOpen, setIsOpen] = React54.useState(false);
8796
8796
  const [requestedView, setRequestedView] = React54.useState("menu");
8797
+ const [host, setHostElement] = React54.useState(null);
8798
+ const [hostOptions, setHostOptions] = React54.useState({});
8799
+ const [hostTitle, setHostTitle] = React54.useState(null);
8800
+ const setHost = React54.useCallback((next) => {
8801
+ setHostElement((current) => {
8802
+ if (current === next) return current;
8803
+ if (!next) setHostTitle(null);
8804
+ return next;
8805
+ });
8806
+ }, []);
8797
8807
  const openWalletCenter = React54.useCallback((view = "menu") => {
8798
8808
  setRequestedView(view);
8799
8809
  setIsOpen(true);
@@ -8803,8 +8813,8 @@ function WalletCenterProvider({ children }) {
8803
8813
  setRequestedView("menu");
8804
8814
  }, []);
8805
8815
  const value = React54.useMemo(
8806
- () => ({ isOpen, requestedView, openWalletCenter, closeWalletCenter }),
8807
- [isOpen, requestedView, openWalletCenter, closeWalletCenter]
8816
+ () => ({ isOpen, requestedView, openWalletCenter, closeWalletCenter, host, setHost, hostOptions, setHostOptions, hostTitle, setHostTitle }),
8817
+ [isOpen, requestedView, openWalletCenter, closeWalletCenter, host, setHost, hostOptions, hostTitle]
8808
8818
  );
8809
8819
  return /* @__PURE__ */ jsxRuntime.jsx(WalletCenterContext.Provider, { value, children });
8810
8820
  }
@@ -8832,53 +8842,105 @@ function RedirectTo({ href, replace = true }) {
8832
8842
  return null;
8833
8843
  }
8834
8844
 
8835
- // src/core/entityEvents.ts
8836
- init_tokenManager();
8837
- init_config();
8838
- function subscribeEntityEvents(entityId, onEvent, onError) {
8839
- let eventSource = null;
8840
- let reconnectTimeout = null;
8841
- let attempts = 0;
8845
+ // src/core/jsonEventStream.ts
8846
+ function subscribeJsonEvents(options) {
8842
8847
  let closed = false;
8843
- function connect() {
8848
+ let retry = 0;
8849
+ let timer;
8850
+ let controller;
8851
+ const connect = async () => {
8844
8852
  if (closed) return;
8845
- const token = exports.tokenManager.getCurrentToken();
8846
- if (!token) {
8847
- onError?.(new Error("No auth token for entity event stream"));
8848
- reconnectTimeout = setTimeout(connect, 5e3);
8849
- return;
8850
- }
8851
- const baseUrl = getPaymentsServiceUrl();
8852
- const url = `${baseUrl}/api/events/stream?entity_id=${encodeURIComponent(entityId)}&access_token=${encodeURIComponent(token)}`;
8853
- eventSource = new EventSource(url);
8854
- eventSource.onmessage = (e) => {
8855
- try {
8856
- onEvent(JSON.parse(e.data));
8857
- } catch {
8858
- }
8859
- };
8860
- eventSource.onopen = () => {
8861
- attempts = 0;
8853
+ const attempt = new AbortController();
8854
+ controller = attempt;
8855
+ let reader;
8856
+ let stall;
8857
+ const renewDeadline = () => {
8858
+ if (stall) clearTimeout(stall);
8859
+ stall = setTimeout(() => attempt.abort(), 75e3);
8862
8860
  };
8863
- eventSource.onerror = () => {
8864
- eventSource?.close();
8865
- eventSource = null;
8866
- if (closed) return;
8867
- attempts++;
8868
- const delay2 = Math.min(1e3 * Math.pow(2, attempts - 1), 3e4);
8869
- reconnectTimeout = setTimeout(connect, delay2);
8870
- onError?.(new Error(`Entity SSE error, reconnecting in ${delay2}ms`));
8871
- };
8872
- }
8873
- connect();
8861
+ try {
8862
+ renewDeadline();
8863
+ const token = options.token();
8864
+ if (!token) throw new Error("Sign in to receive live updates.");
8865
+ const response = await fetch(options.url(), {
8866
+ headers: { Authorization: `Bearer ${token}`, Accept: "text/event-stream" },
8867
+ signal: attempt.signal,
8868
+ credentials: "omit",
8869
+ cache: "no-store",
8870
+ redirect: "error"
8871
+ });
8872
+ if (!response.ok || !response.headers.get("content-type")?.includes("text/event-stream") || !response.body) {
8873
+ throw new Error(`Live updates unavailable (HTTP ${response.status}).`);
8874
+ }
8875
+ reader = response.body.getReader();
8876
+ const decoder = new TextDecoder();
8877
+ let buffer = "", data = [], size = 0;
8878
+ while (!closed) {
8879
+ const part = await reader.read();
8880
+ if (part.done) break;
8881
+ renewDeadline();
8882
+ buffer += decoder.decode(part.value, { stream: true });
8883
+ for (; ; ) {
8884
+ const end = buffer.search(/[\r\n]/);
8885
+ if (end < 0 || buffer[end] === "\r" && end === buffer.length - 1) break;
8886
+ const line = buffer.slice(0, end);
8887
+ const delimiter = buffer[end] === "\r" && buffer[end + 1] === "\n" ? 2 : 1;
8888
+ buffer = buffer.slice(end + delimiter);
8889
+ size += line.length;
8890
+ if (size > 262144) throw new Error("Live update exceeded its size limit.");
8891
+ if (!line) {
8892
+ if (data.length) {
8893
+ let value;
8894
+ try {
8895
+ value = JSON.parse(data.join("\n"));
8896
+ } catch {
8897
+ }
8898
+ if (value !== void 0 && !closed) {
8899
+ retry = 0;
8900
+ options.onEvent(value);
8901
+ }
8902
+ }
8903
+ data = [];
8904
+ size = 0;
8905
+ } else if (line.startsWith("data:")) {
8906
+ data.push(line.slice(5).replace(/^ /, ""));
8907
+ }
8908
+ }
8909
+ if (buffer.length + size > 262144) throw new Error("Live update exceeded its size limit.");
8910
+ }
8911
+ if (!closed) throw new Error("Live updates disconnected.");
8912
+ } catch (error) {
8913
+ if (!closed) options.onError?.(error instanceof Error ? error : new Error("Live updates unavailable."));
8914
+ } finally {
8915
+ if (stall) clearTimeout(stall);
8916
+ attempt.abort();
8917
+ if (reader) {
8918
+ void reader.cancel().catch(() => void 0);
8919
+ reader.releaseLock();
8920
+ }
8921
+ if (!closed) timer = setTimeout(() => void connect(), Math.min(1e3 * 2 ** Math.min(retry++, 5), 3e4));
8922
+ }
8923
+ };
8924
+ void connect();
8874
8925
  return () => {
8875
8926
  closed = true;
8876
- eventSource?.close();
8877
- eventSource = null;
8878
- if (reconnectTimeout) clearTimeout(reconnectTimeout);
8927
+ if (timer) clearTimeout(timer);
8928
+ controller?.abort();
8879
8929
  };
8880
8930
  }
8881
8931
 
8932
+ // src/core/entityEvents.ts
8933
+ init_tokenManager();
8934
+ init_config();
8935
+ function subscribeEntityEvents(entityId, onEvent, onError) {
8936
+ return subscribeJsonEvents({
8937
+ url: () => `${getPaymentsServiceUrl()}/api/events/stream?entity_id=${encodeURIComponent(entityId)}`,
8938
+ token: () => exports.tokenManager.getCurrentToken(),
8939
+ onEvent,
8940
+ onError
8941
+ });
8942
+ }
8943
+
8882
8944
  // src/core/globalNotificationService.ts
8883
8945
  var _GlobalNotificationService = class _GlobalNotificationService {
8884
8946
  constructor(callbacks) {
@@ -9390,7 +9452,7 @@ function CenterPrimaryButton({
9390
9452
  size = "sm",
9391
9453
  className = ""
9392
9454
  }) {
9393
- const sizeClasses2 = size === "md" ? "text-[12px] px-3 py-1.5" : "text-[11px] px-2.5 py-1";
9455
+ const sizeClasses2 = size === "md" ? "text-[12px] px-3 py-1.5 max-lg:min-h-[44px] max-lg:px-4 max-lg:text-[13px]" : "text-[11px] px-2.5 py-1 max-lg:min-h-[44px] max-lg:px-4 max-lg:text-[13px]";
9394
9456
  return /* @__PURE__ */ jsxRuntime.jsx(
9395
9457
  "button",
9396
9458
  {
@@ -9399,7 +9461,7 @@ function CenterPrimaryButton({
9399
9461
  onClick,
9400
9462
  className: [
9401
9463
  "font-medium rounded-md transition-colors",
9402
- "bg-cta text-on-cta hover:bg-cta-hover",
9464
+ "bg-cta text-on-cta hover:bg-cta-hover active:opacity-90",
9403
9465
  "disabled:opacity-50 disabled:cursor-not-allowed",
9404
9466
  sizeClasses2,
9405
9467
  className
@@ -11460,7 +11522,7 @@ function StripeProgressPanel({
11460
11522
  detail ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-[10px] leading-relaxed text-text-secondary/75", children: detail }) : null
11461
11523
  ] })
11462
11524
  ] }),
11463
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-1.5 w-full overflow-hidden rounded-full bg-border-default/40", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: `h-full w-2/3 rounded-full ${delayed ? "bg-status-warning-text" : "bg-cta"} motion-safe:animate-pulse` }) })
11525
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-1.5 w-full overflow-hidden rounded-full bg-border-default", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: `h-full w-2/3 rounded-full ${delayed ? "bg-status-warning-text" : "bg-cta"} motion-safe:animate-pulse` }) })
11464
11526
  ] });
11465
11527
  }
11466
11528
  function StripeResultPanel({
@@ -11866,7 +11928,7 @@ function ProgressPanel({
11866
11928
  /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-[16px] font-medium text-text-primary leading-snug", children: title }),
11867
11929
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-[12px] leading-relaxed text-text-secondary", children: body })
11868
11930
  ] }),
11869
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-1.5 w-full overflow-hidden rounded-full bg-border-default/40", children: /* @__PURE__ */ jsxRuntime.jsx(
11931
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-1.5 w-full overflow-hidden rounded-full bg-border-default", children: /* @__PURE__ */ jsxRuntime.jsx(
11870
11932
  "div",
11871
11933
  {
11872
11934
  className: `h-full w-2/3 rounded-full motion-safe:animate-pulse ${delayed ? "bg-status-warning-text" : "bg-cta"}`
@@ -14935,7 +14997,7 @@ function RecoveryPanel({
14935
14997
  return /* @__PURE__ */ jsxRuntime.jsx(
14936
14998
  "div",
14937
14999
  {
14938
- className: "rounded-lg border border-status-warning-text/25 bg-status-warning-bg/80 px-3.5 py-3 text-status-warning-text",
15000
+ className: "rounded-lg border border-status-warning-text/25 bg-status-warning-bg px-3.5 py-3 text-status-warning-text",
14939
15001
  role: "alert",
14940
15002
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3", children: [
14941
15003
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: `mt-0.5 h-8 w-8 shrink-0 rounded-full flex items-center justify-center ${iconClass}`, children: /* @__PURE__ */ jsxRuntime.jsx(outline.ExclamationTriangleIcon, { className: "h-4 w-4", strokeWidth: 1.8 }) }),
@@ -15376,7 +15438,7 @@ function AddWalletsStep({ chrome } = {}) {
15376
15438
  showDynamic && /* @__PURE__ */ jsxRuntime.jsx(
15377
15439
  "div",
15378
15440
  {
15379
- className: "fixed inset-0 z-50 flex items-center justify-center bg-black/70 p-4",
15441
+ className: "fixed inset-0 z-[10000] flex items-center justify-center bg-black/70 p-4",
15380
15442
  role: "dialog",
15381
15443
  "aria-modal": "true",
15382
15444
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full max-w-md rounded-lg border border-border-default bg-surface p-4", children: [
@@ -15456,6 +15518,8 @@ var Drawer = ({
15456
15518
  React54.useEffect(() => {
15457
15519
  if (!isOpen || typeof document === "undefined") return;
15458
15520
  const previouslyFocused = document.activeElement;
15521
+ const bodyOverflow = document.body.style.overflow;
15522
+ document.body.style.overflow = "hidden";
15459
15523
  const initialFocus = panelRef.current?.querySelector("[data-drawer-initial-focus]") ?? closeButtonRef.current;
15460
15524
  initialFocus?.focus();
15461
15525
  const handleKeyDown = (event) => {
@@ -15486,11 +15550,16 @@ var Drawer = ({
15486
15550
  document.addEventListener("keydown", handleKeyDown);
15487
15551
  return () => {
15488
15552
  document.removeEventListener("keydown", handleKeyDown);
15553
+ document.body.style.overflow = bodyOverflow;
15489
15554
  previouslyFocused?.focus?.();
15490
15555
  };
15491
15556
  }, [isOpen, onClose]);
15492
- const widthClass = maxWidth === "sm" ? "w-full max-w-sm" : maxWidth === "md" ? "w-full max-w-md" : maxWidth === "lg" ? "w-full max-w-2xl" : maxWidth === "half" ? "w-1/2" : maxWidth === "full-mobile" ? "w-full xl:w-1/2" : maxWidth === "full" ? "w-full" : "w-full max-w-md";
15493
- const widthStyle = maxWidth === "lg" ? { width: "672px", maxWidth: "672px" } : maxWidth === "half" ? { width: "50vw", maxWidth: "50vw" } : maxWidth === "full-mobile" ? {} : {};
15557
+ const widthClass = maxWidth === "sm" ? "w-full max-w-sm" : maxWidth === "md" ? "w-full max-w-md" : maxWidth === "lg" ? "w-full max-w-2xl" : maxWidth === "half" ? "w-full lg:w-1/2" : maxWidth === "full-mobile" ? "w-full xl:w-1/2" : maxWidth === "full" ? "w-full" : "w-full max-w-md";
15558
+ const widthStyle = maxWidth === "lg" ? { width: "672px", maxWidth: "672px" } : (
15559
+ // 'half' is a desk shape; a hard 50vw made it 187px on a phone. The
15560
+ // class carries the split now, so there is no inline width to fight.
15561
+ maxWidth === "half" ? {} : maxWidth === "full-mobile" ? {} : {}
15562
+ );
15494
15563
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: isOpen && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 overflow-hidden z-[10000]", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-0 overflow-hidden", children: [
15495
15564
  /* @__PURE__ */ jsxRuntime.jsx(
15496
15565
  "div",
@@ -15527,12 +15596,12 @@ var Drawer = ({
15527
15596
  /* @__PURE__ */ jsxRuntime.jsx(
15528
15597
  "div",
15529
15598
  {
15530
- className: `flex-1 px-3 pt-2 ${panelBg} ${fillHeight ? "flex flex-col overflow-hidden pb-0" : "overflow-y-auto pb-6"} ${contentClassName}`,
15599
+ className: `flex-1 px-3 pt-2 ${panelBg} ${fillHeight ? "flex flex-col overflow-hidden pb-0" : "overflow-y-auto pb-[max(1.5rem,env(safe-area-inset-bottom))]"} ${contentClassName}`,
15531
15600
  style: contentStyle,
15532
15601
  children
15533
15602
  }
15534
15603
  ),
15535
- footer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `px-6 py-4 border-t border-border-default ${panelBg} flex-shrink-0 ${footerClassName}`, children: footer })
15604
+ footer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex-shrink-0 border-t border-border-default px-6 py-4 pb-[max(1rem,env(safe-area-inset-bottom))] ${panelBg} ${footerClassName}`, children: footer })
15536
15605
  ]
15537
15606
  }
15538
15607
  ) })
@@ -16139,7 +16208,7 @@ var AccountOpeningPanel = ({ onContinue, continueLabel = "Continue" }) => {
16139
16208
  /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-[16px] font-medium text-text-primary leading-snug", children: copy.title }),
16140
16209
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-[12px] leading-relaxed text-text-secondary", children: showExit && !terminalFailure ? "This is taking longer than usual. We'll let you know as soon as it's ready \u2014 you can carry on in the meantime." : copy.body })
16141
16210
  ] }),
16142
- terminalFailure ? null : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-1.5 w-full overflow-hidden rounded-full bg-border-default/40", children: /* @__PURE__ */ jsxRuntime.jsx(
16211
+ terminalFailure ? null : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-1.5 w-full overflow-hidden rounded-full bg-border-default", children: /* @__PURE__ */ jsxRuntime.jsx(
16143
16212
  "div",
16144
16213
  {
16145
16214
  className: `h-full w-2/3 rounded-full motion-safe:animate-pulse ${impatient ? "bg-status-warning-text" : "bg-cta"}`
@@ -20522,14 +20591,14 @@ function SignatureWorkflow({
20522
20591
  {
20523
20592
  id: `signature-${pending.id}`,
20524
20593
  type: "action",
20525
- title: "Signature Required",
20526
- message: "A queued action is waiting for your signature.",
20594
+ title: "Signature needed",
20595
+ message: "Something is waiting for your signature.",
20527
20596
  duration: 0,
20528
20597
  showProgress: false,
20529
20598
  onClose: dismissPending,
20530
20599
  onClick: () => openSigner(pending),
20531
20600
  action: {
20532
- label: "Review & Sign",
20601
+ label: "Review and sign",
20533
20602
  onClick: () => openSigner(pending)
20534
20603
  }
20535
20604
  }
@@ -20539,7 +20608,7 @@ function SignatureWorkflow({
20539
20608
  {
20540
20609
  isOpen: true,
20541
20610
  onClose: closeSigner,
20542
- title: currentMessage.data?.message_type ? `${currentMessage.data.message_type} \u2014 Sign` : "Sign Transaction",
20611
+ title: currentMessage.data?.message_type ? `${humanizeMessageType(currentMessage.data.message_type)} \u2014 Sign` : "Sign this request",
20543
20612
  maxWidth: "lg",
20544
20613
  fillHeight: true,
20545
20614
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col h-full", children: [
@@ -22168,10 +22237,10 @@ function SecurityPage() {
22168
22237
  const [generateDescription, setGenerateDescription] = React54.useState("");
22169
22238
  const [freshApiKey, setFreshApiKey] = React54.useState(null);
22170
22239
  const [freshApiKeyCopied, setFreshApiKeyCopied] = React54.useState(false);
22171
- const refresh = React54.useCallback(async () => {
22240
+ const refresh = React54.useCallback(async (opts) => {
22172
22241
  setError(null);
22173
22242
  try {
22174
- invalidateWalletCount();
22243
+ if (opts?.invalidate !== false) invalidateWalletCount();
22175
22244
  const [k, l] = await Promise.all([
22176
22245
  listMyLoginKeys(),
22177
22246
  keysService.getLockdownStatus().catch(() => null)
@@ -22185,7 +22254,7 @@ function SecurityPage() {
22185
22254
  }
22186
22255
  }, []);
22187
22256
  React54.useEffect(() => {
22188
- refresh();
22257
+ void refresh({ invalidate: false });
22189
22258
  }, [refresh]);
22190
22259
  const refreshApiKeys = React54.useCallback(async () => {
22191
22260
  try {
@@ -23023,7 +23092,7 @@ function SecurityPage() {
23023
23092
  (account) => !(account.chain_id === activeChainId && account.wallet_address.toLowerCase() === target)
23024
23093
  );
23025
23094
  if (otherAccounts.length === 0) return null;
23026
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg bg-status-warning-bg/30 border border-status-warning-text/30 px-3 py-2 space-y-1", children: [
23095
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg bg-status-warning-bg border border-status-warning-text/30 px-3 py-2 space-y-1", children: [
23027
23096
  /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-[11px] text-status-warning-text font-medium", children: [
23028
23097
  "This key also owns ",
23029
23098
  otherAccounts.length,
@@ -23338,7 +23407,7 @@ function RowGhostButton({
23338
23407
  type: "button",
23339
23408
  disabled,
23340
23409
  onClick,
23341
- className: "text-[11px] font-medium px-2.5 py-1 rounded-md text-text-secondary hover:text-text-primary hover:bg-chip disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
23410
+ className: "rounded-md px-2.5 py-1 text-[11px] font-medium text-text-secondary transition-colors hover:bg-chip hover:text-text-primary active:bg-chip-active disabled:cursor-not-allowed disabled:opacity-50 max-lg:min-h-[44px] max-lg:px-4 max-lg:text-[13px]",
23342
23411
  children
23343
23412
  }
23344
23413
  );
@@ -23354,7 +23423,7 @@ function RowNeutralButton({
23354
23423
  type: "button",
23355
23424
  disabled,
23356
23425
  onClick,
23357
- className: "text-[11px] font-medium px-2.5 py-1 rounded-md bg-chip text-text-primary hover:bg-chip-hover disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
23426
+ className: "rounded-md bg-chip px-2.5 py-1 text-[11px] font-medium text-text-primary transition-colors hover:bg-chip-hover active:bg-chip-active disabled:cursor-not-allowed disabled:opacity-50 max-lg:min-h-[44px] max-lg:px-4 max-lg:text-[13px]",
23358
23427
  children
23359
23428
  }
23360
23429
  );
@@ -25165,7 +25234,10 @@ var WalletCenterSurface = ({
25165
25234
  modules,
25166
25235
  actors,
25167
25236
  identity,
25168
- initialView = "menu"
25237
+ initialView = "menu",
25238
+ embedded = false,
25239
+ backLabel = "Back",
25240
+ onTitle
25169
25241
  }) => {
25170
25242
  const { pendingList, refreshPending } = useSignatureQueue();
25171
25243
  const {
@@ -25193,6 +25265,10 @@ var WalletCenterSurface = ({
25193
25265
  const cancelGuardRef = React54.useRef(/* @__PURE__ */ new Map());
25194
25266
  const wasOpenRef = React54.useRef(false);
25195
25267
  const walletRootRef = React54.useRef(null);
25268
+ const leaveSection = React54.useCallback(() => {
25269
+ if (embedded && initialView !== "menu") onClose();
25270
+ else setSection("menu");
25271
+ }, [embedded, initialView, onClose]);
25196
25272
  React54.useEffect(() => {
25197
25273
  const justOpened = isOpen && !wasOpenRef.current;
25198
25274
  wasOpenRef.current = isOpen;
@@ -25210,9 +25286,9 @@ var WalletCenterSurface = ({
25210
25286
  React54.useEffect(() => {
25211
25287
  if (!isOpen) return;
25212
25288
  if (activeBuiltinFor(section, modules) === "transactions" && pendingList.length === 0) {
25213
- setSection("menu");
25289
+ leaveSection();
25214
25290
  }
25215
- }, [isOpen, modules, pendingList.length, section]);
25291
+ }, [isOpen, leaveSection, modules, pendingList.length, section]);
25216
25292
  const delegatedGroupId = React54.useMemo(() => {
25217
25293
  if (!delegationToken || typeof window === "undefined") return null;
25218
25294
  return window.localStorage.getItem("delegation_group_id");
@@ -25465,11 +25541,11 @@ var WalletCenterSurface = ({
25465
25541
  setActionError(null);
25466
25542
  try {
25467
25543
  await actor.onSelect();
25468
- setSection("menu");
25544
+ leaveSection();
25469
25545
  } catch (error) {
25470
25546
  setActionError(error?.message ?? "Failed to switch signing context.");
25471
25547
  }
25472
- }, []);
25548
+ }, [leaveSection]);
25473
25549
  const drawerTitle = React54.useMemo(() => {
25474
25550
  if (selected) {
25475
25551
  const label = humanizeMessageType(selected.data?.message_type);
@@ -25477,11 +25553,117 @@ var WalletCenterSurface = ({
25477
25553
  }
25478
25554
  return "Wallet";
25479
25555
  }, [selected, selectedSource]);
25556
+ const hostedTitle = !embedded ? null : selected ? drawerTitle : section === "actors" ? "Signing context" : activeModule?.label ?? null;
25557
+ React54.useEffect(() => {
25558
+ if (!embedded) return void 0;
25559
+ onTitle?.(hostedTitle);
25560
+ return () => onTitle?.(null);
25561
+ }, [embedded, hostedTitle, onTitle]);
25480
25562
  const isCompactView = !selected;
25481
25563
  const drawerPanelClass = isCompactView ? stripLayoutUtilities(walletCenterUi?.drawer?.panel, ["height"]) : walletCenterUi?.drawer?.panel;
25482
25564
  const drawerContentClass = isCompactView ? stripLayoutUtilities(walletCenterUi?.drawer?.content, ["overflow"]) : walletCenterUi?.drawer?.content;
25483
- const walletRootClass = isCompactView ? stripLayoutUtilities(walletCenterUi?.root, ["height", "overflow"]) : walletCenterUi?.root;
25484
- const walletMainClass = isCompactView ? stripLayoutUtilities(walletCenterUi?.main, ["height", "overflow"]) : walletCenterUi?.main;
25565
+ const walletRootClass = embedded ? void 0 : isCompactView ? stripLayoutUtilities(walletCenterUi?.root, ["height", "overflow"]) : walletCenterUi?.root;
25566
+ const walletMainClass = embedded ? void 0 : isCompactView ? stripLayoutUtilities(walletCenterUi?.main, ["height", "overflow"]) : walletCenterUi?.main;
25567
+ const body = /* @__PURE__ */ jsxRuntime.jsx("div", { ref: walletRootRef, className: cx4(isCompactView ? "w-full" : "flex h-full overflow-hidden", walletRootClass), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cx4(isCompactView ? "min-h-0 w-full" : "flex-1 min-h-0 overflow-hidden", walletMainClass), children: selected ? /* @__PURE__ */ jsxRuntime.jsx(
25568
+ DetailPane,
25569
+ {
25570
+ message: selected,
25571
+ source: selectedSource,
25572
+ userId,
25573
+ onBack: handleBackToList,
25574
+ hideBack: embedded,
25575
+ onSigned: async (m) => {
25576
+ onSigned?.(m);
25577
+ setSelected(null);
25578
+ await refreshPending();
25579
+ },
25580
+ onRetry: handleRetry,
25581
+ onSwitchToSign: () => setSelectedSource("pending"),
25582
+ selectorRegistry,
25583
+ addressLabels,
25584
+ renderSimpleSummary
25585
+ }
25586
+ ) : section === "menu" ? /* @__PURE__ */ jsxRuntime.jsx(
25587
+ WalletMenu,
25588
+ {
25589
+ identity: resolvedIdentity,
25590
+ items: menuItems,
25591
+ actors: resolvedActors,
25592
+ actionError,
25593
+ onSelectModule: handleSelectModule,
25594
+ onOpenActors: () => setSection("actors"),
25595
+ onClose: embedded ? void 0 : onClose,
25596
+ onSignOut: handleSignOut
25597
+ }
25598
+ ) : section === "actors" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-col", children: [
25599
+ embedded ? null : /* @__PURE__ */ jsxRuntime.jsx(SectionHeader, { title: "Signing context", onBack: leaveSection }),
25600
+ /* @__PURE__ */ jsxRuntime.jsx(
25601
+ ActorsPane,
25602
+ {
25603
+ actors: resolvedActors,
25604
+ error: actionError,
25605
+ onSelect: handleSelectActor
25606
+ }
25607
+ )
25608
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-col", children: [
25609
+ embedded ? null : /* @__PURE__ */ jsxRuntime.jsx(SectionHeader, { title: activeModule?.label ?? "Wallet", onBack: leaveSection }),
25610
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0", children: activeModule ? /* @__PURE__ */ jsxRuntime.jsx(
25611
+ SectionPane,
25612
+ {
25613
+ module: activeModule,
25614
+ panelContext,
25615
+ pendingList,
25616
+ busyId,
25617
+ actionError,
25618
+ onSelectPending: (m) => handleSelect(m, "pending"),
25619
+ onSign: handleSign,
25620
+ onCancel: handleCancel,
25621
+ historyItems: filteredHistoryItems,
25622
+ historyFilter,
25623
+ historyLoading,
25624
+ historyError,
25625
+ historyHasMore: historyHasMore && historyItems.length < HISTORY_MAX_ITEMS,
25626
+ historyAtCap: historyItems.length >= HISTORY_MAX_ITEMS,
25627
+ historyLoadedOnce,
25628
+ showHistoryFilters: !embedded,
25629
+ onFilterChange: handleFilterChange,
25630
+ onLoadMore: handleLoadMore,
25631
+ onSelectHistory: (m) => handleSelect(m, "history"),
25632
+ onRetry: handleRetryFromRow,
25633
+ classNames: walletCenterUi
25634
+ }
25635
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
25636
+ EmptyState,
25637
+ {
25638
+ title: "This wallet view is unavailable",
25639
+ subtitle: "Return to the wallet menu and choose another destination.",
25640
+ classNames: walletCenterUi
25641
+ }
25642
+ ) })
25643
+ ] }) }) });
25644
+ if (embedded) {
25645
+ const back = selected ? { label: activeModule?.label ?? "Wallet", onPick: handleBackToList } : section === "menu" ? null : { label: backLabel, onPick: leaveSection };
25646
+ const sectionControls = !selected && activeBuiltin === "history" ? /* @__PURE__ */ jsxRuntime.jsx(FilterChips, { filter: historyFilter, onChange: handleFilterChange }) : null;
25647
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full min-h-0 flex-col", children: [
25648
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: cx4("min-h-0 flex-1", isCompactView ? "overflow-y-auto" : "overflow-hidden"), children: body }),
25649
+ back || sectionControls ? /* @__PURE__ */ jsxRuntime.jsxs("nav", { "aria-label": "Wallet controls", className: "flex h-12 shrink-0 items-center gap-2 border-t border-border-light px-4", children: [
25650
+ back ? /* @__PURE__ */ jsxRuntime.jsxs(
25651
+ "button",
25652
+ {
25653
+ type: "button",
25654
+ onClick: back.onPick,
25655
+ className: "flex h-8 shrink-0 items-center gap-1.5 rounded-full bg-chip-hover pl-2 pr-3 text-[12.5px] font-medium text-text-primary transition-colors hover:bg-raised-hover",
25656
+ children: [
25657
+ /* @__PURE__ */ jsxRuntime.jsx(IconChevronLeft, {}),
25658
+ back.label
25659
+ ]
25660
+ }
25661
+ ) : null,
25662
+ back && sectionControls ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-5 w-px shrink-0 bg-border-strong", "aria-hidden": "true" }) : null,
25663
+ sectionControls ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-0 flex-1 items-center gap-2 overflow-x-auto", children: sectionControls }) : null
25664
+ ] }) : null
25665
+ ] });
25666
+ }
25485
25667
  return /* @__PURE__ */ jsxRuntime.jsx(
25486
25668
  Drawer,
25487
25669
  {
@@ -25499,89 +25681,7 @@ var WalletCenterSurface = ({
25499
25681
  closeButtonClassName: walletCenterUi?.drawer?.closeButton,
25500
25682
  contentClassName: drawerContentClass,
25501
25683
  contentStyle: isCompactView ? { flex: "0 1 auto", maxHeight: "calc(100vh - 24px)", overflowY: "auto", paddingBottom: 12 } : void 0,
25502
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: walletRootRef, className: cx4(isCompactView ? "w-full" : "flex h-full overflow-hidden", walletRootClass), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cx4(isCompactView ? "min-h-0 w-full" : "flex-1 min-h-0 overflow-hidden", walletMainClass), children: selected ? /* @__PURE__ */ jsxRuntime.jsx(
25503
- DetailPane,
25504
- {
25505
- message: selected,
25506
- source: selectedSource,
25507
- userId,
25508
- onBack: handleBackToList,
25509
- onSigned: async (m) => {
25510
- onSigned?.(m);
25511
- setSelected(null);
25512
- await refreshPending();
25513
- },
25514
- onRetry: handleRetry,
25515
- onSwitchToSign: () => setSelectedSource("pending"),
25516
- selectorRegistry,
25517
- addressLabels,
25518
- renderSimpleSummary
25519
- }
25520
- ) : section === "menu" ? /* @__PURE__ */ jsxRuntime.jsx(
25521
- WalletMenu,
25522
- {
25523
- identity: resolvedIdentity,
25524
- items: menuItems,
25525
- actors: resolvedActors,
25526
- actionError,
25527
- onSelectModule: handleSelectModule,
25528
- onOpenActors: () => setSection("actors"),
25529
- onClose,
25530
- onSignOut: handleSignOut
25531
- }
25532
- ) : section === "actors" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-col", children: [
25533
- /* @__PURE__ */ jsxRuntime.jsx(SectionHeader, { title: "Signing context", onBack: () => setSection("menu") }),
25534
- /* @__PURE__ */ jsxRuntime.jsx(
25535
- ActorsPane,
25536
- {
25537
- actors: resolvedActors,
25538
- error: actionError,
25539
- onSelect: handleSelectActor
25540
- }
25541
- )
25542
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-col", children: [
25543
- /* @__PURE__ */ jsxRuntime.jsx(
25544
- SectionHeader,
25545
- {
25546
- title: activeModule?.label ?? "Wallet",
25547
- onBack: () => {
25548
- setSection("menu");
25549
- }
25550
- }
25551
- ),
25552
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0", children: activeModule ? /* @__PURE__ */ jsxRuntime.jsx(
25553
- SectionPane,
25554
- {
25555
- module: activeModule,
25556
- panelContext,
25557
- pendingList,
25558
- busyId,
25559
- actionError,
25560
- onSelectPending: (m) => handleSelect(m, "pending"),
25561
- onSign: handleSign,
25562
- onCancel: handleCancel,
25563
- historyItems: filteredHistoryItems,
25564
- historyFilter,
25565
- historyLoading,
25566
- historyError,
25567
- historyHasMore: historyHasMore && historyItems.length < HISTORY_MAX_ITEMS,
25568
- historyAtCap: historyItems.length >= HISTORY_MAX_ITEMS,
25569
- historyLoadedOnce,
25570
- onFilterChange: handleFilterChange,
25571
- onLoadMore: handleLoadMore,
25572
- onSelectHistory: (m) => handleSelect(m, "history"),
25573
- onRetry: handleRetryFromRow,
25574
- classNames: walletCenterUi
25575
- }
25576
- ) : /* @__PURE__ */ jsxRuntime.jsx(
25577
- EmptyState,
25578
- {
25579
- title: "This wallet view is unavailable",
25580
- subtitle: "Return to the wallet menu and choose another destination.",
25581
- classNames: walletCenterUi
25582
- }
25583
- ) })
25584
- ] }) }) })
25684
+ children: body
25585
25685
  }
25586
25686
  );
25587
25687
  };
@@ -25703,7 +25803,7 @@ function WalletMenu({
25703
25803
  action.id
25704
25804
  );
25705
25805
  }),
25706
- /* @__PURE__ */ jsxRuntime.jsx(
25806
+ onClose ? /* @__PURE__ */ jsxRuntime.jsx(
25707
25807
  "button",
25708
25808
  {
25709
25809
  type: "button",
@@ -25713,7 +25813,7 @@ function WalletMenu({
25713
25813
  "aria-label": "Close wallet center",
25714
25814
  children: /* @__PURE__ */ jsxRuntime.jsx(IconX, {})
25715
25815
  }
25716
- )
25816
+ ) : null
25717
25817
  ] })
25718
25818
  ] }),
25719
25819
  /* @__PURE__ */ jsxRuntime.jsx(ActiveEnvironmentBadge, {})
@@ -25844,6 +25944,7 @@ function SectionPane(props) {
25844
25944
  {
25845
25945
  items: props.historyItems,
25846
25946
  filter: props.historyFilter,
25947
+ showFilters: props.showHistoryFilters ?? true,
25847
25948
  onFilterChange: props.onFilterChange,
25848
25949
  loading: props.historyLoading,
25849
25950
  error: props.historyError,
@@ -26075,6 +26176,7 @@ function PendingSection({
26075
26176
  )) });
26076
26177
  }
26077
26178
  function HistorySection({
26179
+ showFilters = true,
26078
26180
  items,
26079
26181
  filter,
26080
26182
  onFilterChange,
@@ -26090,7 +26192,7 @@ function HistorySection({
26090
26192
  classNames
26091
26193
  }) {
26092
26194
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx4("p-3 space-y-3", classNames?.listSection), children: [
26093
- /* @__PURE__ */ jsxRuntime.jsx(FilterChips, { filter, onChange: onFilterChange }),
26195
+ showFilters ? /* @__PURE__ */ jsxRuntime.jsx(FilterChips, { filter, onChange: onFilterChange }) : null,
26094
26196
  error && /* @__PURE__ */ jsxRuntime.jsx(ErrorBanner, { children: error }),
26095
26197
  !loadedOnce && loading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-10 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(LoadingSpinner, { size: "md" }) }),
26096
26198
  loadedOnce && items.length === 0 && !loading && /* @__PURE__ */ jsxRuntime.jsx(
@@ -26173,6 +26275,7 @@ function DetailPane({
26173
26275
  source,
26174
26276
  userId,
26175
26277
  onBack,
26278
+ hideBack = false,
26176
26279
  onSigned,
26177
26280
  onRetry,
26178
26281
  onSwitchToSign,
@@ -26182,7 +26285,7 @@ function DetailPane({
26182
26285
  }) {
26183
26286
  const drawerKey = `signature-${source}-${message.id}`;
26184
26287
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col h-full", children: [
26185
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-2.5 border-b border-border-light", children: /* @__PURE__ */ jsxRuntime.jsxs(
26288
+ hideBack ? null : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-2.5 border-b border-border-light", children: /* @__PURE__ */ jsxRuntime.jsxs(
26186
26289
  "button",
26187
26290
  {
26188
26291
  type: "button",
@@ -26267,9 +26370,9 @@ function WalletCenter({
26267
26370
  onCanceled
26268
26371
  }) {
26269
26372
  const { user } = useAuth();
26270
- const { isOpen, requestedView, closeWalletCenter } = useWalletCenter();
26373
+ const { isOpen, requestedView, closeWalletCenter, host, hostOptions, setHostTitle } = useWalletCenter();
26271
26374
  if (!isOpen || !user?.id) return null;
26272
- return /* @__PURE__ */ jsxRuntime.jsx(
26375
+ const surface = /* @__PURE__ */ jsxRuntime.jsx(
26273
26376
  WalletCenterSurface,
26274
26377
  {
26275
26378
  isOpen: true,
@@ -26284,9 +26387,13 @@ function WalletCenter({
26284
26387
  renderSimpleSummary,
26285
26388
  onSigned,
26286
26389
  onRetried,
26287
- onCanceled
26390
+ onCanceled,
26391
+ embedded: Boolean(host),
26392
+ backLabel: hostOptions.backLabel,
26393
+ onTitle: setHostTitle
26288
26394
  }
26289
26395
  );
26396
+ return host ? reactDom.createPortal(surface, host) : surface;
26290
26397
  }
26291
26398
  function WalletCenterTrigger({
26292
26399
  variant = "icon",
@@ -30745,7 +30852,7 @@ var PendingPaymentCard = ({
30745
30852
  {
30746
30853
  className: [
30747
30854
  "flex items-center gap-3 px-3 py-2 border-b transition-colors",
30748
- isHighlighted ? "border-status-warning-text/40 bg-status-warning-bg/30" : "border-border-light hover:bg-chip",
30855
+ isHighlighted ? "border-status-warning-text/40 bg-status-warning-bg" : "border-border-light hover:bg-chip",
30749
30856
  className
30750
30857
  ].join(" "),
30751
30858
  children: [
@@ -30813,7 +30920,7 @@ var PendingPaymentCard = ({
30813
30920
  {
30814
30921
  className: [
30815
30922
  "rounded-lg border p-4 transition-shadow",
30816
- isHighlighted ? "border-status-warning-text/40 bg-status-warning-bg/40" : "border-border-default bg-surface",
30923
+ isHighlighted ? "border-status-warning-text/40 bg-status-warning-bg" : "border-border-default bg-surface",
30817
30924
  "hover:shadow-sm",
30818
30925
  className
30819
30926
  ].join(" "),
@@ -31704,6 +31811,7 @@ exports.snapshotNeedsPrepaidPlan = snapshotNeedsPrepaidPlan;
31704
31811
  exports.startMyEmailVerification = startMyEmailVerification;
31705
31812
  exports.statusToColor = statusToColor;
31706
31813
  exports.subscribeEntityEvents = subscribeEntityEvents;
31814
+ exports.subscribeJsonEvents = subscribeJsonEvents;
31707
31815
  exports.switchChain = switchChain;
31708
31816
  exports.syntheticPasskeyAddress = syntheticPasskeyAddress;
31709
31817
  exports.testChainIds = testChainIds;