@hfunlabs/hypurr-connect 0.1.14 → 0.1.15

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
@@ -1,3 +1,28 @@
1
+ // #style-inject:#style-inject
2
+ function styleInject(css, { insertAt } = {}) {
3
+ if (!css || typeof document === "undefined") return;
4
+ const head = document.head || document.getElementsByTagName("head")[0];
5
+ const style = document.createElement("style");
6
+ style.type = "text/css";
7
+ if (insertAt === "top") {
8
+ if (head.firstChild) {
9
+ head.insertBefore(style, head.firstChild);
10
+ } else {
11
+ head.appendChild(style);
12
+ }
13
+ } else {
14
+ head.appendChild(style);
15
+ }
16
+ if (style.styleSheet) {
17
+ style.styleSheet.cssText = css;
18
+ } else {
19
+ style.appendChild(document.createTextNode(css));
20
+ }
21
+ }
22
+
23
+ // src/styles.css
24
+ styleInject(".hypurr-connect .btn-raised {\n background-color: #0d1219;\n background-image:\n linear-gradient(\n 180deg,\n hsla(0, 0%, 100%, .03),\n transparent);\n box-shadow:\n inset 0 1px 0 hsla(0, 0%, 100%, .1),\n inset 0 -1px 0 rgba(0, 0, 0, .35),\n inset 0 0 0 1px #262a30;\n color: #aab1c1;\n transition:\n background-color .15s,\n color .15s,\n background-image .15s,\n box-shadow .15s;\n}\n.hypurr-connect .btn-raised:hover:not(:disabled) {\n background-color: #15171a;\n background-image:\n linear-gradient(\n 180deg,\n hsla(0, 0%, 100%, .04),\n transparent);\n box-shadow:\n inset 0 1px 0 hsla(0, 0%, 100%, .14),\n inset 0 -1px 0 rgba(0, 0, 0, .4),\n inset 0 0 0 1px #444548;\n color: #d1d5db;\n}\n.hypurr-connect .btn-raised-active {\n background-color: #1e2124;\n background-image:\n linear-gradient(\n 180deg,\n hsla(0, 0%, 100%, .05),\n transparent);\n box-shadow:\n inset 0 1px 0 hsla(0, 0%, 100%, .18),\n inset 0 -1px 0 rgba(0, 0, 0, .45),\n inset 0 0 0 1px #4b4d50,\n 0 1px 2px rgba(0, 0, 0, .5);\n color: #fff;\n}\n.hypurr-connect .btn-raised-active,\n.hypurr-connect .btn-raised-disabled {\n transition:\n background-color .15s,\n color .15s,\n background-image .15s,\n box-shadow .15s;\n}\n.hypurr-connect .btn-raised-disabled {\n background-color: #0d1219;\n background-image:\n linear-gradient(\n 180deg,\n hsla(0, 0%, 100%, .02),\n transparent);\n box-shadow:\n inset 0 1px 0 hsla(0, 0%, 100%, .05),\n inset 0 -1px 0 rgba(0, 0, 0, .25),\n inset 0 0 0 1px #1c2026;\n color: #7d8597;\n cursor: not-allowed;\n}\n.hypurr-connect .\\!visible {\n visibility: visible !important;\n}\n.hypurr-connect .visible {\n visibility: visible;\n}\n.hypurr-connect .fixed {\n position: fixed;\n}\n.hypurr-connect .absolute {\n position: absolute;\n}\n.hypurr-connect .relative {\n position: relative;\n}\n.hypurr-connect .inset-0 {\n inset: 0;\n}\n.hypurr-connect .right-2 {\n right: .5rem;\n}\n.hypurr-connect .right-6 {\n right: 1.5rem;\n}\n.hypurr-connect .top-1\\/2 {\n top: 50%;\n}\n.hypurr-connect .z-\\[100\\] {\n z-index: 100;\n}\n.hypurr-connect .z-\\[101\\] {\n z-index: 101;\n}\n.hypurr-connect .z-\\[110\\] {\n z-index: 110;\n}\n.hypurr-connect .z-\\[111\\] {\n z-index: 111;\n}\n.hypurr-connect .mb-1\\.5 {\n margin-bottom: .375rem;\n}\n.hypurr-connect .mb-2 {\n margin-bottom: .5rem;\n}\n.hypurr-connect .mt-0\\.5 {\n margin-top: .125rem;\n}\n.hypurr-connect .mt-1 {\n margin-top: .25rem;\n}\n.hypurr-connect .mt-1\\.5 {\n margin-top: .375rem;\n}\n.hypurr-connect .block {\n display: block;\n}\n.hypurr-connect .inline-block {\n display: inline-block;\n}\n.hypurr-connect .inline {\n display: inline;\n}\n.hypurr-connect .flex {\n display: flex;\n}\n.hypurr-connect .inline-flex {\n display: inline-flex;\n}\n.hypurr-connect .grid {\n display: grid;\n}\n.hypurr-connect .contents {\n display: contents;\n}\n.hypurr-connect .hidden {\n display: none;\n}\n.hypurr-connect .h-8 {\n height: 2rem;\n}\n.hypurr-connect .w-8 {\n width: 2rem;\n}\n.hypurr-connect .w-full {\n width: 100%;\n}\n.hypurr-connect .min-w-0 {\n min-width: 0;\n}\n.hypurr-connect .max-w-md {\n max-width: 28rem;\n}\n.hypurr-connect .flex-1 {\n flex: 1 1 0%;\n}\n.hypurr-connect .flex-shrink-0 {\n flex-shrink: 0;\n}\n.hypurr-connect .-translate-y-1\\/2 {\n --tw-translate-y:-50%;\n}\n.hypurr-connect .-translate-y-1\\/2,\n.hypurr-connect .transform {\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.hypurr-connect .cursor-not-allowed {\n cursor: not-allowed;\n}\n.hypurr-connect .grid-cols-4 {\n grid-template-columns: repeat(4, minmax(0, 1fr));\n}\n.hypurr-connect .items-start {\n align-items: flex-start;\n}\n.hypurr-connect .items-center {\n align-items: center;\n}\n.hypurr-connect .justify-center {\n justify-content: center;\n}\n.hypurr-connect .justify-between {\n justify-content: space-between;\n}\n.hypurr-connect .gap-1\\.5 {\n gap: .375rem;\n}\n.hypurr-connect .gap-2 {\n gap: .5rem;\n}\n.hypurr-connect .gap-3 {\n gap: .75rem;\n}\n.hypurr-connect :is(.space-y-2 > :not([hidden]) ~ :not([hidden])) {\n --tw-space-y-reverse:0;\n margin-top: calc(.5rem*(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(.5rem*var(--tw-space-y-reverse));\n}\n.hypurr-connect :is(.space-y-3 > :not([hidden]) ~ :not([hidden])) {\n --tw-space-y-reverse:0;\n margin-top: calc(.75rem*(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(.75rem*var(--tw-space-y-reverse));\n}\n.hypurr-connect :is(.space-y-4 > :not([hidden]) ~ :not([hidden])) {\n --tw-space-y-reverse:0;\n margin-top: calc(1rem*(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(1rem*var(--tw-space-y-reverse));\n}\n.hypurr-connect .overflow-hidden {\n overflow: hidden;\n}\n.hypurr-connect .truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.hypurr-connect .break-all {\n word-break: break-all;\n}\n.hypurr-connect .rounded {\n border-radius: .25rem;\n}\n.hypurr-connect .rounded-lg {\n border-radius: .5rem;\n}\n.hypurr-connect .rounded-md {\n border-radius: .375rem;\n}\n.hypurr-connect .border {\n border-width: 1px;\n}\n.hypurr-connect .border-b {\n border-bottom-width: 1px;\n}\n.hypurr-connect .border-amber-500\\/25 {\n border-color: rgba(245, 158, 11, .25);\n}\n.hypurr-connect .border-gray-700 {\n --tw-border-opacity:1;\n border-color: rgb(55 65 81/var(--tw-border-opacity,1));\n}\n.hypurr-connect .border-purple-500 {\n --tw-border-opacity:1;\n border-color: rgb(185 125 241/var(--tw-border-opacity,1));\n}\n.hypurr-connect .border-surface-bd {\n --tw-border-opacity:1;\n border-color: rgb(38 42 48/var(--tw-border-opacity,1));\n}\n.hypurr-connect .border-trade-down\\/20 {\n border-color: hsla(0, 91%, 71%, .2);\n}\n.hypurr-connect .border-trade-down\\/50 {\n border-color: hsla(0, 91%, 71%, .5);\n}\n.hypurr-connect .border-white\\/\\[0\\.06\\] {\n border-color: hsla(0, 0%, 100%, .06);\n}\n.hypurr-connect .border-white\\/\\[0\\.08\\] {\n border-color: hsla(0, 0%, 100%, .08);\n}\n.hypurr-connect .bg-amber-500\\/\\[0\\.08\\] {\n background-color: rgba(245, 158, 11, .08);\n}\n.hypurr-connect .bg-black\\/70 {\n background-color: rgba(0, 0, 0, .7);\n}\n.hypurr-connect .bg-surface-btn\\/90 {\n background-color: rgba(13, 18, 25, .9);\n}\n.hypurr-connect .bg-surface-modal {\n --tw-bg-opacity:1;\n background-color: rgb(14 18 24/var(--tw-bg-opacity,1));\n}\n.hypurr-connect .bg-trade-down\\/\\[0\\.08\\] {\n background-color: hsla(0, 91%, 71%, .08);\n}\n.hypurr-connect .bg-transparent {\n background-color: transparent;\n}\n.hypurr-connect .bg-white\\/\\[0\\.03\\] {\n background-color: hsla(0, 0%, 100%, .03);\n}\n.hypurr-connect .bg-white\\/\\[0\\.06\\] {\n background-color: hsla(0, 0%, 100%, .06);\n}\n.hypurr-connect .p-1\\.5 {\n padding: .375rem;\n}\n.hypurr-connect .p-3 {\n padding: .75rem;\n}\n.hypurr-connect .p-4 {\n padding: 1rem;\n}\n.hypurr-connect .px-3 {\n padding-left: .75rem;\n padding-right: .75rem;\n}\n.hypurr-connect .px-6 {\n padding-left: 1.5rem;\n padding-right: 1.5rem;\n}\n.hypurr-connect .py-1\\.5 {\n padding-top: .375rem;\n padding-bottom: .375rem;\n}\n.hypurr-connect .py-2 {\n padding-top: .5rem;\n padding-bottom: .5rem;\n}\n.hypurr-connect .py-2\\.5 {\n padding-top: .625rem;\n padding-bottom: .625rem;\n}\n.hypurr-connect .py-5 {\n padding-top: 1.25rem;\n}\n.hypurr-connect .pb-5,\n.hypurr-connect .py-5 {\n padding-bottom: 1.25rem;\n}\n.hypurr-connect .pb-6 {\n padding-bottom: 1.5rem;\n}\n.hypurr-connect .pr-11 {\n padding-right: 2.75rem;\n}\n.hypurr-connect .pt-5 {\n padding-top: 1.25rem;\n}\n.hypurr-connect .pt-6 {\n padding-top: 1.5rem;\n}\n.hypurr-connect .font-mono {\n font-family:\n Google Sans Code,\n Roboto Mono,\n ui-monospace,\n SFMono-Regular,\n Menlo,\n Monaco,\n Consolas,\n monospace;\n}\n.hypurr-connect .font-sans {\n font-family:\n Inter,\n ui-sans-serif,\n system-ui,\n -apple-system,\n BlinkMacSystemFont,\n Segoe UI,\n Roboto,\n Helvetica Neue,\n Arial,\n sans-serif;\n}\n.hypurr-connect .text-base {\n font-size: 12.5px;\n line-height: 1rem;\n}\n.hypurr-connect .text-lg {\n font-size: 14px;\n line-height: 1.25rem;\n}\n.hypurr-connect .font-medium {\n font-weight: 500;\n}\n.hypurr-connect .font-semibold {\n font-weight: 600;\n}\n.hypurr-connect .uppercase {\n text-transform: uppercase;\n}\n.hypurr-connect .tabular-nums {\n --tw-numeric-spacing:tabular-nums;\n font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction);\n}\n.hypurr-connect .tracking-\\[0\\.1em\\] {\n letter-spacing: .1em;\n}\n.hypurr-connect .text-amber-200 {\n --tw-text-opacity:1;\n color: rgb(253 230 138/var(--tw-text-opacity,1));\n}\n.hypurr-connect .text-amber-400 {\n --tw-text-opacity:1;\n color: rgb(251 191 36/var(--tw-text-opacity,1));\n}\n.hypurr-connect .text-gray-400 {\n --tw-text-opacity:1;\n color: rgb(170 177 193/var(--tw-text-opacity,1));\n}\n.hypurr-connect .text-gray-500 {\n --tw-text-opacity:1;\n color: rgb(107 114 128/var(--tw-text-opacity,1));\n}\n.hypurr-connect .text-gray-600 {\n --tw-text-opacity:1;\n color: rgb(125 133 151/var(--tw-text-opacity,1));\n}\n.hypurr-connect .text-purple-400 {\n --tw-text-opacity:1;\n color: rgb(216 180 254/var(--tw-text-opacity,1));\n}\n.hypurr-connect .text-trade-down {\n --tw-text-opacity:1;\n color: rgb(248 113 113/var(--tw-text-opacity,1));\n}\n.hypurr-connect .text-trade-up {\n --tw-text-opacity:1;\n color: rgb(52 211 153/var(--tw-text-opacity,1));\n}\n.hypurr-connect .text-white {\n --tw-text-opacity:1;\n color: rgb(255 255 255/var(--tw-text-opacity,1));\n}\n.hypurr-connect .placeholder-gray-600::-moz-placeholder {\n --tw-placeholder-opacity:1;\n color: rgb(125 133 151/var(--tw-placeholder-opacity,1));\n}\n.hypurr-connect .placeholder-gray-600::placeholder {\n --tw-placeholder-opacity:1;\n color: rgb(125 133 151/var(--tw-placeholder-opacity,1));\n}\n.hypurr-connect .shadow-modal {\n --tw-shadow:0 25px 50px -12px rgba(0,0,0,.6);\n --tw-shadow-colored:0 25px 50px -12px var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow,0 0 #0000),\n var(--tw-ring-shadow,0 0 #0000),\n var(--tw-shadow);\n}\n.hypurr-connect .outline {\n outline-style: solid;\n}\n.hypurr-connect .blur {\n --tw-blur:blur(8px);\n}\n.hypurr-connect .blur,\n.hypurr-connect .drop-shadow {\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\n}\n.hypurr-connect .drop-shadow {\n --tw-drop-shadow:drop-shadow(0 1px 2px rgba(0,0,0,.1)) drop-shadow(0 1px 1px rgba(0,0,0,.06));\n}\n.hypurr-connect .filter {\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\n}\n.hypurr-connect .backdrop-blur-sm {\n --tw-backdrop-blur:blur(4px);\n -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);\n backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);\n}\n.hypurr-connect .transition {\n transition-property:\n color,\n background-color,\n border-color,\n text-decoration-color,\n fill,\n stroke,\n opacity,\n box-shadow,\n transform,\n filter,\n -webkit-backdrop-filter;\n transition-property:\n color,\n background-color,\n border-color,\n text-decoration-color,\n fill,\n stroke,\n opacity,\n box-shadow,\n transform,\n filter,\n backdrop-filter;\n transition-property:\n color,\n background-color,\n border-color,\n text-decoration-color,\n fill,\n stroke,\n opacity,\n box-shadow,\n transform,\n filter,\n backdrop-filter,\n -webkit-backdrop-filter;\n transition-timing-function: cubic-bezier(.4, 0, .2, 1);\n transition-duration: .15s;\n}\n.hypurr-connect .transition-colors {\n transition-property:\n color,\n background-color,\n border-color,\n text-decoration-color,\n fill,\n stroke;\n transition-timing-function: cubic-bezier(.4, 0, .2, 1);\n transition-duration: .15s;\n}\n.hypurr-connect .hover\\:bg-purple-500\\/10:hover {\n background-color: rgba(185, 125, 241, .1);\n}\n.hypurr-connect .hover\\:text-gray-300:hover {\n --tw-text-opacity:1;\n color: rgb(209 213 219/var(--tw-text-opacity,1));\n}\n.hypurr-connect .hover\\:text-white:hover {\n --tw-text-opacity:1;\n color: rgb(255 255 255/var(--tw-text-opacity,1));\n}\n.hypurr-connect .focus\\:outline-none:focus {\n outline: 2px solid transparent;\n outline-offset: 2px;\n}\n.hypurr-connect .disabled\\:cursor-not-allowed:disabled {\n cursor: not-allowed;\n}\n.hypurr-connect .disabled\\:opacity-40:disabled {\n opacity: .4;\n}\n.hypurr-connect .disabled\\:opacity-50:disabled {\n opacity: .5;\n}\n");
25
+
1
26
  // src/HypurrConnectProvider.tsx
2
27
  import {
3
28
  ExchangeClient,
@@ -62,22 +87,36 @@ async function generateAgentKey() {
62
87
  const signer = new PrivateKeySigner(privateKey);
63
88
  return { privateKey, address: signer.address };
64
89
  }
65
- async function fetchActiveAgent(userAddress, isTestnet) {
90
+ function isNamedAgent(agent) {
91
+ return agent.name.replace(/ valid_until \d+$/, "") === AGENT_NAME;
92
+ }
93
+ async function fetchExtraAgents(userAddress, isTestnet) {
66
94
  const url = isTestnet ? "https://api.hyperliquid-testnet.xyz/info" : "https://api.hyperliquid.xyz/info";
67
95
  const res = await fetch(url, {
68
96
  method: "POST",
69
97
  headers: { "Content-Type": "application/json" },
70
98
  body: JSON.stringify({ type: "extraAgents", user: userAddress })
71
99
  });
72
- if (!res.ok) return null;
100
+ if (!res.ok) return [];
73
101
  const agents = await res.json();
74
- if (!Array.isArray(agents)) return null;
102
+ if (!Array.isArray(agents)) return [];
103
+ return agents.map((agent) => ({
104
+ ...agent,
105
+ validUntil: agent.validUntil * 1e3
106
+ }));
107
+ }
108
+ async function fetchActiveAgent(userAddress, isTestnet) {
75
109
  const nowMs = Date.now();
76
- const match = agents.find(
77
- (a) => a.name === AGENT_NAME && a.validUntil * 1e3 > nowMs
78
- );
110
+ const agents = await fetchExtraAgents(userAddress, isTestnet);
111
+ const match = agents.find((a) => isNamedAgent(a) && a.validUntil > nowMs);
79
112
  if (!match) return null;
80
- return { ...match, validUntil: match.validUntil * 1e3 };
113
+ return match;
114
+ }
115
+ async function fetchAgentByAddress(userAddress, agentAddress, isTestnet) {
116
+ const agents = await fetchExtraAgents(userAddress, isTestnet);
117
+ return agents.find(
118
+ (agent) => agent.address.toLowerCase() === agentAddress.toLowerCase()
119
+ ) ?? null;
81
120
  }
82
121
  async function isAgentValid(stored, userAddress, isTestnet) {
83
122
  if (stored.validUntil <= Date.now()) return false;
@@ -197,6 +236,57 @@ var GrpcExchangeTransport = class {
197
236
  }
198
237
  };
199
238
 
239
+ // src/agentWallet.ts
240
+ var MS_PER_SECOND = 1e3;
241
+ var NS_PER_MS = 1e6;
242
+ var MS_PER_DAY = 24 * 60 * 60 * 1e3;
243
+ var TELEGRAM_AGENT_APPROVAL_NAME = "xyz";
244
+ var DEFAULT_AGENT_APPROVAL_DURATION_MS = MS_PER_DAY;
245
+ var AGENT_APPROVAL_DURATION_OPTIONS = [
246
+ { label: "1 day", durationMs: MS_PER_DAY },
247
+ { label: "7 days", durationMs: 7 * MS_PER_DAY },
248
+ { label: "30 days", durationMs: 30 * MS_PER_DAY },
249
+ { label: "90 days", durationMs: 90 * MS_PER_DAY }
250
+ ];
251
+ function toFiniteNumber(value) {
252
+ if (value === void 0) return 0;
253
+ const numeric = typeof value === "bigint" ? Number(value) : Number(value);
254
+ return Number.isFinite(numeric) ? numeric : 0;
255
+ }
256
+ function normalizeAgentApprovalDurationMs(durationMs) {
257
+ return typeof durationMs === "number" && Number.isFinite(durationMs) && durationMs > 0 ? durationMs : DEFAULT_AGENT_APPROVAL_DURATION_MS;
258
+ }
259
+ function createTelegramAgentApprovalName(durationMs) {
260
+ const expiresAt = Date.now() + normalizeAgentApprovalDurationMs(durationMs);
261
+ return `${TELEGRAM_AGENT_APPROVAL_NAME} valid_until ${expiresAt}`;
262
+ }
263
+ function agentExpiresAtMs(wallet) {
264
+ if (!wallet.isAgent || !wallet.agentExpiresAt) return null;
265
+ const timestamp = wallet.agentExpiresAt;
266
+ if (timestamp instanceof Date) return timestamp.getTime();
267
+ if (typeof timestamp === "number") return timestamp;
268
+ if (typeof timestamp === "string") {
269
+ const parsed = Date.parse(timestamp);
270
+ return Number.isFinite(parsed) ? parsed : null;
271
+ }
272
+ const seconds = toFiniteNumber(timestamp.seconds);
273
+ const nanos = toFiniteNumber(timestamp.nanos);
274
+ const ms = seconds * MS_PER_SECOND + Math.floor(nanos / NS_PER_MS);
275
+ return Number.isFinite(ms) && ms > 0 ? ms : null;
276
+ }
277
+ function formatAgentExpiry(expiresAtMs) {
278
+ return new Intl.DateTimeFormat(void 0, {
279
+ dateStyle: "medium",
280
+ timeStyle: "short"
281
+ }).format(new Date(expiresAtMs));
282
+ }
283
+ function getAgentExpiryTitle(wallet) {
284
+ const expiresAtMs = agentExpiresAtMs(wallet);
285
+ if (!expiresAtMs || expiresAtMs > Date.now()) return null;
286
+ const expiresAt = formatAgentExpiry(expiresAtMs);
287
+ return `Agent approval expired ${expiresAt}. Connect the owner wallet to renew this agent.`;
288
+ }
289
+
200
290
  // src/HypurrConnectProvider.tsx
201
291
  import { jsx } from "react/jsx-runtime";
202
292
  var TELEGRAM_STORAGE_KEY = "hypurr-connect-tg-jwt";
@@ -205,6 +295,23 @@ var TELEGRAM_AUTH_STATE_KEY = "hypurr-connect-auth-state";
205
295
  var TELEGRAM_AUTH_MESSAGE = "hypurr-connect:telegram-auth";
206
296
  var DEFAULT_AUTH_HUB_URL = "https://auth.hypurr.fun/login";
207
297
  var DEFAULT_MEDIA_URL = "https://media.hypurr.fun";
298
+ var USER_SIGNED_DOMAIN_NAME = "HyperliquidSignTransaction";
299
+ var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
300
+ var APPROVE_AGENT_PRIMARY_TYPE = "HyperliquidTransaction:ApproveAgent";
301
+ var APPROVE_AGENT_TYPES = {
302
+ [APPROVE_AGENT_PRIMARY_TYPE]: [
303
+ { name: "hyperliquidChain", type: "string" },
304
+ { name: "agentAddress", type: "address" },
305
+ { name: "agentName", type: "string" },
306
+ { name: "nonce", type: "uint64" }
307
+ ]
308
+ };
309
+ var EIP712_DOMAIN_TYPES = [
310
+ { name: "name", type: "string" },
311
+ { name: "version", type: "string" },
312
+ { name: "chainId", type: "uint256" },
313
+ { name: "verifyingContract", type: "address" }
314
+ ];
208
315
  var IGNORED_EXTERNAL_SIGNATURE = "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b";
209
316
  var DEFAULT_TELEGRAM_SCOPES = [
210
317
  "telegram:user:read",
@@ -239,6 +346,46 @@ function normalizeMediaUrl(mediaUrl) {
239
346
  function isAddress(value) {
240
347
  return !!value && /^0x[a-fA-F0-9]{40}$/.test(value);
241
348
  }
349
+ function createApproveAgentAction(params) {
350
+ const nonce = Date.now();
351
+ return {
352
+ action: {
353
+ type: "approveAgent",
354
+ signatureChainId: `0x${params.chainId.toString(16)}`,
355
+ hyperliquidChain: params.isTestnet ? "Testnet" : "Mainnet",
356
+ agentAddress: params.agentAddress.toLowerCase(),
357
+ agentName: params.agentName,
358
+ nonce
359
+ },
360
+ nonce
361
+ };
362
+ }
363
+ async function signApproveAgentAction(params) {
364
+ const { action } = createApproveAgentAction(params);
365
+ const signatureHex = await params.signTypedDataAsync({
366
+ domain: {
367
+ name: USER_SIGNED_DOMAIN_NAME,
368
+ version: "1",
369
+ chainId: params.chainId,
370
+ verifyingContract: ZERO_ADDRESS
371
+ },
372
+ types: {
373
+ EIP712Domain: EIP712_DOMAIN_TYPES,
374
+ ...APPROVE_AGENT_TYPES
375
+ },
376
+ primaryType: APPROVE_AGENT_PRIMARY_TYPE,
377
+ message: {
378
+ hyperliquidChain: action.hyperliquidChain,
379
+ agentAddress: action.agentAddress,
380
+ agentName: action.agentName,
381
+ nonce: action.nonce
382
+ }
383
+ });
384
+ return {
385
+ action,
386
+ signatureHex
387
+ };
388
+ }
242
389
  function getRawSignedTransaction(result) {
243
390
  if (typeof result === "string" && result.startsWith("0x")) {
244
391
  return result;
@@ -877,6 +1024,104 @@ function HypurrConnectProvider({
877
1024
  },
878
1025
  [tgClient, telegramRpcOptions, refreshWallets]
879
1026
  );
1027
+ const renewAgentWallet = useCallback(
1028
+ async ({
1029
+ walletId,
1030
+ ownerAddress,
1031
+ signTypedDataAsync,
1032
+ chainId,
1033
+ approvalDurationMs,
1034
+ agentName
1035
+ }) => {
1036
+ if (authMethod !== "telegram") {
1037
+ throw new Error(
1038
+ "[HypurrConnect] Agent wallet renewal is only available for Telegram wallets."
1039
+ );
1040
+ }
1041
+ if (!isAddress(ownerAddress)) {
1042
+ throw new Error(
1043
+ "[HypurrConnect] Connect the owner EOA wallet before renewing this agent."
1044
+ );
1045
+ }
1046
+ if (!telegramRpcOptions) {
1047
+ throw new Error("[HypurrConnect] No Telegram RPC session available.");
1048
+ }
1049
+ const wallet = wallets.find((w) => w.id === walletId);
1050
+ if (!wallet) {
1051
+ throw new Error("[HypurrConnect] Agent wallet not found.");
1052
+ }
1053
+ if (!wallet.isAgent) {
1054
+ throw new Error(
1055
+ "[HypurrConnect] Selected wallet is not an agent wallet."
1056
+ );
1057
+ }
1058
+ if (!isAddress(wallet.ethereumAddress)) {
1059
+ throw new Error(
1060
+ "[HypurrConnect] Agent wallet does not have a valid owner EVM address."
1061
+ );
1062
+ }
1063
+ if (ownerAddress.toLowerCase() !== wallet.ethereumAddress.toLowerCase()) {
1064
+ throw new Error(
1065
+ "[HypurrConnect] Connect the owner EOA for this agent wallet before renewing."
1066
+ );
1067
+ }
1068
+ const agentAddress = wallet.agentEthereumAddress?.value;
1069
+ if (!isAddress(agentAddress)) {
1070
+ throw new Error(
1071
+ "[HypurrConnect] Agent wallet does not have a valid agent EVM address."
1072
+ );
1073
+ }
1074
+ const isTestnet = config.isTestnet ?? false;
1075
+ const approvalAgentName = agentName ?? createTelegramAgentApprovalName(approvalDurationMs);
1076
+ setTgError(null);
1077
+ try {
1078
+ const { action, signatureHex } = await signApproveAgentAction({
1079
+ signTypedDataAsync,
1080
+ agentAddress,
1081
+ agentName: approvalAgentName,
1082
+ chainId,
1083
+ isTestnet
1084
+ });
1085
+ await tgClient.hyperliquidAgentWalletRenew(
1086
+ {
1087
+ authData: {},
1088
+ address: { value: wallet.ethereumAddress },
1089
+ signature: {
1090
+ agentAddress: action.agentAddress,
1091
+ agentName: action.agentName,
1092
+ nonce: action.nonce,
1093
+ chainId,
1094
+ signature: signatureHex
1095
+ }
1096
+ },
1097
+ telegramRpcOptions
1098
+ );
1099
+ const remote = await fetchAgentByAddress(
1100
+ ownerAddress,
1101
+ agentAddress,
1102
+ isTestnet
1103
+ );
1104
+ if (remote && remote.validUntil <= Date.now()) {
1105
+ throw new Error(
1106
+ "[HypurrConnect] Agent renewal was submitted, but the agent is still expired."
1107
+ );
1108
+ }
1109
+ refreshWallets();
1110
+ } catch (err) {
1111
+ console.error("[HypurrConnect] Agent wallet renewal failed:", err);
1112
+ setTgError(err instanceof Error ? err.message : String(err));
1113
+ throw err;
1114
+ }
1115
+ },
1116
+ [
1117
+ authMethod,
1118
+ config.isTestnet,
1119
+ refreshWallets,
1120
+ telegramRpcOptions,
1121
+ tgClient,
1122
+ wallets
1123
+ ]
1124
+ );
880
1125
  const createWalletPack = useCallback(
881
1126
  async (name) => {
882
1127
  const { response } = await tgClient.telegramChatWalletPackCreate(
@@ -1221,6 +1466,7 @@ function HypurrConnectProvider({
1221
1466
  createWallet,
1222
1467
  deleteWallet,
1223
1468
  renameWallet,
1469
+ renewAgentWallet,
1224
1470
  refreshWallets,
1225
1471
  packs,
1226
1472
  createWalletPack,
@@ -1263,6 +1509,7 @@ function HypurrConnectProvider({
1263
1509
  createWallet,
1264
1510
  deleteWallet,
1265
1511
  renameWallet,
1512
+ renewAgentWallet,
1266
1513
  refreshWallets,
1267
1514
  packs,
1268
1515
  createWalletPack,
@@ -1444,18 +1691,18 @@ var btnStyle = {
1444
1691
  alignItems: "center",
1445
1692
  gap: 12,
1446
1693
  overflow: "hidden",
1447
- borderRadius: 6,
1448
- background: "rgba(255,255,255,0.05)",
1449
- padding: "0 24px",
1694
+ borderRadius: 4,
1695
+ background: "rgba(255,255,255,0.1)",
1696
+ padding: "4px 24px",
1450
1697
  fontSize: 14,
1451
- fontWeight: 600,
1452
- letterSpacing: "-0.01em",
1698
+ fontWeight: 500,
1699
+ letterSpacing: "-0.03em",
1453
1700
  color: "#fff",
1454
1701
  cursor: "pointer",
1455
1702
  border: "none",
1456
1703
  transition: "background 150ms"
1457
1704
  };
1458
- var btnHoverBg = { background: "rgba(255,255,255,0.1)" };
1705
+ var btnHoverBg = { background: "rgba(255,255,255,0.15)" };
1459
1706
  var backdropStyle = {
1460
1707
  position: "fixed",
1461
1708
  inset: 0,
@@ -1485,9 +1732,9 @@ var modalBoxStyle = {
1485
1732
  padding: 24
1486
1733
  };
1487
1734
  var headingStyle = {
1488
- fontSize: 16,
1489
- fontWeight: 700,
1490
- letterSpacing: "-0.025em",
1735
+ fontSize: 20,
1736
+ fontWeight: 500,
1737
+ letterSpacing: "-0.03em",
1491
1738
  color: "#fff",
1492
1739
  margin: 0
1493
1740
  };
@@ -1496,7 +1743,7 @@ var dividerStyle = {
1496
1743
  width: "100%",
1497
1744
  background: "rgba(255,255,255,0.05)"
1498
1745
  };
1499
- var iconSize = { width: 20, height: 20 };
1746
+ var iconSize = { width: 26, height: 26 };
1500
1747
  var mobileQuery = typeof window !== "undefined" ? window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT}px)`) : null;
1501
1748
  function subscribeMobile(cb) {
1502
1749
  mobileQuery?.addEventListener("change", cb);
@@ -1653,7 +1900,7 @@ var grabHandleStyle = {
1653
1900
  margin: "0 auto",
1654
1901
  height: 4,
1655
1902
  width: 100,
1656
- borderRadius: 9999,
1903
+ borderRadius: 4,
1657
1904
  background: "rgba(255,255,255,0.05)"
1658
1905
  };
1659
1906
  function MobileDrawer({
@@ -1709,28 +1956,9 @@ function MobileDrawer({
1709
1956
  ] });
1710
1957
  }
1711
1958
 
1712
- // src/WalletSelectorDropdown.tsx
1713
- import { AnimatePresence as AnimatePresence5, motion as motion5 } from "framer-motion";
1714
- import {
1715
- Fragment as Fragment5,
1716
- useCallback as useCallback6,
1717
- useMemo as useMemo2,
1718
- useState as useState5
1719
- } from "react";
1720
-
1721
- // src/UserProfileModal.tsx
1722
- import { AnimatePresence as AnimatePresence4, motion as motion4 } from "framer-motion";
1723
- import {
1724
- useCallback as useCallback5,
1725
- useState as useState4
1726
- } from "react";
1727
-
1728
- // src/DeleteWalletModal.tsx
1959
+ // src/AddWalletModal.tsx
1729
1960
  import { AnimatePresence as AnimatePresence2, motion as motion2 } from "framer-motion";
1730
- import {
1731
- useCallback as useCallback3,
1732
- useState as useState2
1733
- } from "react";
1961
+ import { useCallback as useCallback3, useState as useState2 } from "react";
1734
1962
 
1735
1963
  // src/icons/lucide.tsx
1736
1964
  import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
@@ -1777,6 +2005,47 @@ function Wallet(props) {
1777
2005
  /* @__PURE__ */ jsx5("path", { d: "M18 12a2 2 0 0 0-2 2c0 1.1.9 2 2 2h4v-4z" })
1778
2006
  ] });
1779
2007
  }
2008
+ function Bot(props) {
2009
+ return /* @__PURE__ */ jsxs4("svg", { ...svgBase(props), children: [
2010
+ /* @__PURE__ */ jsx5("path", { d: "M12 8V4H8" }),
2011
+ /* @__PURE__ */ jsx5("rect", { width: "16", height: "12", x: "4", y: "8", rx: "2" }),
2012
+ /* @__PURE__ */ jsx5("path", { d: "M2 14h2" }),
2013
+ /* @__PURE__ */ jsx5("path", { d: "M20 14h2" }),
2014
+ /* @__PURE__ */ jsx5("path", { d: "M15 13v2" }),
2015
+ /* @__PURE__ */ jsx5("path", { d: "M9 13v2" })
2016
+ ] });
2017
+ }
2018
+ function Eye(props) {
2019
+ return /* @__PURE__ */ jsxs4("svg", { ...svgBase(props), children: [
2020
+ /* @__PURE__ */ jsx5("path", { d: "M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0" }),
2021
+ /* @__PURE__ */ jsx5("circle", { cx: "12", cy: "12", r: "3" })
2022
+ ] });
2023
+ }
2024
+ function EyeOff(props) {
2025
+ return /* @__PURE__ */ jsxs4("svg", { ...svgBase(props), children: [
2026
+ /* @__PURE__ */ jsx5("path", { d: "M10.733 5.076a10.74 10.74 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.8 10.8 0 0 1-1.444 2.49" }),
2027
+ /* @__PURE__ */ jsx5("path", { d: "M14.084 14.158a3 3 0 0 1-4.242-4.242" }),
2028
+ /* @__PURE__ */ jsx5("path", { d: "M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143" }),
2029
+ /* @__PURE__ */ jsx5("path", { d: "m2 2 20 20" })
2030
+ ] });
2031
+ }
2032
+ function Check(props) {
2033
+ return /* @__PURE__ */ jsx5("svg", { ...svgBase(props), children: /* @__PURE__ */ jsx5("path", { d: "M20 6 9 17l-5-5" }) });
2034
+ }
2035
+ function KeyRound(props) {
2036
+ return /* @__PURE__ */ jsxs4("svg", { ...svgBase(props), children: [
2037
+ /* @__PURE__ */ jsx5("path", { d: "M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z" }),
2038
+ /* @__PURE__ */ jsx5("circle", { cx: "16.5", cy: "7.5", r: ".5", fill: "currentColor" })
2039
+ ] });
2040
+ }
2041
+ function RefreshCw(props) {
2042
+ return /* @__PURE__ */ jsxs4("svg", { ...svgBase(props), children: [
2043
+ /* @__PURE__ */ jsx5("path", { d: "M3 12a9 9 0 0 1 15.18-6.49" }),
2044
+ /* @__PURE__ */ jsx5("path", { d: "M21 3v6h-6" }),
2045
+ /* @__PURE__ */ jsx5("path", { d: "M21 12a9 9 0 0 1-15.18 6.49" }),
2046
+ /* @__PURE__ */ jsx5("path", { d: "M3 21v-6h6" })
2047
+ ] });
2048
+ }
1780
2049
  function TrendingUp(props) {
1781
2050
  return /* @__PURE__ */ jsxs4("svg", { ...svgBase(props), children: [
1782
2051
  /* @__PURE__ */ jsx5("polyline", { points: "22 7 13.5 15.5 8.5 10.5 2 17" }),
@@ -1851,21 +2120,1026 @@ function LogOut(props) {
1851
2120
  /* @__PURE__ */ jsx5("line", { x1: "21", x2: "9", y1: "12", y2: "12" })
1852
2121
  ] });
1853
2122
  }
1854
- function Plus(props) {
1855
- return /* @__PURE__ */ jsxs4("svg", { ...svgBase(props), children: [
1856
- /* @__PURE__ */ jsx5("path", { d: "M5 12h14" }),
1857
- /* @__PURE__ */ jsx5("path", { d: "M12 5v14" })
2123
+ function Plus(props) {
2124
+ return /* @__PURE__ */ jsxs4("svg", { ...svgBase(props), children: [
2125
+ /* @__PURE__ */ jsx5("path", { d: "M5 12h14" }),
2126
+ /* @__PURE__ */ jsx5("path", { d: "M12 5v14" })
2127
+ ] });
2128
+ }
2129
+ function X(props) {
2130
+ return /* @__PURE__ */ jsxs4("svg", { ...svgBase(props), children: [
2131
+ /* @__PURE__ */ jsx5("path", { d: "M18 6 6 18" }),
2132
+ /* @__PURE__ */ jsx5("path", { d: "m6 6 12 12" })
2133
+ ] });
2134
+ }
2135
+ function SpinKeyframes() {
2136
+ return /* @__PURE__ */ jsx5("style", { children: `@keyframes hypurr-spin { to { transform: rotate(360deg); } }` });
2137
+ }
2138
+
2139
+ // src/AddWalletModal.tsx
2140
+ import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
2141
+ var WALLET_NAME_REGEX = /^[a-zA-Z0-9/]*$/;
2142
+ var PRIVATE_KEY_REGEX = /^(0x)?[a-fA-F0-9]{64}$/;
2143
+ var BASE_TAB_KEYS = ["generate", "import", "api"];
2144
+ function createAuthSignatureRequest(chainId, hyperliquidChain, agentAddress, approvalDurationMs) {
2145
+ const nonce = Date.now();
2146
+ return {
2147
+ domain: {
2148
+ name: "HyperliquidSignTransaction",
2149
+ version: "1",
2150
+ chainId,
2151
+ verifyingContract: "0x0000000000000000000000000000000000000000"
2152
+ },
2153
+ types: {
2154
+ "HyperliquidTransaction:ApproveAgent": [
2155
+ { name: "hyperliquidChain", type: "string" },
2156
+ { name: "agentAddress", type: "address" },
2157
+ { name: "agentName", type: "string" },
2158
+ { name: "nonce", type: "uint64" }
2159
+ ]
2160
+ },
2161
+ primaryType: "HyperliquidTransaction:ApproveAgent",
2162
+ message: {
2163
+ hyperliquidChain,
2164
+ agentAddress: agentAddress.toLowerCase(),
2165
+ agentName: createTelegramAgentApprovalName(approvalDurationMs),
2166
+ nonce
2167
+ }
2168
+ };
2169
+ }
2170
+ var tabClass = (selected) => `flex-1 py-1.5 rounded text-base font-medium flex items-center justify-center gap-1.5 ${selected ? "btn-raised-active" : "btn-raised"}`;
2171
+ var inputClass = (hasError) => `w-full bg-surface-btn/90 border ${hasError ? "border-trade-down/50" : "border-surface-bd"} rounded-lg px-3 py-2.5 text-white placeholder-gray-600 focus:outline-none font-mono text-base`;
2172
+ var formatAddress = (address) => `${address.slice(0, 6)}...${address.slice(-4)}`;
2173
+ function AddWalletModal({
2174
+ isOpen,
2175
+ onClose,
2176
+ ownerAddress,
2177
+ isWalletConnected,
2178
+ chainId,
2179
+ signTypedDataAsync,
2180
+ onConnectWallet,
2181
+ onDisconnectWallet,
2182
+ onWalletAdded,
2183
+ onAddReadOnlyWallet,
2184
+ onNotify,
2185
+ hyperliquidChain = "Mainnet",
2186
+ agentApprovalDurationOptions,
2187
+ defaultAgentApprovalDurationMs = DEFAULT_AGENT_APPROVAL_DURATION_MS
2188
+ }) {
2189
+ const tabKeys = onAddReadOnlyWallet ? [...BASE_TAB_KEYS, "readonly"] : BASE_TAB_KEYS;
2190
+ const [activeTab, setActiveTab] = useState2("generate");
2191
+ const [isLoading, setIsLoading] = useState2(false);
2192
+ const [walletName, setWalletName] = useState2("");
2193
+ const [newWalletName, setNewWalletName] = useState2("");
2194
+ const [importWalletName, setImportWalletName] = useState2("");
2195
+ const [importPrivateKey, setImportPrivateKey] = useState2("");
2196
+ const [showImportPrivateKey, setShowImportPrivateKey] = useState2(false);
2197
+ const [readOnlyAddress, setReadOnlyAddress] = useState2("");
2198
+ const [agentApprovalDurationMs, setAgentApprovalDurationMs] = useState2(
2199
+ defaultAgentApprovalDurationMs
2200
+ );
2201
+ const [error, setError] = useState2(null);
2202
+ const {
2203
+ authMethod,
2204
+ createWallet,
2205
+ isLoading: userLoading,
2206
+ refreshWallets,
2207
+ telegramClient,
2208
+ telegramRpcOptions
2209
+ } = useHypurrConnectInternal();
2210
+ const isValidWalletName = walletName.length > 0 && WALLET_NAME_REGEX.test(walletName);
2211
+ const isValidNewWalletName = newWalletName.length > 0 && WALLET_NAME_REGEX.test(newWalletName);
2212
+ const isValidImportWalletName = importWalletName.length > 0 && WALLET_NAME_REGEX.test(importWalletName);
2213
+ const trimmedImportPrivateKey = importPrivateKey.trim();
2214
+ const isValidImportPrivateKey = PRIVATE_KEY_REGEX.test(
2215
+ trimmedImportPrivateKey
2216
+ );
2217
+ const isProcessing = isLoading || userLoading;
2218
+ const durationOptions = agentApprovalDurationOptions && agentApprovalDurationOptions.length > 0 ? agentApprovalDurationOptions : AGENT_APPROVAL_DURATION_OPTIONS;
2219
+ const handleClose = useCallback3(() => {
2220
+ if (isProcessing) return;
2221
+ setError(null);
2222
+ setImportPrivateKey("");
2223
+ setShowImportPrivateKey(false);
2224
+ onClose();
2225
+ }, [isProcessing, onClose]);
2226
+ const assertTelegramReady = useCallback3(() => {
2227
+ if (authMethod !== "telegram" || !telegramRpcOptions) {
2228
+ throw new Error("Telegram login is required to add wallets");
2229
+ }
2230
+ }, [authMethod, telegramRpcOptions]);
2231
+ const completeWalletAdded = useCallback3(
2232
+ async (wallet) => {
2233
+ refreshWallets();
2234
+ await onWalletAdded?.(wallet);
2235
+ },
2236
+ [onWalletAdded, refreshWallets]
2237
+ );
2238
+ const handleCreateWallet = useCallback3(async () => {
2239
+ if (!isValidNewWalletName) {
2240
+ setError("Wallet name may only contain letters, numbers, and /");
2241
+ return;
2242
+ }
2243
+ setError(null);
2244
+ setIsLoading(true);
2245
+ try {
2246
+ assertTelegramReady();
2247
+ const wallet = await createWallet(newWalletName);
2248
+ await completeWalletAdded(wallet);
2249
+ onNotify?.({ type: "success", message: "Wallet created successfully" });
2250
+ setNewWalletName("");
2251
+ handleClose();
2252
+ } catch (e) {
2253
+ const message = e instanceof Error ? e.message : "Failed to create wallet";
2254
+ setError(message);
2255
+ onNotify?.({ type: "error", message });
2256
+ } finally {
2257
+ setIsLoading(false);
2258
+ }
2259
+ }, [
2260
+ assertTelegramReady,
2261
+ completeWalletAdded,
2262
+ createWallet,
2263
+ handleClose,
2264
+ isValidNewWalletName,
2265
+ newWalletName,
2266
+ onNotify
2267
+ ]);
2268
+ const handleImportWallet = useCallback3(async () => {
2269
+ if (!isValidImportWalletName) {
2270
+ setError("Wallet name may only contain letters, numbers, and /");
2271
+ return;
2272
+ }
2273
+ if (!isValidImportPrivateKey) {
2274
+ setError("Please enter a valid 64-character hex private key");
2275
+ return;
2276
+ }
2277
+ setError(null);
2278
+ setIsLoading(true);
2279
+ try {
2280
+ assertTelegramReady();
2281
+ const response = await telegramClient.hyperliquidWalletImport(
2282
+ {
2283
+ authData: {},
2284
+ name: importWalletName,
2285
+ privateKey: trimmedImportPrivateKey
2286
+ },
2287
+ telegramRpcOptions
2288
+ );
2289
+ await completeWalletAdded(response.response.wallet);
2290
+ onNotify?.({ type: "success", message: "Wallet imported successfully" });
2291
+ setImportWalletName("");
2292
+ setImportPrivateKey("");
2293
+ handleClose();
2294
+ } catch (e) {
2295
+ const message = e instanceof Error ? e.message : "Failed to import wallet";
2296
+ setError(message);
2297
+ onNotify?.({ type: "error", message });
2298
+ } finally {
2299
+ setIsLoading(false);
2300
+ }
2301
+ }, [
2302
+ assertTelegramReady,
2303
+ completeWalletAdded,
2304
+ handleClose,
2305
+ importWalletName,
2306
+ isValidImportPrivateKey,
2307
+ isValidImportWalletName,
2308
+ onNotify,
2309
+ telegramClient,
2310
+ telegramRpcOptions,
2311
+ trimmedImportPrivateKey
2312
+ ]);
2313
+ const handleSignAndAdd = useCallback3(async () => {
2314
+ if (!ownerAddress) {
2315
+ onConnectWallet?.();
2316
+ return;
2317
+ }
2318
+ if (!signTypedDataAsync || !chainId) {
2319
+ setError("Wallet signing is not ready yet");
2320
+ return;
2321
+ }
2322
+ if (!isValidWalletName) {
2323
+ setError("Wallet name may only contain letters, numbers, and /");
2324
+ return;
2325
+ }
2326
+ setError(null);
2327
+ setIsLoading(true);
2328
+ try {
2329
+ assertTelegramReady();
2330
+ const res = await telegramClient.hyperliquidAgentSignatureCreate(
2331
+ { authData: {}, address: ownerAddress },
2332
+ telegramRpcOptions
2333
+ );
2334
+ const agentAddress = res.response.agent;
2335
+ const request = createAuthSignatureRequest(
2336
+ chainId,
2337
+ hyperliquidChain,
2338
+ agentAddress,
2339
+ agentApprovalDurationMs
2340
+ );
2341
+ const signature = await signTypedDataAsync(request);
2342
+ await telegramClient.hyperliquidAgentWalletCreate(
2343
+ {
2344
+ authData: {},
2345
+ name: walletName,
2346
+ signature: {
2347
+ agentAddress: request.message.agentAddress,
2348
+ agentName: request.message.agentName,
2349
+ nonce: request.message.nonce,
2350
+ chainId,
2351
+ signature
2352
+ }
2353
+ },
2354
+ telegramRpcOptions
2355
+ );
2356
+ await completeWalletAdded();
2357
+ onNotify?.({ type: "success", message: "Wallet added successfully" });
2358
+ onDisconnectWallet?.();
2359
+ setWalletName("");
2360
+ handleClose();
2361
+ } catch (e) {
2362
+ const message = e instanceof Error ? e.message : "Failed to add wallet";
2363
+ setError(message);
2364
+ onNotify?.({ type: "error", message });
2365
+ } finally {
2366
+ setIsLoading(false);
2367
+ }
2368
+ }, [
2369
+ assertTelegramReady,
2370
+ agentApprovalDurationMs,
2371
+ chainId,
2372
+ completeWalletAdded,
2373
+ handleClose,
2374
+ hyperliquidChain,
2375
+ isValidWalletName,
2376
+ onConnectWallet,
2377
+ onDisconnectWallet,
2378
+ onNotify,
2379
+ ownerAddress,
2380
+ signTypedDataAsync,
2381
+ telegramClient,
2382
+ telegramRpcOptions,
2383
+ walletName
2384
+ ]);
2385
+ const handleAddReadOnly = useCallback3(async () => {
2386
+ const trimmed = readOnlyAddress.trim();
2387
+ if (!trimmed) {
2388
+ setError("Please enter a wallet address");
2389
+ return;
2390
+ }
2391
+ if (!/^0x[a-fA-F0-9]{40}$/.test(trimmed)) {
2392
+ setError("Invalid Ethereum address format");
2393
+ return;
2394
+ }
2395
+ setError(null);
2396
+ setIsLoading(true);
2397
+ try {
2398
+ await onAddReadOnlyWallet?.(trimmed);
2399
+ onNotify?.({ type: "success", message: "Read-only wallet added" });
2400
+ setReadOnlyAddress("");
2401
+ handleClose();
2402
+ } catch (e) {
2403
+ const message = e instanceof Error ? e.message : "Failed to add wallet";
2404
+ setError(message);
2405
+ onNotify?.({ type: "error", message });
2406
+ } finally {
2407
+ setIsLoading(false);
2408
+ }
2409
+ }, [handleClose, onAddReadOnlyWallet, onNotify, readOnlyAddress]);
2410
+ return /* @__PURE__ */ jsx6(AnimatePresence2, { children: isOpen && /* @__PURE__ */ jsxs5(motion2.div, { className: "hypurr-connect", style: { display: "contents" }, children: [
2411
+ /* @__PURE__ */ jsx6(SpinKeyframes, {}),
2412
+ /* @__PURE__ */ jsx6(
2413
+ motion2.div,
2414
+ {
2415
+ className: "fixed inset-0 z-[100] bg-black/70 backdrop-blur-sm",
2416
+ initial: { opacity: 0 },
2417
+ animate: { opacity: 1 },
2418
+ exit: { opacity: 0 },
2419
+ transition: { duration: 0.15 },
2420
+ onClick: handleClose
2421
+ }
2422
+ ),
2423
+ /* @__PURE__ */ jsx6("div", { className: "fixed inset-0 z-[101] flex items-center justify-center p-4", children: /* @__PURE__ */ jsxs5(
2424
+ motion2.div,
2425
+ {
2426
+ className: "relative w-full max-w-md overflow-hidden rounded-lg border border-surface-bd bg-surface-modal font-sans shadow-modal",
2427
+ initial: { opacity: 0, y: 8 },
2428
+ animate: { opacity: 1, y: 0 },
2429
+ exit: { opacity: 0, y: 8 },
2430
+ transition: { duration: 0.18, ease: "easeOut" },
2431
+ onClick: (event) => event.stopPropagation(),
2432
+ children: [
2433
+ /* @__PURE__ */ jsxs5("div", { className: "relative flex items-center justify-center border-b border-white/[0.06] px-6 pb-5 pt-6", children: [
2434
+ /* @__PURE__ */ jsx6("h3", { className: "text-lg font-semibold text-white", children: "Add Wallet" }),
2435
+ /* @__PURE__ */ jsx6(
2436
+ "button",
2437
+ {
2438
+ onClick: handleClose,
2439
+ disabled: isProcessing,
2440
+ className: "absolute right-6 text-gray-400 transition-colors hover:text-white disabled:cursor-not-allowed disabled:opacity-40",
2441
+ "aria-label": "Close",
2442
+ children: /* @__PURE__ */ jsx6(X, { size: 16 })
2443
+ }
2444
+ )
2445
+ ] }),
2446
+ /* @__PURE__ */ jsx6("div", { className: "flex gap-1.5 px-6 pt-5", children: tabKeys.map((tab) => /* @__PURE__ */ jsx6(
2447
+ "button",
2448
+ {
2449
+ type: "button",
2450
+ onClick: () => {
2451
+ setError(null);
2452
+ setActiveTab(tab);
2453
+ },
2454
+ className: tabClass(activeTab === tab),
2455
+ children: tab === "generate" ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
2456
+ /* @__PURE__ */ jsx6(Plus, { size: 13 }),
2457
+ " New"
2458
+ ] }) : tab === "import" ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
2459
+ /* @__PURE__ */ jsx6(KeyRound, { size: 13 }),
2460
+ " Import"
2461
+ ] }) : tab === "api" ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
2462
+ /* @__PURE__ */ jsx6(Wallet, { size: 13 }),
2463
+ " Link"
2464
+ ] }) : /* @__PURE__ */ jsxs5(Fragment2, { children: [
2465
+ /* @__PURE__ */ jsx6(Eye, { size: 13 }),
2466
+ " Watch"
2467
+ ] })
2468
+ },
2469
+ tab
2470
+ )) }),
2471
+ /* @__PURE__ */ jsxs5("div", { className: "px-6 pb-6 pt-5", children: [
2472
+ activeTab === "generate" && /* @__PURE__ */ jsxs5("section", { className: "space-y-4", children: [
2473
+ /* @__PURE__ */ jsx6("p", { className: "text-base text-gray-400", children: "Create a new Hyperliquid wallet." }),
2474
+ /* @__PURE__ */ jsx6(
2475
+ WalletNameInput,
2476
+ {
2477
+ value: newWalletName,
2478
+ setValue: setNewWalletName,
2479
+ isValid: isValidNewWalletName,
2480
+ clearError: () => setError(null),
2481
+ placeholder: "MyNewWallet"
2482
+ }
2483
+ ),
2484
+ /* @__PURE__ */ jsx6(
2485
+ "button",
2486
+ {
2487
+ onClick: handleCreateWallet,
2488
+ disabled: isProcessing || !isValidNewWalletName,
2489
+ className: `flex w-full items-center justify-center gap-2 rounded-lg py-2 text-base font-medium ${!isProcessing && isValidNewWalletName ? "btn-raised" : "btn-raised-disabled"}`,
2490
+ children: isProcessing ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
2491
+ /* @__PURE__ */ jsx6(Loader2, { size: 14 }),
2492
+ " Creating..."
2493
+ ] }) : /* @__PURE__ */ jsxs5(Fragment2, { children: [
2494
+ /* @__PURE__ */ jsx6(Plus, { size: 14 }),
2495
+ " Create Wallet"
2496
+ ] })
2497
+ }
2498
+ ),
2499
+ error && /* @__PURE__ */ jsx6(ErrorBox, { message: error })
2500
+ ] }),
2501
+ activeTab === "import" && /* @__PURE__ */ jsxs5("section", { className: "space-y-4", children: [
2502
+ /* @__PURE__ */ jsx6("p", { className: "text-base text-gray-400", children: "Import a Hyperliquid wallet with its private key." }),
2503
+ /* @__PURE__ */ jsx6(
2504
+ WalletNameInput,
2505
+ {
2506
+ value: importWalletName,
2507
+ setValue: setImportWalletName,
2508
+ isValid: isValidImportWalletName,
2509
+ clearError: () => setError(null),
2510
+ placeholder: "MyImportedWallet"
2511
+ }
2512
+ ),
2513
+ /* @__PURE__ */ jsxs5("div", { children: [
2514
+ /* @__PURE__ */ jsx6("label", { className: "mb-2 block text-base uppercase tracking-[0.1em] text-gray-400", children: "Private Key" }),
2515
+ /* @__PURE__ */ jsxs5("div", { className: "relative", children: [
2516
+ /* @__PURE__ */ jsx6(
2517
+ "input",
2518
+ {
2519
+ type: showImportPrivateKey ? "text" : "password",
2520
+ value: importPrivateKey,
2521
+ onChange: (event) => {
2522
+ setImportPrivateKey(event.target.value);
2523
+ setError(null);
2524
+ },
2525
+ placeholder: "0x...",
2526
+ spellCheck: false,
2527
+ autoComplete: "off",
2528
+ className: `${inputClass(
2529
+ !!importPrivateKey && !isValidImportPrivateKey
2530
+ )} pr-11`
2531
+ }
2532
+ ),
2533
+ /* @__PURE__ */ jsx6(
2534
+ "button",
2535
+ {
2536
+ type: "button",
2537
+ onClick: () => setShowImportPrivateKey((visible) => !visible),
2538
+ className: "absolute right-2 top-1/2 -translate-y-1/2 p-1.5 text-gray-500 transition-colors hover:text-gray-300",
2539
+ "aria-label": showImportPrivateKey ? "Hide private key" : "Show private key",
2540
+ children: showImportPrivateKey ? /* @__PURE__ */ jsx6(EyeOff, { size: 15 }) : /* @__PURE__ */ jsx6(Eye, { size: 15 })
2541
+ }
2542
+ )
2543
+ ] })
2544
+ ] }),
2545
+ /* @__PURE__ */ jsx6(
2546
+ "button",
2547
+ {
2548
+ onClick: handleImportWallet,
2549
+ disabled: isProcessing || !isValidImportWalletName || !isValidImportPrivateKey,
2550
+ className: `flex w-full items-center justify-center gap-2 rounded-lg border bg-transparent py-2 text-base font-medium transition-colors ${!isProcessing && isValidImportWalletName && isValidImportPrivateKey ? "border-purple-500 text-purple-400 hover:bg-purple-500/10" : "cursor-not-allowed border-gray-700 text-gray-600"}`,
2551
+ children: isProcessing ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
2552
+ /* @__PURE__ */ jsx6(Loader2, { size: 14 }),
2553
+ " Importing..."
2554
+ ] }) : /* @__PURE__ */ jsxs5(Fragment2, { children: [
2555
+ /* @__PURE__ */ jsx6(KeyRound, { size: 14 }),
2556
+ " Import Wallet"
2557
+ ] })
2558
+ }
2559
+ ),
2560
+ error && /* @__PURE__ */ jsx6(ErrorBox, { message: error })
2561
+ ] }),
2562
+ activeTab === "api" && /* @__PURE__ */ jsxs5("section", { className: "space-y-4", children: [
2563
+ /* @__PURE__ */ jsx6("p", { className: "text-base text-gray-400", children: "Connect your wallet and sign to link it for trading." }),
2564
+ !isWalletConnected || !ownerAddress ? /* @__PURE__ */ jsxs5(
2565
+ "button",
2566
+ {
2567
+ onClick: onConnectWallet,
2568
+ className: "btn-raised flex w-full items-center justify-center gap-2 rounded-lg py-2 text-base font-medium",
2569
+ children: [
2570
+ /* @__PURE__ */ jsx6(Wallet, { size: 14 }),
2571
+ " Connect Wallet"
2572
+ ]
2573
+ }
2574
+ ) : /* @__PURE__ */ jsxs5(Fragment2, { children: [
2575
+ /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-3 rounded-lg border border-white/[0.06] bg-white/[0.03] px-3 py-2.5", children: [
2576
+ /* @__PURE__ */ jsx6("div", { className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-md border border-white/[0.08] bg-white/[0.06]", children: /* @__PURE__ */ jsx6(Wallet, { size: 14, className: "text-gray-400" }) }),
2577
+ /* @__PURE__ */ jsxs5("div", { className: "min-w-0 flex-1", children: [
2578
+ /* @__PURE__ */ jsx6("p", { className: "text-base text-gray-400", children: "Connected" }),
2579
+ /* @__PURE__ */ jsx6("p", { className: "font-mono text-base text-white", children: formatAddress(ownerAddress) })
2580
+ ] }),
2581
+ /* @__PURE__ */ jsx6(
2582
+ Check,
2583
+ {
2584
+ size: 16,
2585
+ className: "flex-shrink-0 text-trade-up"
2586
+ }
2587
+ )
2588
+ ] }),
2589
+ /* @__PURE__ */ jsx6(
2590
+ WalletNameInput,
2591
+ {
2592
+ value: walletName,
2593
+ setValue: setWalletName,
2594
+ isValid: isValidWalletName,
2595
+ clearError: () => setError(null),
2596
+ placeholder: "MyWallet"
2597
+ }
2598
+ ),
2599
+ /* @__PURE__ */ jsx6(
2600
+ ApprovalDurationPicker,
2601
+ {
2602
+ value: agentApprovalDurationMs,
2603
+ onChange: setAgentApprovalDurationMs,
2604
+ options: durationOptions,
2605
+ disabled: isProcessing
2606
+ }
2607
+ ),
2608
+ /* @__PURE__ */ jsx6(
2609
+ "button",
2610
+ {
2611
+ onClick: handleSignAndAdd,
2612
+ disabled: isProcessing || !isValidWalletName,
2613
+ className: `flex w-full items-center justify-center gap-2 rounded-lg py-2 text-base font-medium ${!isProcessing && isValidWalletName ? "btn-raised" : "btn-raised-disabled"}`,
2614
+ children: isProcessing ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
2615
+ /* @__PURE__ */ jsx6(Loader2, { size: 14 }),
2616
+ " Signing..."
2617
+ ] }) : "Sign & Add Wallet"
2618
+ }
2619
+ ),
2620
+ onDisconnectWallet && /* @__PURE__ */ jsx6(
2621
+ "button",
2622
+ {
2623
+ onClick: onDisconnectWallet,
2624
+ className: "w-full py-1.5 text-base text-gray-400 transition-colors hover:text-gray-300",
2625
+ children: "Disconnect & use different wallet"
2626
+ }
2627
+ )
2628
+ ] }),
2629
+ error && /* @__PURE__ */ jsx6(ErrorBox, { message: error })
2630
+ ] }),
2631
+ activeTab === "readonly" && onAddReadOnlyWallet && /* @__PURE__ */ jsxs5("section", { className: "space-y-4", children: [
2632
+ /* @__PURE__ */ jsx6("p", { className: "text-base text-gray-400", children: "View positions and balances without trading access." }),
2633
+ /* @__PURE__ */ jsxs5("div", { children: [
2634
+ /* @__PURE__ */ jsx6("label", { className: "mb-2 block text-base uppercase tracking-[0.1em] text-gray-400", children: "Wallet Address" }),
2635
+ /* @__PURE__ */ jsx6(
2636
+ "input",
2637
+ {
2638
+ type: "text",
2639
+ value: readOnlyAddress,
2640
+ onChange: (event) => setReadOnlyAddress(event.target.value),
2641
+ placeholder: "0x...",
2642
+ className: inputClass()
2643
+ }
2644
+ )
2645
+ ] }),
2646
+ /* @__PURE__ */ jsx6(
2647
+ "button",
2648
+ {
2649
+ onClick: handleAddReadOnly,
2650
+ disabled: isProcessing || !readOnlyAddress.trim(),
2651
+ className: `flex w-full items-center justify-center gap-2 rounded-lg py-2 text-base font-medium ${!isProcessing && readOnlyAddress.trim() ? "btn-raised" : "btn-raised-disabled"}`,
2652
+ children: isProcessing ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
2653
+ /* @__PURE__ */ jsx6(Loader2, { size: 14 }),
2654
+ " Adding..."
2655
+ ] }) : /* @__PURE__ */ jsxs5(Fragment2, { children: [
2656
+ /* @__PURE__ */ jsx6(Eye, { size: 14 }),
2657
+ " Add Watch Wallet"
2658
+ ] })
2659
+ }
2660
+ ),
2661
+ error && /* @__PURE__ */ jsx6(ErrorBox, { message: error })
2662
+ ] })
2663
+ ] })
2664
+ ]
2665
+ }
2666
+ ) })
2667
+ ] }) });
2668
+ }
2669
+ function WalletNameInput({
2670
+ value,
2671
+ setValue,
2672
+ isValid,
2673
+ clearError,
2674
+ placeholder
2675
+ }) {
2676
+ return /* @__PURE__ */ jsxs5("div", { children: [
2677
+ /* @__PURE__ */ jsx6("label", { className: "mb-2 block text-base uppercase tracking-[0.1em] text-gray-400", children: "Wallet Name" }),
2678
+ /* @__PURE__ */ jsx6(
2679
+ "input",
2680
+ {
2681
+ type: "text",
2682
+ value,
2683
+ onChange: (event) => {
2684
+ const nextValue = event.target.value;
2685
+ if (WALLET_NAME_REGEX.test(nextValue) || nextValue === "") {
2686
+ setValue(nextValue);
2687
+ clearError();
2688
+ }
2689
+ },
2690
+ placeholder,
2691
+ className: inputClass(!!value && !isValid)
2692
+ }
2693
+ ),
2694
+ /* @__PURE__ */ jsx6("p", { className: "mt-1.5 text-base text-gray-600", children: "Letters, numbers, and / only" })
2695
+ ] });
2696
+ }
2697
+ function ApprovalDurationPicker({
2698
+ value,
2699
+ onChange,
2700
+ options,
2701
+ disabled
2702
+ }) {
2703
+ return /* @__PURE__ */ jsxs5("div", { children: [
2704
+ /* @__PURE__ */ jsx6("label", { className: "mb-2 block text-base uppercase tracking-[0.1em] text-gray-400", children: "Approval Duration" }),
2705
+ /* @__PURE__ */ jsx6("div", { className: "grid grid-cols-4 gap-1.5", children: options.map((option) => /* @__PURE__ */ jsx6(
2706
+ "button",
2707
+ {
2708
+ type: "button",
2709
+ onClick: () => onChange(option.durationMs),
2710
+ disabled,
2711
+ className: `rounded py-1.5 text-base font-medium disabled:cursor-not-allowed disabled:opacity-50 ${value === option.durationMs ? "btn-raised-active" : "btn-raised"}`,
2712
+ children: option.label
2713
+ },
2714
+ `${option.label}-${option.durationMs}`
2715
+ )) })
2716
+ ] });
2717
+ }
2718
+ function ErrorBox({ message }) {
2719
+ return /* @__PURE__ */ jsxs5("div", { className: "flex items-start gap-2 rounded-lg border border-trade-down/20 bg-trade-down/[0.08] p-3", children: [
2720
+ /* @__PURE__ */ jsx6(
2721
+ AlertTriangle,
2722
+ {
2723
+ size: 14,
2724
+ className: "mt-0.5 flex-shrink-0 text-trade-down"
2725
+ }
2726
+ ),
2727
+ /* @__PURE__ */ jsx6("p", { className: "text-base text-trade-down", children: message })
2728
+ ] });
2729
+ }
2730
+
2731
+ // src/RenewAgentModal.tsx
2732
+ import { AnimatePresence as AnimatePresence3, motion as motion3 } from "framer-motion";
2733
+ import { useCallback as useCallback4, useMemo as useMemo2, useState as useState3 } from "react";
2734
+ import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
2735
+ var isHexAddress = (address) => !!address && /^0x[a-fA-F0-9]{40}$/.test(address);
2736
+ var formatAddress2 = (address) => address ? `${address.slice(0, 6)}...${address.slice(-4)}` : "";
2737
+ var isSameAddress = (a, b) => isHexAddress(a) && isHexAddress(b) && a.toLowerCase() === b.toLowerCase();
2738
+ function RenewAgentModal({
2739
+ isOpen,
2740
+ onClose,
2741
+ wallet,
2742
+ ownerAddress,
2743
+ isWalletConnected,
2744
+ chainId,
2745
+ signTypedDataAsync,
2746
+ onConnectWallet,
2747
+ onDisconnectWallet,
2748
+ onRenewed,
2749
+ onNotify,
2750
+ approvalDurationOptions,
2751
+ defaultApprovalDurationMs = DEFAULT_AGENT_APPROVAL_DURATION_MS
2752
+ }) {
2753
+ const { renewAgentWallet } = useHypurrConnectInternal();
2754
+ const [isRenewing, setIsRenewing] = useState3(false);
2755
+ const [approvalDurationMs, setApprovalDurationMs] = useState3(
2756
+ defaultApprovalDurationMs
2757
+ );
2758
+ const [error, setError] = useState3(null);
2759
+ const expiryMessage = useMemo2(
2760
+ () => wallet ? getAgentExpiryTitle(wallet) : null,
2761
+ [wallet]
2762
+ );
2763
+ const currentExpiryMs = useMemo2(
2764
+ () => wallet ? agentExpiresAtMs(wallet) : null,
2765
+ [wallet]
2766
+ );
2767
+ const durationOptions = approvalDurationOptions && approvalDurationOptions.length > 0 ? approvalDurationOptions : AGENT_APPROVAL_DURATION_OPTIONS;
2768
+ const expectedOwnerAddress = wallet?.ethereumAddress ?? null;
2769
+ const agentAddress = wallet?.agentEthereumAddress?.value ?? null;
2770
+ const hasExpectedOwner = isHexAddress(expectedOwnerAddress);
2771
+ const hasAgentAddress = isHexAddress(agentAddress);
2772
+ const hasConnectedOwner = isWalletConnected && isHexAddress(ownerAddress);
2773
+ const ownerMatches = isSameAddress(ownerAddress, expectedOwnerAddress);
2774
+ const ownerReady = ownerMatches && !!chainId;
2775
+ const canRenew = !!wallet && hasAgentAddress && ownerReady && !!signTypedDataAsync && !isRenewing;
2776
+ const handleClose = useCallback4(() => {
2777
+ if (isRenewing) return;
2778
+ setError(null);
2779
+ onClose();
2780
+ }, [isRenewing, onClose]);
2781
+ const handleRenew = useCallback4(async () => {
2782
+ if (!wallet) return;
2783
+ if (!isHexAddress(agentAddress)) {
2784
+ setError("This wallet is missing its agent address.");
2785
+ return;
2786
+ }
2787
+ if (!isHexAddress(expectedOwnerAddress)) {
2788
+ setError("This wallet is missing its owner address.");
2789
+ return;
2790
+ }
2791
+ if (!isHexAddress(ownerAddress)) {
2792
+ onConnectWallet?.();
2793
+ return;
2794
+ }
2795
+ if (!isSameAddress(ownerAddress, expectedOwnerAddress)) {
2796
+ setError(
2797
+ `Connect the owner wallet ${formatAddress2(expectedOwnerAddress)} to renew this agent.`
2798
+ );
2799
+ return;
2800
+ }
2801
+ if (!chainId || !signTypedDataAsync) {
2802
+ setError("Wallet signing is not ready yet");
2803
+ return;
2804
+ }
2805
+ setError(null);
2806
+ setIsRenewing(true);
2807
+ try {
2808
+ await renewAgentWallet({
2809
+ walletId: wallet.id,
2810
+ ownerAddress,
2811
+ signTypedDataAsync,
2812
+ chainId,
2813
+ approvalDurationMs
2814
+ });
2815
+ await onRenewed?.(wallet);
2816
+ onNotify?.({ type: "success", message: "Agent wallet renewed" });
2817
+ onClose();
2818
+ } catch (e) {
2819
+ const message = e instanceof Error ? e.message : "Failed to renew agent wallet";
2820
+ setError(message);
2821
+ onNotify?.({ type: "error", message });
2822
+ } finally {
2823
+ setIsRenewing(false);
2824
+ }
2825
+ }, [
2826
+ agentAddress,
2827
+ approvalDurationMs,
2828
+ chainId,
2829
+ expectedOwnerAddress,
2830
+ onClose,
2831
+ onConnectWallet,
2832
+ onNotify,
2833
+ onRenewed,
2834
+ ownerAddress,
2835
+ renewAgentWallet,
2836
+ signTypedDataAsync,
2837
+ wallet
2838
+ ]);
2839
+ return /* @__PURE__ */ jsx7(AnimatePresence3, { children: isOpen && wallet && /* @__PURE__ */ jsxs6(motion3.div, { className: "hypurr-connect", style: { display: "contents" }, children: [
2840
+ /* @__PURE__ */ jsx7(SpinKeyframes, {}),
2841
+ /* @__PURE__ */ jsx7(
2842
+ motion3.div,
2843
+ {
2844
+ className: "fixed inset-0 z-[110] bg-black/70 backdrop-blur-sm",
2845
+ initial: { opacity: 0 },
2846
+ animate: { opacity: 1 },
2847
+ exit: { opacity: 0 },
2848
+ transition: { duration: 0.15 },
2849
+ onClick: handleClose
2850
+ }
2851
+ ),
2852
+ /* @__PURE__ */ jsx7("div", { className: "fixed inset-0 z-[111] flex items-center justify-center p-4", children: /* @__PURE__ */ jsxs6(
2853
+ motion3.div,
2854
+ {
2855
+ className: "relative w-full max-w-md overflow-hidden rounded-lg border border-surface-bd bg-surface-modal font-sans shadow-modal",
2856
+ initial: { opacity: 0, y: 8 },
2857
+ animate: { opacity: 1, y: 0 },
2858
+ exit: { opacity: 0, y: 8 },
2859
+ transition: { duration: 0.18, ease: "easeOut" },
2860
+ onClick: (event) => event.stopPropagation(),
2861
+ children: [
2862
+ /* @__PURE__ */ jsxs6("div", { className: "relative flex items-center justify-center border-b border-white/[0.06] px-6 pb-5 pt-6", children: [
2863
+ /* @__PURE__ */ jsx7("h3", { className: "text-lg font-semibold text-white", children: "Renew Agent Wallet" }),
2864
+ /* @__PURE__ */ jsx7(
2865
+ "button",
2866
+ {
2867
+ onClick: handleClose,
2868
+ disabled: isRenewing,
2869
+ className: "absolute right-6 text-gray-400 transition-colors hover:text-white disabled:cursor-not-allowed disabled:opacity-40",
2870
+ "aria-label": "Close",
2871
+ children: /* @__PURE__ */ jsx7(X, { size: 16 })
2872
+ }
2873
+ )
2874
+ ] }),
2875
+ /* @__PURE__ */ jsxs6("div", { className: "space-y-4 px-6 py-5", children: [
2876
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-start gap-2 rounded-lg border border-amber-500/25 bg-amber-500/[0.08] p-3", children: [
2877
+ /* @__PURE__ */ jsx7(
2878
+ AlertTriangle,
2879
+ {
2880
+ size: 14,
2881
+ className: "mt-0.5 flex-shrink-0 text-amber-400"
2882
+ }
2883
+ ),
2884
+ /* @__PURE__ */ jsx7("p", { className: "text-base text-amber-200", children: expiryMessage ?? (currentExpiryMs ? `Current approval expires ${formatAgentExpiry(
2885
+ currentExpiryMs
2886
+ )}. Renew to extend this agent wallet.` : "Renew this agent wallet with a fresh owner approval.") })
2887
+ ] }),
2888
+ /* @__PURE__ */ jsxs6("div", { className: "rounded-lg border border-white/[0.06] bg-white/[0.03] p-3", children: [
2889
+ /* @__PURE__ */ jsx7("p", { className: "mb-1.5 text-base uppercase tracking-[0.1em] text-gray-400", children: "Agent address" }),
2890
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between gap-3", children: [
2891
+ /* @__PURE__ */ jsxs6("div", { className: "min-w-0", children: [
2892
+ /* @__PURE__ */ jsx7("p", { className: "truncate text-base font-medium text-white", children: wallet.name || "Unnamed Wallet" }),
2893
+ /* @__PURE__ */ jsx7("p", { className: "font-mono text-base text-gray-400", children: hasAgentAddress ? formatAddress2(agentAddress) : "Missing agent address" })
2894
+ ] }),
2895
+ /* @__PURE__ */ jsx7(
2896
+ AlertTriangle,
2897
+ {
2898
+ size: 16,
2899
+ className: "flex-shrink-0 text-amber-400"
2900
+ }
2901
+ )
2902
+ ] })
2903
+ ] }),
2904
+ ownerReady ? /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-3 rounded-lg border border-white/[0.06] bg-white/[0.03] px-3 py-2.5", children: [
2905
+ /* @__PURE__ */ jsx7("div", { className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-md border border-white/[0.08] bg-white/[0.06]", children: /* @__PURE__ */ jsx7(Wallet, { size: 14, className: "text-gray-400" }) }),
2906
+ /* @__PURE__ */ jsxs6("div", { className: "min-w-0 flex-1", children: [
2907
+ /* @__PURE__ */ jsx7("p", { className: "text-base text-gray-400", children: "Owner wallet connected" }),
2908
+ /* @__PURE__ */ jsx7("p", { className: "font-mono text-base text-white", children: formatAddress2(ownerAddress) })
2909
+ ] }),
2910
+ /* @__PURE__ */ jsx7(Check, { size: 16, className: "flex-shrink-0 text-trade-up" })
2911
+ ] }) : hasConnectedOwner && !ownerMatches ? /* @__PURE__ */ jsxs6("div", { className: "space-y-3 rounded-lg border border-trade-down/20 bg-trade-down/[0.08] p-3", children: [
2912
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-start gap-2", children: [
2913
+ /* @__PURE__ */ jsx7(
2914
+ AlertTriangle,
2915
+ {
2916
+ size: 14,
2917
+ className: "mt-0.5 flex-shrink-0 text-trade-down"
2918
+ }
2919
+ ),
2920
+ /* @__PURE__ */ jsxs6("div", { className: "min-w-0", children: [
2921
+ /* @__PURE__ */ jsx7("p", { className: "text-base text-trade-down", children: "Wrong owner wallet connected" }),
2922
+ /* @__PURE__ */ jsxs6("p", { className: "mt-1 font-mono text-base text-gray-400", children: [
2923
+ "Connected ",
2924
+ formatAddress2(ownerAddress)
2925
+ ] }),
2926
+ /* @__PURE__ */ jsxs6("p", { className: "font-mono text-base text-gray-400", children: [
2927
+ "Required ",
2928
+ formatAddress2(expectedOwnerAddress)
2929
+ ] })
2930
+ ] })
2931
+ ] }),
2932
+ onDisconnectWallet && /* @__PURE__ */ jsx7(
2933
+ "button",
2934
+ {
2935
+ onClick: onDisconnectWallet,
2936
+ disabled: isRenewing,
2937
+ className: "btn-raised flex w-full items-center justify-center gap-2 rounded-lg py-2 text-base font-medium disabled:cursor-not-allowed disabled:opacity-40",
2938
+ children: "Disconnect Wallet"
2939
+ }
2940
+ )
2941
+ ] }) : /* @__PURE__ */ jsxs6(
2942
+ "button",
2943
+ {
2944
+ onClick: onConnectWallet,
2945
+ className: "btn-raised flex w-full items-center justify-center gap-2 rounded-lg py-2 text-base font-medium",
2946
+ children: [
2947
+ /* @__PURE__ */ jsx7(Wallet, { size: 14 }),
2948
+ " Connect Owner Wallet",
2949
+ hasExpectedOwner ? ` ${formatAddress2(expectedOwnerAddress)}` : ""
2950
+ ]
2951
+ }
2952
+ ),
2953
+ /* @__PURE__ */ jsx7(
2954
+ ApprovalDurationPicker2,
2955
+ {
2956
+ value: approvalDurationMs,
2957
+ onChange: setApprovalDurationMs,
2958
+ options: durationOptions,
2959
+ disabled: isRenewing
2960
+ }
2961
+ ),
2962
+ error && /* @__PURE__ */ jsxs6("div", { className: "flex items-start gap-2 rounded-lg border border-trade-down/20 bg-trade-down/[0.08] p-3", children: [
2963
+ /* @__PURE__ */ jsx7(
2964
+ AlertTriangle,
2965
+ {
2966
+ size: 14,
2967
+ className: "mt-0.5 flex-shrink-0 text-trade-down"
2968
+ }
2969
+ ),
2970
+ /* @__PURE__ */ jsx7("p", { className: "text-base text-trade-down", children: error })
2971
+ ] })
2972
+ ] }),
2973
+ /* @__PURE__ */ jsxs6("div", { className: "space-y-2 px-6 pb-6", children: [
2974
+ /* @__PURE__ */ jsx7(
2975
+ "button",
2976
+ {
2977
+ onClick: handleRenew,
2978
+ disabled: !canRenew,
2979
+ className: `flex w-full items-center justify-center gap-2 rounded-lg py-2 text-base font-medium ${canRenew ? "btn-raised" : "btn-raised-disabled"}`,
2980
+ children: isRenewing ? /* @__PURE__ */ jsxs6(Fragment3, { children: [
2981
+ /* @__PURE__ */ jsx7(Loader2, { size: 14 }),
2982
+ " Renewing..."
2983
+ ] }) : "Renew Agent Wallet"
2984
+ }
2985
+ ),
2986
+ ownerReady && onDisconnectWallet && /* @__PURE__ */ jsx7(
2987
+ "button",
2988
+ {
2989
+ onClick: onDisconnectWallet,
2990
+ disabled: isRenewing,
2991
+ className: "w-full py-1.5 text-base text-gray-400 transition-colors hover:text-gray-300 disabled:cursor-not-allowed disabled:opacity-40",
2992
+ children: "Disconnect & use different owner"
2993
+ }
2994
+ )
2995
+ ] })
2996
+ ]
2997
+ }
2998
+ ) })
2999
+ ] }) });
3000
+ }
3001
+ function ApprovalDurationPicker2({
3002
+ value,
3003
+ onChange,
3004
+ options,
3005
+ disabled
3006
+ }) {
3007
+ return /* @__PURE__ */ jsxs6("div", { children: [
3008
+ /* @__PURE__ */ jsx7("label", { className: "mb-2 block text-base uppercase tracking-[0.1em] text-gray-400", children: "Approval Duration" }),
3009
+ /* @__PURE__ */ jsx7("div", { className: "grid grid-cols-4 gap-1.5", children: options.map((option) => /* @__PURE__ */ jsx7(
3010
+ "button",
3011
+ {
3012
+ type: "button",
3013
+ onClick: () => onChange(option.durationMs),
3014
+ disabled,
3015
+ className: `rounded py-1.5 text-base font-medium disabled:cursor-not-allowed disabled:opacity-50 ${value === option.durationMs ? "btn-raised-active" : "btn-raised"}`,
3016
+ children: option.label
3017
+ },
3018
+ `${option.label}-${option.durationMs}`
3019
+ )) })
1858
3020
  ] });
1859
3021
  }
1860
- function X(props) {
1861
- return /* @__PURE__ */ jsxs4("svg", { ...svgBase(props), children: [
1862
- /* @__PURE__ */ jsx5("path", { d: "M18 6 6 18" }),
1863
- /* @__PURE__ */ jsx5("path", { d: "m6 6 12 12" })
3022
+
3023
+ // src/WalletSelectorDropdown.tsx
3024
+ import { AnimatePresence as AnimatePresence7, motion as motion7 } from "framer-motion";
3025
+ import {
3026
+ Fragment as Fragment8,
3027
+ useCallback as useCallback9,
3028
+ useMemo as useMemo3,
3029
+ useState as useState8
3030
+ } from "react";
3031
+
3032
+ // src/AgentExpiryWarning.tsx
3033
+ import {
3034
+ useCallback as useCallback5,
3035
+ useRef as useRef2,
3036
+ useState as useState4
3037
+ } from "react";
3038
+ import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
3039
+ var EXPIRED_AGENT_COLOR = "#f59e0b";
3040
+ function AgentExpiryWarningIcon({
3041
+ message,
3042
+ onClick,
3043
+ size = 13
3044
+ }) {
3045
+ const triggerRef = useRef2(null);
3046
+ const [tooltipPosition, setTooltipPosition] = useState4(null);
3047
+ const setTriggerRef = useCallback5((node) => {
3048
+ triggerRef.current = node;
3049
+ }, []);
3050
+ const showTooltip = useCallback5(() => {
3051
+ const rect = triggerRef.current?.getBoundingClientRect();
3052
+ if (!rect) return;
3053
+ const tooltipWidth = 260;
3054
+ const left = Math.min(
3055
+ Math.max(rect.left + rect.width / 2, tooltipWidth / 2 + 8),
3056
+ window.innerWidth - tooltipWidth / 2 - 8
3057
+ );
3058
+ const top = rect.bottom + 8 < window.innerHeight - 48 ? rect.bottom + 8 : Math.max(8, rect.top - 44);
3059
+ setTooltipPosition({ left, top });
3060
+ }, []);
3061
+ const hideTooltip = useCallback5(() => {
3062
+ setTooltipPosition(null);
3063
+ }, []);
3064
+ const triggerStyle = {
3065
+ width: size + 5,
3066
+ height: size + 5,
3067
+ padding: 0,
3068
+ border: "none",
3069
+ borderRadius: 4,
3070
+ background: "transparent",
3071
+ color: EXPIRED_AGENT_COLOR,
3072
+ display: "inline-flex",
3073
+ alignItems: "center",
3074
+ justifyContent: "center",
3075
+ flexShrink: 0,
3076
+ cursor: onClick ? "pointer" : "help"
3077
+ };
3078
+ const sharedProps = {
3079
+ ref: setTriggerRef,
3080
+ "aria-label": "Agent approval expired",
3081
+ onMouseEnter: showTooltip,
3082
+ onMouseLeave: hideTooltip,
3083
+ onFocus: showTooltip,
3084
+ onBlur: hideTooltip,
3085
+ style: triggerStyle
3086
+ };
3087
+ return /* @__PURE__ */ jsxs7(Fragment4, { children: [
3088
+ onClick ? /* @__PURE__ */ jsx8(
3089
+ "button",
3090
+ {
3091
+ type: "button",
3092
+ ...sharedProps,
3093
+ onClick: (event) => {
3094
+ event.stopPropagation();
3095
+ onClick();
3096
+ },
3097
+ children: /* @__PURE__ */ jsx8(AlertTriangle, { size, color: EXPIRED_AGENT_COLOR })
3098
+ }
3099
+ ) : /* @__PURE__ */ jsx8("span", { ...sharedProps, children: /* @__PURE__ */ jsx8(AlertTriangle, { size, color: EXPIRED_AGENT_COLOR }) }),
3100
+ tooltipPosition && /* @__PURE__ */ jsx8(
3101
+ "div",
3102
+ {
3103
+ role: "tooltip",
3104
+ style: {
3105
+ position: "fixed",
3106
+ left: tooltipPosition.left,
3107
+ top: tooltipPosition.top,
3108
+ transform: "translateX(-50%)",
3109
+ zIndex: 1e4,
3110
+ width: 260,
3111
+ maxWidth: "calc(100vw - 16px)",
3112
+ padding: "7px 9px",
3113
+ borderRadius: 6,
3114
+ border: "1px solid rgba(255,255,255,0.12)",
3115
+ background: "#111827",
3116
+ boxShadow: "0 10px 28px rgba(0,0,0,0.45)",
3117
+ color: "#e5e7eb",
3118
+ fontSize: 12,
3119
+ lineHeight: "1rem",
3120
+ fontWeight: 500,
3121
+ pointerEvents: "none",
3122
+ whiteSpace: "normal"
3123
+ },
3124
+ children: message
3125
+ }
3126
+ )
1864
3127
  ] });
1865
3128
  }
1866
- function SpinKeyframes() {
1867
- return /* @__PURE__ */ jsx5("style", { children: `@keyframes hypurr-spin { to { transform: rotate(360deg); } }` });
1868
- }
3129
+
3130
+ // src/UserProfileModal.tsx
3131
+ import { AnimatePresence as AnimatePresence6, motion as motion6 } from "framer-motion";
3132
+ import {
3133
+ useCallback as useCallback8,
3134
+ useState as useState7
3135
+ } from "react";
3136
+
3137
+ // src/DeleteWalletModal.tsx
3138
+ import { AnimatePresence as AnimatePresence4, motion as motion4 } from "framer-motion";
3139
+ import {
3140
+ useCallback as useCallback6,
3141
+ useState as useState5
3142
+ } from "react";
1869
3143
 
1870
3144
  // src/profileStyles.ts
1871
3145
  var profileColors = {
@@ -1893,6 +3167,44 @@ var fontFamily = {
1893
3167
  sans: "Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif",
1894
3168
  mono: "Google Sans Code, Roboto Mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace"
1895
3169
  };
3170
+ var parseSrgb = (color) => {
3171
+ const value = color.trim();
3172
+ const shortHex = /^#([0-9a-f]{3})$/i.exec(value);
3173
+ if (shortHex) {
3174
+ const [r, g, b] = shortHex[1].split("").map((c) => parseInt(c + c, 16));
3175
+ return [r, g, b];
3176
+ }
3177
+ const longHex = /^#([0-9a-f]{6})$/i.exec(value);
3178
+ if (longHex) {
3179
+ const v = longHex[1];
3180
+ return [
3181
+ parseInt(v.slice(0, 2), 16),
3182
+ parseInt(v.slice(2, 4), 16),
3183
+ parseInt(v.slice(4, 6), 16)
3184
+ ];
3185
+ }
3186
+ const rgb = /^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*[\d.]+\s*)?\)$/i.exec(
3187
+ value
3188
+ );
3189
+ if (rgb) {
3190
+ return [parseInt(rgb[1], 10), parseInt(rgb[2], 10), parseInt(rgb[3], 10)];
3191
+ }
3192
+ return null;
3193
+ };
3194
+ var relativeLuminance = (color) => {
3195
+ const rgb = parseSrgb(color);
3196
+ if (!rgb) return null;
3197
+ const [r, g, b] = rgb.map((c) => {
3198
+ const v = c / 255;
3199
+ return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
3200
+ });
3201
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b;
3202
+ };
3203
+ var pickContrastColor = (background, lightFg = profileColors.text, darkFg = "#0a0a0a") => {
3204
+ const lum = relativeLuminance(background);
3205
+ if (lum === null) return lightFg;
3206
+ return lum > 0.5 ? darkFg : lightFg;
3207
+ };
1896
3208
  var colorWithAlpha = (color, alpha) => {
1897
3209
  const hex = color.trim();
1898
3210
  const shortHex = /^#([0-9a-f]{3})$/i.exec(hex);
@@ -2031,7 +3343,7 @@ var dangerOutlineButtonStyle = (enabled, hovered = false) => ({
2031
3343
  });
2032
3344
 
2033
3345
  // src/DeleteWalletModal.tsx
2034
- import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
3346
+ import { Fragment as Fragment5, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
2035
3347
  var DANGER_BG = "rgba(248,113,113,0.07)";
2036
3348
  var DANGER_BORDER = "rgba(248,113,113,0.2)";
2037
3349
  var backdropStyle2 = modalBackdropStyle(110);
@@ -2111,20 +3423,21 @@ function DeleteWalletModal({
2111
3423
  onConfirm,
2112
3424
  onNotify
2113
3425
  }) {
2114
- const [confirmName, setConfirmName] = useState2("");
2115
- const [isDeleting, setIsDeleting] = useState2(false);
2116
- const [error, setError] = useState2(null);
2117
- const [deleteHovered, setDeleteHovered] = useState2(false);
3426
+ const [confirmName, setConfirmName] = useState5("");
3427
+ const [isDeleting, setIsDeleting] = useState5(false);
3428
+ const [error, setError] = useState5(null);
3429
+ const [deleteHovered, setDeleteHovered] = useState5(false);
2118
3430
  const walletName = wallet?.name || "Unnamed Wallet";
3431
+ const displayAddress = wallet?.isAgent && wallet.agentEthereumAddress?.value ? wallet.agentEthereumAddress.value : wallet?.ethereumAddress;
2119
3432
  const isNameMatch = confirmName === walletName;
2120
3433
  const canDelete = isNameMatch && !isDeleting;
2121
- const handleClose = useCallback3(() => {
3434
+ const handleClose = useCallback6(() => {
2122
3435
  if (isDeleting) return;
2123
3436
  setConfirmName("");
2124
3437
  setError(null);
2125
3438
  onClose();
2126
3439
  }, [isDeleting, onClose]);
2127
- const handleDelete = useCallback3(async () => {
3440
+ const handleDelete = useCallback6(async () => {
2128
3441
  if (!wallet || !isNameMatch) return;
2129
3442
  setError(null);
2130
3443
  setIsDeleting(true);
@@ -2139,10 +3452,10 @@ function DeleteWalletModal({
2139
3452
  setIsDeleting(false);
2140
3453
  }
2141
3454
  }, [wallet, isNameMatch, onConfirm, onClose, onNotify]);
2142
- return /* @__PURE__ */ jsx6(AnimatePresence2, { children: isOpen && wallet && /* @__PURE__ */ jsxs5(Fragment2, { children: [
2143
- /* @__PURE__ */ jsx6(SpinKeyframes, {}),
2144
- /* @__PURE__ */ jsx6(
2145
- motion2.div,
3455
+ return /* @__PURE__ */ jsx9(AnimatePresence4, { children: isOpen && wallet && /* @__PURE__ */ jsxs8(Fragment5, { children: [
3456
+ /* @__PURE__ */ jsx9(SpinKeyframes, {}),
3457
+ /* @__PURE__ */ jsx9(
3458
+ motion4.div,
2146
3459
  {
2147
3460
  style: backdropStyle2,
2148
3461
  initial: { opacity: 0 },
@@ -2153,8 +3466,8 @@ function DeleteWalletModal({
2153
3466
  },
2154
3467
  "backdrop"
2155
3468
  ),
2156
- /* @__PURE__ */ jsx6("div", { style: wrapperStyle, children: /* @__PURE__ */ jsxs5(
2157
- motion2.div,
3469
+ /* @__PURE__ */ jsx9("div", { style: wrapperStyle, children: /* @__PURE__ */ jsxs8(
3470
+ motion4.div,
2158
3471
  {
2159
3472
  style: panelStyle,
2160
3473
  initial: { opacity: 0, y: 8 },
@@ -2163,22 +3476,22 @@ function DeleteWalletModal({
2163
3476
  transition: { duration: 0.18, ease: "easeOut" },
2164
3477
  onClick: (e) => e.stopPropagation(),
2165
3478
  children: [
2166
- /* @__PURE__ */ jsxs5("div", { style: headerStyle, children: [
2167
- /* @__PURE__ */ jsx6("h3", { style: titleStyle, children: "Delete Wallet" }),
2168
- /* @__PURE__ */ jsx6(
3479
+ /* @__PURE__ */ jsxs8("div", { style: headerStyle, children: [
3480
+ /* @__PURE__ */ jsx9("h3", { style: titleStyle, children: "Delete Wallet" }),
3481
+ /* @__PURE__ */ jsx9(
2169
3482
  "button",
2170
3483
  {
2171
3484
  onClick: handleClose,
2172
3485
  disabled: isDeleting,
2173
3486
  style: closeBtnStyle(isDeleting),
2174
3487
  "aria-label": "Close",
2175
- children: /* @__PURE__ */ jsx6(X, { size: 16 })
3488
+ children: /* @__PURE__ */ jsx9(X, { size: 16 })
2176
3489
  }
2177
3490
  )
2178
3491
  ] }),
2179
- /* @__PURE__ */ jsxs5("div", { style: bodyStyle, children: [
2180
- /* @__PURE__ */ jsxs5("div", { style: warningBoxStyle, children: [
2181
- /* @__PURE__ */ jsx6(
3492
+ /* @__PURE__ */ jsxs8("div", { style: bodyStyle, children: [
3493
+ /* @__PURE__ */ jsxs8("div", { style: warningBoxStyle, children: [
3494
+ /* @__PURE__ */ jsx9(
2182
3495
  AlertTriangle,
2183
3496
  {
2184
3497
  size: 15,
@@ -2186,8 +3499,8 @@ function DeleteWalletModal({
2186
3499
  style: { flexShrink: 0, marginTop: 2 }
2187
3500
  }
2188
3501
  ),
2189
- /* @__PURE__ */ jsxs5("div", { children: [
2190
- /* @__PURE__ */ jsx6(
3502
+ /* @__PURE__ */ jsxs8("div", { children: [
3503
+ /* @__PURE__ */ jsx9(
2191
3504
  "p",
2192
3505
  {
2193
3506
  style: {
@@ -2200,7 +3513,7 @@ function DeleteWalletModal({
2200
3513
  children: "This action cannot be undone"
2201
3514
  }
2202
3515
  ),
2203
- /* @__PURE__ */ jsx6(
3516
+ /* @__PURE__ */ jsx9(
2204
3517
  "p",
2205
3518
  {
2206
3519
  style: {
@@ -2214,8 +3527,8 @@ function DeleteWalletModal({
2214
3527
  )
2215
3528
  ] })
2216
3529
  ] }),
2217
- /* @__PURE__ */ jsxs5("div", { style: infoBoxStyle, children: [
2218
- /* @__PURE__ */ jsx6(
3530
+ /* @__PURE__ */ jsxs8("div", { style: infoBoxStyle, children: [
3531
+ /* @__PURE__ */ jsx9(
2219
3532
  "p",
2220
3533
  {
2221
3534
  style: {
@@ -2226,7 +3539,7 @@ function DeleteWalletModal({
2226
3539
  children: "Wallet to delete"
2227
3540
  }
2228
3541
  ),
2229
- /* @__PURE__ */ jsx6(
3542
+ /* @__PURE__ */ jsx9(
2230
3543
  "p",
2231
3544
  {
2232
3545
  style: {
@@ -2239,7 +3552,7 @@ function DeleteWalletModal({
2239
3552
  children: walletName
2240
3553
  }
2241
3554
  ),
2242
- /* @__PURE__ */ jsx6(
3555
+ /* @__PURE__ */ jsx9(
2243
3556
  "p",
2244
3557
  {
2245
3558
  style: {
@@ -2250,15 +3563,15 @@ function DeleteWalletModal({
2250
3563
  fontFamily: fontFamily.mono,
2251
3564
  wordBreak: "break-all"
2252
3565
  },
2253
- children: wallet.ethereumAddress
3566
+ children: displayAddress
2254
3567
  }
2255
3568
  )
2256
3569
  ] }),
2257
- /* @__PURE__ */ jsxs5("div", { children: [
2258
- /* @__PURE__ */ jsxs5("label", { style: labelStyle, children: [
3570
+ /* @__PURE__ */ jsxs8("div", { children: [
3571
+ /* @__PURE__ */ jsxs8("label", { style: labelStyle, children: [
2259
3572
  "Type",
2260
3573
  " ",
2261
- /* @__PURE__ */ jsxs5(
3574
+ /* @__PURE__ */ jsxs8(
2262
3575
  "span",
2263
3576
  {
2264
3577
  style: {
@@ -2275,7 +3588,7 @@ function DeleteWalletModal({
2275
3588
  " ",
2276
3589
  "to confirm"
2277
3590
  ] }),
2278
- /* @__PURE__ */ jsx6(
3591
+ /* @__PURE__ */ jsx9(
2279
3592
  "input",
2280
3593
  {
2281
3594
  type: "text",
@@ -2287,7 +3600,7 @@ function DeleteWalletModal({
2287
3600
  }
2288
3601
  )
2289
3602
  ] }),
2290
- error && /* @__PURE__ */ jsxs5(
3603
+ error && /* @__PURE__ */ jsxs8(
2291
3604
  "div",
2292
3605
  {
2293
3606
  style: {
@@ -2300,7 +3613,7 @@ function DeleteWalletModal({
2300
3613
  borderRadius: 8
2301
3614
  },
2302
3615
  children: [
2303
- /* @__PURE__ */ jsx6(
3616
+ /* @__PURE__ */ jsx9(
2304
3617
  AlertTriangle,
2305
3618
  {
2306
3619
  size: 14,
@@ -2308,7 +3621,7 @@ function DeleteWalletModal({
2308
3621
  style: { flexShrink: 0, marginTop: 2 }
2309
3622
  }
2310
3623
  ),
2311
- /* @__PURE__ */ jsx6(
3624
+ /* @__PURE__ */ jsx9(
2312
3625
  "p",
2313
3626
  {
2314
3627
  style: {
@@ -2324,7 +3637,7 @@ function DeleteWalletModal({
2324
3637
  }
2325
3638
  )
2326
3639
  ] }),
2327
- /* @__PURE__ */ jsx6("div", { style: footerStyle, children: /* @__PURE__ */ jsx6(
3640
+ /* @__PURE__ */ jsx9("div", { style: footerStyle, children: /* @__PURE__ */ jsx9(
2328
3641
  "button",
2329
3642
  {
2330
3643
  onClick: handleDelete,
@@ -2332,11 +3645,11 @@ function DeleteWalletModal({
2332
3645
  onMouseEnter: () => setDeleteHovered(true),
2333
3646
  onMouseLeave: () => setDeleteHovered(false),
2334
3647
  style: deleteButtonStyle(canDelete, deleteHovered),
2335
- children: isDeleting ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
2336
- /* @__PURE__ */ jsx6(Loader2, { size: 14 }),
3648
+ children: isDeleting ? /* @__PURE__ */ jsxs8(Fragment5, { children: [
3649
+ /* @__PURE__ */ jsx9(Loader2, { size: 14 }),
2337
3650
  " Deleting..."
2338
- ] }) : /* @__PURE__ */ jsxs5(Fragment2, { children: [
2339
- /* @__PURE__ */ jsx6(Trash2, { size: 14 }),
3651
+ ] }) : /* @__PURE__ */ jsxs8(Fragment5, { children: [
3652
+ /* @__PURE__ */ jsx9(Trash2, { size: 14 }),
2340
3653
  " Delete Wallet"
2341
3654
  ] })
2342
3655
  }
@@ -2349,15 +3662,15 @@ function DeleteWalletModal({
2349
3662
  }
2350
3663
 
2351
3664
  // src/RenameWalletModal.tsx
2352
- import { AnimatePresence as AnimatePresence3, motion as motion3 } from "framer-motion";
3665
+ import { AnimatePresence as AnimatePresence5, motion as motion5 } from "framer-motion";
2353
3666
  import {
2354
- useCallback as useCallback4,
3667
+ useCallback as useCallback7,
2355
3668
  useEffect as useEffect2,
2356
- useState as useState3
3669
+ useState as useState6
2357
3670
  } from "react";
2358
- import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
3671
+ import { Fragment as Fragment6, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
2359
3672
  var DANGER_BORDER2 = "rgba(248,113,113,0.2)";
2360
- var WALLET_NAME_REGEX = /^[a-zA-Z0-9/]+$/;
3673
+ var WALLET_NAME_REGEX2 = /^[a-zA-Z0-9/]+$/;
2361
3674
  var backdropStyle3 = modalBackdropStyle(110);
2362
3675
  var wrapperStyle2 = modalWrapperStyle2(111, 16);
2363
3676
  var panelStyle2 = {
@@ -2425,26 +3738,27 @@ function RenameWalletModal({
2425
3738
  onConfirm,
2426
3739
  onNotify
2427
3740
  }) {
2428
- const [name, setName] = useState3("");
2429
- const [isRenaming, setIsRenaming] = useState3(false);
2430
- const [error, setError] = useState3(null);
2431
- const [saveHovered, setSaveHovered] = useState3(false);
3741
+ const [name, setName] = useState6("");
3742
+ const [isRenaming, setIsRenaming] = useState6(false);
3743
+ const [error, setError] = useState6(null);
3744
+ const [saveHovered, setSaveHovered] = useState6(false);
2432
3745
  const currentName = wallet?.name || "Unnamed";
3746
+ const displayAddress = wallet?.isAgent && wallet.agentEthereumAddress?.value ? wallet.agentEthereumAddress.value : wallet?.ethereumAddress;
2433
3747
  const trimmedName = name.trim();
2434
3748
  const isNameChanged = trimmedName !== currentName;
2435
- const isNameValid = WALLET_NAME_REGEX.test(trimmedName);
3749
+ const isNameValid = WALLET_NAME_REGEX2.test(trimmedName);
2436
3750
  const canSubmit = isNameValid && isNameChanged && !isRenaming;
2437
3751
  useEffect2(() => {
2438
3752
  if (!wallet) return;
2439
3753
  setName(wallet.name || "");
2440
3754
  setError(null);
2441
3755
  }, [wallet]);
2442
- const handleClose = useCallback4(() => {
3756
+ const handleClose = useCallback7(() => {
2443
3757
  if (isRenaming) return;
2444
3758
  setError(null);
2445
3759
  onClose();
2446
3760
  }, [isRenaming, onClose]);
2447
- const handleRename = useCallback4(async () => {
3761
+ const handleRename = useCallback7(async () => {
2448
3762
  if (!wallet || !isNameValid || !isNameChanged) return;
2449
3763
  setError(null);
2450
3764
  setIsRenaming(true);
@@ -2466,10 +3780,10 @@ function RenameWalletModal({
2466
3780
  onClose,
2467
3781
  onNotify
2468
3782
  ]);
2469
- return /* @__PURE__ */ jsx7(AnimatePresence3, { children: isOpen && wallet && /* @__PURE__ */ jsxs6(Fragment3, { children: [
2470
- /* @__PURE__ */ jsx7(SpinKeyframes, {}),
2471
- /* @__PURE__ */ jsx7(
2472
- motion3.div,
3783
+ return /* @__PURE__ */ jsx10(AnimatePresence5, { children: isOpen && wallet && /* @__PURE__ */ jsxs9(Fragment6, { children: [
3784
+ /* @__PURE__ */ jsx10(SpinKeyframes, {}),
3785
+ /* @__PURE__ */ jsx10(
3786
+ motion5.div,
2473
3787
  {
2474
3788
  style: backdropStyle3,
2475
3789
  initial: { opacity: 0 },
@@ -2480,8 +3794,8 @@ function RenameWalletModal({
2480
3794
  },
2481
3795
  "backdrop"
2482
3796
  ),
2483
- /* @__PURE__ */ jsx7("div", { style: wrapperStyle2, children: /* @__PURE__ */ jsxs6(
2484
- motion3.div,
3797
+ /* @__PURE__ */ jsx10("div", { style: wrapperStyle2, children: /* @__PURE__ */ jsxs9(
3798
+ motion5.div,
2485
3799
  {
2486
3800
  style: panelStyle2,
2487
3801
  initial: { opacity: 0, y: 8 },
@@ -2490,22 +3804,22 @@ function RenameWalletModal({
2490
3804
  transition: { duration: 0.18, ease: "easeOut" },
2491
3805
  onClick: (e) => e.stopPropagation(),
2492
3806
  children: [
2493
- /* @__PURE__ */ jsxs6("div", { style: headerStyle2, children: [
2494
- /* @__PURE__ */ jsx7("h3", { style: titleStyle, children: "Rename Wallet" }),
2495
- /* @__PURE__ */ jsx7(
3807
+ /* @__PURE__ */ jsxs9("div", { style: headerStyle2, children: [
3808
+ /* @__PURE__ */ jsx10("h3", { style: titleStyle, children: "Rename Wallet" }),
3809
+ /* @__PURE__ */ jsx10(
2496
3810
  "button",
2497
3811
  {
2498
3812
  onClick: handleClose,
2499
3813
  disabled: isRenaming,
2500
3814
  style: closeBtnStyle(isRenaming),
2501
3815
  "aria-label": "Close",
2502
- children: /* @__PURE__ */ jsx7(X, { size: 16 })
3816
+ children: /* @__PURE__ */ jsx10(X, { size: 16 })
2503
3817
  }
2504
3818
  )
2505
3819
  ] }),
2506
- /* @__PURE__ */ jsxs6("div", { style: bodyStyle2, children: [
2507
- /* @__PURE__ */ jsxs6("div", { style: infoBoxStyle2, children: [
2508
- /* @__PURE__ */ jsx7(
3820
+ /* @__PURE__ */ jsxs9("div", { style: bodyStyle2, children: [
3821
+ /* @__PURE__ */ jsxs9("div", { style: infoBoxStyle2, children: [
3822
+ /* @__PURE__ */ jsx10(
2509
3823
  "p",
2510
3824
  {
2511
3825
  style: {
@@ -2516,7 +3830,7 @@ function RenameWalletModal({
2516
3830
  children: "Wallet"
2517
3831
  }
2518
3832
  ),
2519
- /* @__PURE__ */ jsx7(
3833
+ /* @__PURE__ */ jsx10(
2520
3834
  "p",
2521
3835
  {
2522
3836
  style: {
@@ -2529,7 +3843,7 @@ function RenameWalletModal({
2529
3843
  children: currentName
2530
3844
  }
2531
3845
  ),
2532
- /* @__PURE__ */ jsx7(
3846
+ /* @__PURE__ */ jsx10(
2533
3847
  "p",
2534
3848
  {
2535
3849
  style: {
@@ -2540,13 +3854,13 @@ function RenameWalletModal({
2540
3854
  fontFamily: fontFamily.mono,
2541
3855
  wordBreak: "break-all"
2542
3856
  },
2543
- children: wallet.ethereumAddress
3857
+ children: displayAddress
2544
3858
  }
2545
3859
  )
2546
3860
  ] }),
2547
- /* @__PURE__ */ jsxs6("div", { children: [
2548
- /* @__PURE__ */ jsx7("label", { style: labelStyle2, children: "Wallet name" }),
2549
- /* @__PURE__ */ jsx7(
3861
+ /* @__PURE__ */ jsxs9("div", { children: [
3862
+ /* @__PURE__ */ jsx10("label", { style: labelStyle2, children: "Wallet name" }),
3863
+ /* @__PURE__ */ jsx10(
2550
3864
  "input",
2551
3865
  {
2552
3866
  type: "text",
@@ -2564,7 +3878,7 @@ function RenameWalletModal({
2564
3878
  style: inputStyle2(!!error, isRenaming)
2565
3879
  }
2566
3880
  ),
2567
- /* @__PURE__ */ jsx7(
3881
+ /* @__PURE__ */ jsx10(
2568
3882
  "p",
2569
3883
  {
2570
3884
  style: {
@@ -2577,7 +3891,7 @@ function RenameWalletModal({
2577
3891
  }
2578
3892
  )
2579
3893
  ] }),
2580
- error && /* @__PURE__ */ jsxs6(
3894
+ error && /* @__PURE__ */ jsxs9(
2581
3895
  "div",
2582
3896
  {
2583
3897
  style: {
@@ -2590,7 +3904,7 @@ function RenameWalletModal({
2590
3904
  borderRadius: 8
2591
3905
  },
2592
3906
  children: [
2593
- /* @__PURE__ */ jsx7(
3907
+ /* @__PURE__ */ jsx10(
2594
3908
  AlertTriangle,
2595
3909
  {
2596
3910
  size: 14,
@@ -2598,7 +3912,7 @@ function RenameWalletModal({
2598
3912
  style: { flexShrink: 0, marginTop: 2 }
2599
3913
  }
2600
3914
  ),
2601
- /* @__PURE__ */ jsx7(
3915
+ /* @__PURE__ */ jsx10(
2602
3916
  "p",
2603
3917
  {
2604
3918
  style: {
@@ -2614,7 +3928,7 @@ function RenameWalletModal({
2614
3928
  }
2615
3929
  )
2616
3930
  ] }),
2617
- /* @__PURE__ */ jsx7("div", { style: footerStyle2, children: /* @__PURE__ */ jsx7(
3931
+ /* @__PURE__ */ jsx10("div", { style: footerStyle2, children: /* @__PURE__ */ jsx10(
2618
3932
  "button",
2619
3933
  {
2620
3934
  onClick: handleRename,
@@ -2622,11 +3936,11 @@ function RenameWalletModal({
2622
3936
  onMouseEnter: () => setSaveHovered(true),
2623
3937
  onMouseLeave: () => setSaveHovered(false),
2624
3938
  style: saveButtonStyle(canSubmit, saveHovered),
2625
- children: isRenaming ? /* @__PURE__ */ jsxs6(Fragment3, { children: [
2626
- /* @__PURE__ */ jsx7(Loader2, { size: 14 }),
3939
+ children: isRenaming ? /* @__PURE__ */ jsxs9(Fragment6, { children: [
3940
+ /* @__PURE__ */ jsx10(Loader2, { size: 14 }),
2627
3941
  " Saving..."
2628
- ] }) : /* @__PURE__ */ jsxs6(Fragment3, { children: [
2629
- /* @__PURE__ */ jsx7(Pencil, { size: 14 }),
3942
+ ] }) : /* @__PURE__ */ jsxs9(Fragment6, { children: [
3943
+ /* @__PURE__ */ jsx10(Pencil, { size: 14 }),
2630
3944
  " Save Name"
2631
3945
  ] })
2632
3946
  }
@@ -2639,7 +3953,7 @@ function RenameWalletModal({
2639
3953
  }
2640
3954
 
2641
3955
  // src/UserProfileModal.tsx
2642
- import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
3956
+ import { Fragment as Fragment7, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
2643
3957
  var DEFAULT_SLIPPAGE_OPTIONS = [
2644
3958
  { label: "0.5%", value: 5e-3 },
2645
3959
  { label: "1%", value: 0.01 },
@@ -2704,12 +4018,39 @@ var walletRowStyle = {
2704
4018
  border: `1px solid ${profileColors.surfaceBd}`,
2705
4019
  transition: "background-color 150ms, border-color 150ms"
2706
4020
  };
4021
+ function getWalletTypeMeta(wallet) {
4022
+ if (wallet.isAgent) {
4023
+ return {
4024
+ label: "Agent wallet",
4025
+ color: "#38bdf8",
4026
+ background: "rgba(56,189,248,0.16)",
4027
+ border: "rgba(56,189,248,0.34)",
4028
+ icon: /* @__PURE__ */ jsx11(Bot, { size: 10 })
4029
+ };
4030
+ }
4031
+ if (wallet.isReadOnly) {
4032
+ return {
4033
+ label: "Read-only wallet",
4034
+ color: "#a78bfa",
4035
+ background: "rgba(167,139,250,0.16)",
4036
+ border: "rgba(167,139,250,0.34)",
4037
+ icon: /* @__PURE__ */ jsx11(Eye, { size: 10 })
4038
+ };
4039
+ }
4040
+ return {
4041
+ label: "Private-key wallet",
4042
+ color: "#34d399",
4043
+ background: "rgba(52,211,153,0.16)",
4044
+ border: "rgba(52,211,153,0.34)",
4045
+ icon: /* @__PURE__ */ jsx11(KeyRound, { size: 10 })
4046
+ };
4047
+ }
2707
4048
  function ToggleSwitch({
2708
4049
  checked,
2709
4050
  onChange,
2710
4051
  accentColor
2711
4052
  }) {
2712
- return /* @__PURE__ */ jsx8(
4053
+ return /* @__PURE__ */ jsx11(
2713
4054
  "button",
2714
4055
  {
2715
4056
  onClick: onChange,
@@ -2728,7 +4069,7 @@ function ToggleSwitch({
2728
4069
  padding: 0,
2729
4070
  transition: "background 150ms"
2730
4071
  },
2731
- children: /* @__PURE__ */ jsx8(
4072
+ children: /* @__PURE__ */ jsx11(
2732
4073
  "span",
2733
4074
  {
2734
4075
  style: {
@@ -2736,9 +4077,9 @@ function ToggleSwitch({
2736
4077
  height: 12,
2737
4078
  width: 12,
2738
4079
  borderRadius: "50%",
2739
- background: profileColors.text,
4080
+ background: checked ? pickContrastColor(accentColor) : profileColors.text,
2740
4081
  transform: checked ? "translateX(20px)" : "translateX(4px)",
2741
- transition: "transform 150ms"
4082
+ transition: "transform 150ms, background 150ms"
2742
4083
  }
2743
4084
  }
2744
4085
  )
@@ -2751,8 +4092,8 @@ function RaisedButton({
2751
4092
  children,
2752
4093
  style
2753
4094
  }) {
2754
- const [hovered, setHovered] = useState4(false);
2755
- return /* @__PURE__ */ jsx8(
4095
+ const [hovered, setHovered] = useState7(false);
4096
+ return /* @__PURE__ */ jsx11(
2756
4097
  "button",
2757
4098
  {
2758
4099
  type: "button",
@@ -2775,8 +4116,8 @@ function SlippageButton({
2775
4116
  onClick,
2776
4117
  children
2777
4118
  }) {
2778
- const [hovered, setHovered] = useState4(false);
2779
- return /* @__PURE__ */ jsx8(
4119
+ const [hovered, setHovered] = useState7(false);
4120
+ return /* @__PURE__ */ jsx11(
2780
4121
  "button",
2781
4122
  {
2782
4123
  type: "button",
@@ -2804,6 +4145,7 @@ function UserProfileModal({
2804
4145
  onWalletDeleted,
2805
4146
  onWalletRenamed,
2806
4147
  onShowPortfolio,
4148
+ onRenewAgentWallet,
2807
4149
  onNotify,
2808
4150
  accentColor,
2809
4151
  principalColors
@@ -2815,9 +4157,9 @@ function UserProfileModal({
2815
4157
  renameWallet,
2816
4158
  authMethod
2817
4159
  } = useHypurrConnectInternal();
2818
- const [settingsTab, setSettingsTab] = useState4("ui");
2819
- const [walletToDelete, setWalletToDelete] = useState4(null);
2820
- const [walletToRename, setWalletToRename] = useState4(null);
4160
+ const [settingsTab, setSettingsTab] = useState7("ui");
4161
+ const [walletToDelete, setWalletToDelete] = useState7(null);
4162
+ const [walletToRename, setWalletToRename] = useState7(null);
2821
4163
  const profilePic = user?.photoUrl || "";
2822
4164
  const displayName = user?.displayName || "";
2823
4165
  const hfunScore = user?.hfunScore ?? null;
@@ -2825,30 +4167,30 @@ function UserProfileModal({
2825
4167
  const telegramId = user?.telegramId;
2826
4168
  const wallets = userWallets ?? [];
2827
4169
  const colors = resolvePrincipalColors(accentColor, principalColors);
2828
- const handleDeleteWallet = useCallback5(
4170
+ const handleDeleteWallet = useCallback8(
2829
4171
  async (walletId) => {
2830
4172
  await deleteWallet(walletId);
2831
4173
  onWalletDeleted?.(walletId);
2832
4174
  },
2833
4175
  [deleteWallet, onWalletDeleted]
2834
4176
  );
2835
- const handleRenameWallet = useCallback5(
4177
+ const handleRenameWallet = useCallback8(
2836
4178
  async (walletId, name) => {
2837
4179
  await renameWallet(walletId, name);
2838
4180
  onWalletRenamed?.(walletId, name);
2839
4181
  },
2840
4182
  [renameWallet, onWalletRenamed]
2841
4183
  );
2842
- const handleCopyAddress = useCallback5(() => {
4184
+ const handleCopyAddress = useCallback8(() => {
2843
4185
  if (!displayName) return;
2844
4186
  navigator.clipboard.writeText(displayName);
2845
4187
  onNotify?.({ type: "success", message: "Address copied" });
2846
4188
  }, [displayName, onNotify]);
2847
- return /* @__PURE__ */ jsxs7(Fragment4, { children: [
2848
- /* @__PURE__ */ jsx8(AnimatePresence4, { children: isOpen && /* @__PURE__ */ jsxs7(Fragment4, { children: [
2849
- /* @__PURE__ */ jsx8(SpinKeyframes, {}),
2850
- /* @__PURE__ */ jsx8(
2851
- motion4.div,
4189
+ return /* @__PURE__ */ jsxs10(Fragment7, { children: [
4190
+ /* @__PURE__ */ jsx11(AnimatePresence6, { children: isOpen && /* @__PURE__ */ jsxs10(Fragment7, { children: [
4191
+ /* @__PURE__ */ jsx11(SpinKeyframes, {}),
4192
+ /* @__PURE__ */ jsx11(
4193
+ motion6.div,
2852
4194
  {
2853
4195
  style: backdropStyle4,
2854
4196
  initial: { opacity: 0 },
@@ -2859,8 +4201,8 @@ function UserProfileModal({
2859
4201
  },
2860
4202
  "backdrop"
2861
4203
  ),
2862
- /* @__PURE__ */ jsx8("div", { style: wrapperStyle3, onClick: onClose, children: /* @__PURE__ */ jsxs7(
2863
- motion4.div,
4204
+ /* @__PURE__ */ jsx11("div", { style: wrapperStyle3, onClick: onClose, children: /* @__PURE__ */ jsxs10(
4205
+ motion6.div,
2864
4206
  {
2865
4207
  style: panelStyle3,
2866
4208
  initial: { opacity: 0, y: 8 },
@@ -2869,20 +4211,20 @@ function UserProfileModal({
2869
4211
  transition: { duration: 0.18, ease: "easeOut" },
2870
4212
  onClick: (e) => e.stopPropagation(),
2871
4213
  children: [
2872
- /* @__PURE__ */ jsxs7("div", { style: headerStyle3, children: [
2873
- /* @__PURE__ */ jsx8("h3", { style: titleStyle, children: "Profile & Settings" }),
2874
- /* @__PURE__ */ jsx8(
4214
+ /* @__PURE__ */ jsxs10("div", { style: headerStyle3, children: [
4215
+ /* @__PURE__ */ jsx11("h3", { style: titleStyle, children: "Profile & Settings" }),
4216
+ /* @__PURE__ */ jsx11(
2875
4217
  "button",
2876
4218
  {
2877
4219
  onClick: onClose,
2878
4220
  style: closeBtnStyle(),
2879
4221
  "aria-label": "Close",
2880
- children: /* @__PURE__ */ jsx8(X, { size: 16 })
4222
+ children: /* @__PURE__ */ jsx11(X, { size: 16 })
2881
4223
  }
2882
4224
  )
2883
4225
  ] }),
2884
- /* @__PURE__ */ jsxs7("div", { style: profileSectionStyle, children: [
2885
- authMethod === "eoa" && !profilePic ? /* @__PURE__ */ jsxs7(
4226
+ /* @__PURE__ */ jsxs10("div", { style: profileSectionStyle, children: [
4227
+ authMethod === "eoa" && !profilePic ? /* @__PURE__ */ jsxs10(
2886
4228
  "div",
2887
4229
  {
2888
4230
  style: {
@@ -2892,7 +4234,7 @@ function UserProfileModal({
2892
4234
  borderRadius: 8
2893
4235
  },
2894
4236
  children: [
2895
- /* @__PURE__ */ jsx8(
4237
+ /* @__PURE__ */ jsx11(
2896
4238
  "p",
2897
4239
  {
2898
4240
  style: {
@@ -2903,7 +4245,7 @@ function UserProfileModal({
2903
4245
  children: "Wallet"
2904
4246
  }
2905
4247
  ),
2906
- /* @__PURE__ */ jsxs7(
4248
+ /* @__PURE__ */ jsxs10(
2907
4249
  "div",
2908
4250
  {
2909
4251
  style: {
@@ -2913,7 +4255,7 @@ function UserProfileModal({
2913
4255
  gap: 8
2914
4256
  },
2915
4257
  children: [
2916
- /* @__PURE__ */ jsx8(
4258
+ /* @__PURE__ */ jsx11(
2917
4259
  "p",
2918
4260
  {
2919
4261
  style: {
@@ -2927,7 +4269,7 @@ function UserProfileModal({
2927
4269
  children: displayName
2928
4270
  }
2929
4271
  ),
2930
- /* @__PURE__ */ jsx8(
4272
+ /* @__PURE__ */ jsx11(
2931
4273
  "button",
2932
4274
  {
2933
4275
  onClick: handleCopyAddress,
@@ -2940,7 +4282,7 @@ function UserProfileModal({
2940
4282
  display: "flex"
2941
4283
  },
2942
4284
  "aria-label": "Copy address",
2943
- children: /* @__PURE__ */ jsx8(Copy, { size: 13 })
4285
+ children: /* @__PURE__ */ jsx11(Copy, { size: 13 })
2944
4286
  }
2945
4287
  )
2946
4288
  ]
@@ -2948,7 +4290,7 @@ function UserProfileModal({
2948
4290
  )
2949
4291
  ]
2950
4292
  }
2951
- ) : /* @__PURE__ */ jsxs7(
4293
+ ) : /* @__PURE__ */ jsxs10(
2952
4294
  "div",
2953
4295
  {
2954
4296
  style: {
@@ -2957,7 +4299,7 @@ function UserProfileModal({
2957
4299
  gap: 16
2958
4300
  },
2959
4301
  children: [
2960
- profilePic ? /* @__PURE__ */ jsx8(
4302
+ profilePic ? /* @__PURE__ */ jsx11(
2961
4303
  "img",
2962
4304
  {
2963
4305
  src: profilePic,
@@ -2969,7 +4311,7 @@ function UserProfileModal({
2969
4311
  border: `1px solid ${profileColors.surfaceBd}`
2970
4312
  }
2971
4313
  }
2972
- ) : /* @__PURE__ */ jsx8(
4314
+ ) : /* @__PURE__ */ jsx11(
2973
4315
  "div",
2974
4316
  {
2975
4317
  style: {
@@ -2989,8 +4331,8 @@ function UserProfileModal({
2989
4331
  children: displayName?.charAt(0)
2990
4332
  }
2991
4333
  ),
2992
- /* @__PURE__ */ jsxs7("div", { style: { flex: 1, minWidth: 0 }, children: [
2993
- /* @__PURE__ */ jsx8(
4334
+ /* @__PURE__ */ jsxs10("div", { style: { flex: 1, minWidth: 0 }, children: [
4335
+ /* @__PURE__ */ jsx11(
2994
4336
  "h4",
2995
4337
  {
2996
4338
  style: {
@@ -3006,7 +4348,7 @@ function UserProfileModal({
3006
4348
  children: displayName
3007
4349
  }
3008
4350
  ),
3009
- telegramId && /* @__PURE__ */ jsxs7(
4351
+ telegramId && /* @__PURE__ */ jsxs10(
3010
4352
  "p",
3011
4353
  {
3012
4354
  style: {
@@ -3025,7 +4367,7 @@ function UserProfileModal({
3025
4367
  ]
3026
4368
  }
3027
4369
  ),
3028
- user && /* @__PURE__ */ jsxs7(
4370
+ user && /* @__PURE__ */ jsxs10(
3029
4371
  "div",
3030
4372
  {
3031
4373
  style: {
@@ -3035,8 +4377,8 @@ function UserProfileModal({
3035
4377
  gap: 10
3036
4378
  },
3037
4379
  children: [
3038
- /* @__PURE__ */ jsxs7("div", { style: statBoxStyle, children: [
3039
- /* @__PURE__ */ jsxs7(
4380
+ /* @__PURE__ */ jsxs10("div", { style: statBoxStyle, children: [
4381
+ /* @__PURE__ */ jsxs10(
3040
4382
  "div",
3041
4383
  {
3042
4384
  style: {
@@ -3047,12 +4389,12 @@ function UserProfileModal({
3047
4389
  marginBottom: 6
3048
4390
  },
3049
4391
  children: [
3050
- /* @__PURE__ */ jsx8(Star, { size: 13, color: "#eab308", fill: "#eab308" }),
3051
- /* @__PURE__ */ jsx8("span", { style: upperLabelStyle, children: "Hfun Score" })
4392
+ /* @__PURE__ */ jsx11(Star, { size: 13, color: "#eab308", fill: "#eab308" }),
4393
+ /* @__PURE__ */ jsx11("span", { style: upperLabelStyle, children: "Hfun Score" })
3052
4394
  ]
3053
4395
  }
3054
4396
  ),
3055
- /* @__PURE__ */ jsx8(
4397
+ /* @__PURE__ */ jsx11(
3056
4398
  "p",
3057
4399
  {
3058
4400
  style: {
@@ -3067,8 +4409,8 @@ function UserProfileModal({
3067
4409
  }
3068
4410
  )
3069
4411
  ] }),
3070
- /* @__PURE__ */ jsxs7("div", { style: statBoxStyle, children: [
3071
- /* @__PURE__ */ jsxs7(
4412
+ /* @__PURE__ */ jsxs10("div", { style: statBoxStyle, children: [
4413
+ /* @__PURE__ */ jsxs10(
3072
4414
  "div",
3073
4415
  {
3074
4416
  style: {
@@ -3079,12 +4421,12 @@ function UserProfileModal({
3079
4421
  marginBottom: 6
3080
4422
  },
3081
4423
  children: [
3082
- /* @__PURE__ */ jsx8(User, { size: 13 }),
3083
- /* @__PURE__ */ jsx8("span", { style: upperLabelStyle, children: "Reputation" })
4424
+ /* @__PURE__ */ jsx11(User, { size: 13 }),
4425
+ /* @__PURE__ */ jsx11("span", { style: upperLabelStyle, children: "Reputation" })
3084
4426
  ]
3085
4427
  }
3086
4428
  ),
3087
- /* @__PURE__ */ jsx8(
4429
+ /* @__PURE__ */ jsx11(
3088
4430
  "p",
3089
4431
  {
3090
4432
  style: {
@@ -3103,43 +4445,43 @@ function UserProfileModal({
3103
4445
  }
3104
4446
  )
3105
4447
  ] }),
3106
- /* @__PURE__ */ jsxs7("div", { style: settingsSectionStyle, children: [
3107
- /* @__PURE__ */ jsxs7("div", { style: tabRowStyle, children: [
3108
- /* @__PURE__ */ jsxs7(
4448
+ /* @__PURE__ */ jsxs10("div", { style: settingsSectionStyle, children: [
4449
+ /* @__PURE__ */ jsxs10("div", { style: tabRowStyle, children: [
4450
+ /* @__PURE__ */ jsxs10(
3109
4451
  RaisedButton,
3110
4452
  {
3111
4453
  selected: settingsTab === "ui",
3112
4454
  onClick: () => setSettingsTab("ui"),
3113
4455
  children: [
3114
- /* @__PURE__ */ jsx8(Zap, { size: 13 }),
4456
+ /* @__PURE__ */ jsx11(Zap, { size: 13 }),
3115
4457
  " UI"
3116
4458
  ]
3117
4459
  }
3118
4460
  ),
3119
- /* @__PURE__ */ jsxs7(
4461
+ /* @__PURE__ */ jsxs10(
3120
4462
  RaisedButton,
3121
4463
  {
3122
4464
  selected: settingsTab === "trading",
3123
4465
  onClick: () => setSettingsTab("trading"),
3124
4466
  children: [
3125
- /* @__PURE__ */ jsx8(TrendingUp, { size: 13 }),
4467
+ /* @__PURE__ */ jsx11(TrendingUp, { size: 13 }),
3126
4468
  " Trading"
3127
4469
  ]
3128
4470
  }
3129
4471
  ),
3130
- /* @__PURE__ */ jsxs7(
4472
+ /* @__PURE__ */ jsxs10(
3131
4473
  RaisedButton,
3132
4474
  {
3133
4475
  selected: settingsTab === "wallets",
3134
4476
  onClick: () => setSettingsTab("wallets"),
3135
4477
  children: [
3136
- /* @__PURE__ */ jsx8(Wallet, { size: 13 }),
4478
+ /* @__PURE__ */ jsx11(Wallet, { size: 13 }),
3137
4479
  " Wallets"
3138
4480
  ]
3139
4481
  }
3140
4482
  )
3141
4483
  ] }),
3142
- settingsTab === "ui" && /* @__PURE__ */ jsx8(
4484
+ settingsTab === "ui" && /* @__PURE__ */ jsx11(
3143
4485
  "div",
3144
4486
  {
3145
4487
  style: {
@@ -3147,7 +4489,7 @@ function UserProfileModal({
3147
4489
  flexDirection: "column",
3148
4490
  gap: 12
3149
4491
  },
3150
- children: /* @__PURE__ */ jsxs7(
4492
+ children: /* @__PURE__ */ jsxs10(
3151
4493
  "div",
3152
4494
  {
3153
4495
  style: {
@@ -3157,7 +4499,7 @@ function UserProfileModal({
3157
4499
  padding: "8px 0"
3158
4500
  },
3159
4501
  children: [
3160
- /* @__PURE__ */ jsxs7(
4502
+ /* @__PURE__ */ jsxs10(
3161
4503
  "div",
3162
4504
  {
3163
4505
  style: {
@@ -3166,9 +4508,9 @@ function UserProfileModal({
3166
4508
  gap: 12
3167
4509
  },
3168
4510
  children: [
3169
- /* @__PURE__ */ jsx8(Zap, { size: 16, color: profileColors.muted }),
3170
- /* @__PURE__ */ jsxs7("div", { children: [
3171
- /* @__PURE__ */ jsx8(
4511
+ /* @__PURE__ */ jsx11(Zap, { size: 16, color: profileColors.muted }),
4512
+ /* @__PURE__ */ jsxs10("div", { children: [
4513
+ /* @__PURE__ */ jsx11(
3172
4514
  "p",
3173
4515
  {
3174
4516
  style: {
@@ -3181,7 +4523,7 @@ function UserProfileModal({
3181
4523
  children: "Animations"
3182
4524
  }
3183
4525
  ),
3184
- /* @__PURE__ */ jsx8(
4526
+ /* @__PURE__ */ jsx11(
3185
4527
  "p",
3186
4528
  {
3187
4529
  style: {
@@ -3197,7 +4539,7 @@ function UserProfileModal({
3197
4539
  ]
3198
4540
  }
3199
4541
  ),
3200
- /* @__PURE__ */ jsx8(
4542
+ /* @__PURE__ */ jsx11(
3201
4543
  ToggleSwitch,
3202
4544
  {
3203
4545
  checked: animationsEnabled,
@@ -3210,8 +4552,8 @@ function UserProfileModal({
3210
4552
  )
3211
4553
  }
3212
4554
  ),
3213
- settingsTab === "trading" && /* @__PURE__ */ jsxs7("div", { style: { padding: "8px 0" }, children: [
3214
- /* @__PURE__ */ jsxs7(
4555
+ settingsTab === "trading" && /* @__PURE__ */ jsxs10("div", { style: { padding: "8px 0" }, children: [
4556
+ /* @__PURE__ */ jsxs10(
3215
4557
  "div",
3216
4558
  {
3217
4559
  style: {
@@ -3221,9 +4563,9 @@ function UserProfileModal({
3221
4563
  marginBottom: 12
3222
4564
  },
3223
4565
  children: [
3224
- /* @__PURE__ */ jsx8(TrendingUp, { size: 16, color: profileColors.muted }),
3225
- /* @__PURE__ */ jsxs7("div", { children: [
3226
- /* @__PURE__ */ jsx8(
4566
+ /* @__PURE__ */ jsx11(TrendingUp, { size: 16, color: profileColors.muted }),
4567
+ /* @__PURE__ */ jsxs10("div", { children: [
4568
+ /* @__PURE__ */ jsx11(
3227
4569
  "p",
3228
4570
  {
3229
4571
  style: {
@@ -3236,7 +4578,7 @@ function UserProfileModal({
3236
4578
  children: "Default Slippage"
3237
4579
  }
3238
4580
  ),
3239
- /* @__PURE__ */ jsx8(
4581
+ /* @__PURE__ */ jsx11(
3240
4582
  "p",
3241
4583
  {
3242
4584
  style: {
@@ -3252,7 +4594,7 @@ function UserProfileModal({
3252
4594
  ]
3253
4595
  }
3254
4596
  ),
3255
- /* @__PURE__ */ jsx8("div", { style: { display: "flex", gap: 6 }, children: slippageOptions.map((option) => /* @__PURE__ */ jsx8(
4597
+ /* @__PURE__ */ jsx11("div", { style: { display: "flex", gap: 6 }, children: slippageOptions.map((option) => /* @__PURE__ */ jsx11(
3256
4598
  SlippageButton,
3257
4599
  {
3258
4600
  onClick: () => onSlippageChange(option.value),
@@ -3262,7 +4604,7 @@ function UserProfileModal({
3262
4604
  option.value
3263
4605
  )) })
3264
4606
  ] }),
3265
- settingsTab === "wallets" && /* @__PURE__ */ jsxs7(
4607
+ settingsTab === "wallets" && /* @__PURE__ */ jsxs10(
3266
4608
  "div",
3267
4609
  {
3268
4610
  style: {
@@ -3271,7 +4613,7 @@ function UserProfileModal({
3271
4613
  gap: 8
3272
4614
  },
3273
4615
  children: [
3274
- wallets.length === 0 ? /* @__PURE__ */ jsxs7(
4616
+ wallets.length === 0 ? /* @__PURE__ */ jsxs10(
3275
4617
  "div",
3276
4618
  {
3277
4619
  style: {
@@ -3279,7 +4621,7 @@ function UserProfileModal({
3279
4621
  padding: "32px 0"
3280
4622
  },
3281
4623
  children: [
3282
- /* @__PURE__ */ jsx8(
4624
+ /* @__PURE__ */ jsx11(
3283
4625
  "div",
3284
4626
  {
3285
4627
  style: {
@@ -3292,10 +4634,10 @@ function UserProfileModal({
3292
4634
  justifyContent: "center",
3293
4635
  margin: "0 auto 12px"
3294
4636
  },
3295
- children: /* @__PURE__ */ jsx8(Wallet, { size: 18, color: profileColors.muted })
4637
+ children: /* @__PURE__ */ jsx11(Wallet, { size: 18, color: profileColors.muted })
3296
4638
  }
3297
4639
  ),
3298
- /* @__PURE__ */ jsx8(
4640
+ /* @__PURE__ */ jsx11(
3299
4641
  "p",
3300
4642
  {
3301
4643
  style: {
@@ -3309,7 +4651,7 @@ function UserProfileModal({
3309
4651
  )
3310
4652
  ]
3311
4653
  }
3312
- ) : /* @__PURE__ */ jsx8(
4654
+ ) : /* @__PURE__ */ jsx11(
3313
4655
  "div",
3314
4656
  {
3315
4657
  style: {
@@ -3319,20 +4661,21 @@ function UserProfileModal({
3319
4661
  flexDirection: "column",
3320
4662
  gap: 6
3321
4663
  },
3322
- children: wallets.map((wallet) => /* @__PURE__ */ jsx8(
4664
+ children: wallets.map((wallet) => /* @__PURE__ */ jsx11(
3323
4665
  WalletRow,
3324
4666
  {
3325
4667
  wallet,
3326
4668
  colors,
3327
4669
  onRename: () => setWalletToRename(wallet),
3328
4670
  onDelete: () => setWalletToDelete(wallet),
4671
+ onRenewAgentWallet: wallet.isAgent && onRenewAgentWallet ? () => onRenewAgentWallet(wallet) : void 0,
3329
4672
  onShowPortfolio: onShowPortfolio ? () => onShowPortfolio(wallet) : void 0
3330
4673
  },
3331
4674
  wallet.id
3332
4675
  ))
3333
4676
  }
3334
4677
  ),
3335
- /* @__PURE__ */ jsxs7(
4678
+ /* @__PURE__ */ jsxs10(
3336
4679
  "p",
3337
4680
  {
3338
4681
  style: {
@@ -3354,7 +4697,7 @@ function UserProfileModal({
3354
4697
  }
3355
4698
  )
3356
4699
  ] }),
3357
- /* @__PURE__ */ jsx8("div", { style: { padding: "0 24px 24px" }, children: /* @__PURE__ */ jsx8(
4700
+ /* @__PURE__ */ jsx11("div", { style: { padding: "0 24px 24px" }, children: /* @__PURE__ */ jsx11(
3358
4701
  "button",
3359
4702
  {
3360
4703
  onClick: onClose,
@@ -3376,7 +4719,7 @@ function UserProfileModal({
3376
4719
  "panel"
3377
4720
  ) })
3378
4721
  ] }) }),
3379
- /* @__PURE__ */ jsx8(
4722
+ /* @__PURE__ */ jsx11(
3380
4723
  DeleteWalletModal,
3381
4724
  {
3382
4725
  isOpen: !!walletToDelete,
@@ -3386,7 +4729,7 @@ function UserProfileModal({
3386
4729
  onNotify
3387
4730
  }
3388
4731
  ),
3389
- /* @__PURE__ */ jsx8(
4732
+ /* @__PURE__ */ jsx11(
3390
4733
  RenameWalletModal,
3391
4734
  {
3392
4735
  isOpen: !!walletToRename,
@@ -3404,84 +4747,134 @@ function WalletRow({
3404
4747
  colors,
3405
4748
  onRename,
3406
4749
  onDelete,
4750
+ onRenewAgentWallet,
3407
4751
  onShowPortfolio
3408
4752
  }) {
3409
- const [hovered, setHovered] = useState4(false);
3410
- return /* @__PURE__ */ jsxs7(
4753
+ const [hovered, setHovered] = useState7(false);
4754
+ const agentExpiryTitle = getAgentExpiryTitle(wallet);
4755
+ const isAgentExpired = !!agentExpiryTitle;
4756
+ const displayAddress = wallet.isAgent && wallet.agentEthereumAddress?.value ? wallet.agentEthereumAddress.value : wallet.ethereumAddress;
4757
+ const typeMeta = getWalletTypeMeta(wallet);
4758
+ return /* @__PURE__ */ jsxs10(
3411
4759
  "div",
3412
4760
  {
3413
4761
  style: {
3414
4762
  ...walletRowStyle,
3415
- background: hovered ? profileColors.surfaceBtnHover : profileColors.surfaceBtn,
3416
- borderColor: hovered ? profileColors.surfaceBdHover : profileColors.surfaceBd
4763
+ background: isAgentExpired ? hovered ? "rgba(245,158,11,0.12)" : "rgba(245,158,11,0.07)" : hovered ? profileColors.surfaceBtnHover : profileColors.surfaceBtn,
4764
+ borderColor: isAgentExpired ? "rgba(245,158,11,0.34)" : hovered ? profileColors.surfaceBdHover : profileColors.surfaceBd
3417
4765
  },
3418
4766
  onMouseEnter: () => setHovered(true),
3419
4767
  onMouseLeave: () => setHovered(false),
3420
4768
  children: [
3421
- /* @__PURE__ */ jsx8(
4769
+ /* @__PURE__ */ jsxs10(
3422
4770
  "div",
3423
4771
  {
3424
4772
  style: {
4773
+ position: "relative",
3425
4774
  width: 32,
3426
4775
  height: 32,
3427
4776
  borderRadius: 6,
3428
- background: colors.accentBackground,
3429
- border: `1px solid ${colors.accentBorder}`,
4777
+ background: isAgentExpired ? "rgba(245,158,11,0.12)" : colors.accentBackground,
4778
+ border: `1px solid ${isAgentExpired ? "rgba(245,158,11,0.34)" : colors.accentBorder}`,
3430
4779
  display: "flex",
3431
4780
  alignItems: "center",
3432
4781
  justifyContent: "center",
3433
4782
  flexShrink: 0
3434
4783
  },
3435
- children: /* @__PURE__ */ jsx8(
3436
- "span",
3437
- {
3438
- style: {
3439
- fontSize: 12.5,
3440
- lineHeight: "1rem",
3441
- fontWeight: 600,
3442
- color: colors.accentText
3443
- },
3444
- children: (wallet.name || "W")[0].toUpperCase()
3445
- }
3446
- )
4784
+ children: [
4785
+ /* @__PURE__ */ jsx11(
4786
+ "span",
4787
+ {
4788
+ style: {
4789
+ fontSize: 12.5,
4790
+ lineHeight: "1rem",
4791
+ fontWeight: 600,
4792
+ color: isAgentExpired ? EXPIRED_AGENT_COLOR : colors.accentText
4793
+ },
4794
+ children: (wallet.name || "W")[0].toUpperCase()
4795
+ }
4796
+ ),
4797
+ /* @__PURE__ */ jsx11(
4798
+ "span",
4799
+ {
4800
+ role: "img",
4801
+ "aria-label": typeMeta.label,
4802
+ title: typeMeta.label,
4803
+ style: {
4804
+ position: "absolute",
4805
+ right: -5,
4806
+ bottom: -5,
4807
+ width: 16,
4808
+ height: 16,
4809
+ borderRadius: "50%",
4810
+ display: "flex",
4811
+ alignItems: "center",
4812
+ justifyContent: "center",
4813
+ color: typeMeta.color,
4814
+ background: typeMeta.background,
4815
+ border: `1px solid ${typeMeta.border}`,
4816
+ boxShadow: "0 1px 4px rgba(0,0,0,0.35)"
4817
+ },
4818
+ children: typeMeta.icon
4819
+ }
4820
+ )
4821
+ ]
3447
4822
  }
3448
4823
  ),
3449
- /* @__PURE__ */ jsxs7("div", { style: { flex: 1, minWidth: 0 }, children: [
3450
- /* @__PURE__ */ jsx8(
3451
- "p",
4824
+ /* @__PURE__ */ jsxs10("div", { style: { flex: 1, minWidth: 0 }, children: [
4825
+ /* @__PURE__ */ jsx11(
4826
+ "div",
3452
4827
  {
3453
4828
  style: {
3454
- margin: 0,
3455
- fontSize: 12.5,
3456
- lineHeight: "1rem",
3457
- fontWeight: 500,
3458
- color: profileColors.text,
3459
- overflow: "hidden",
3460
- textOverflow: "ellipsis",
3461
- whiteSpace: "nowrap"
4829
+ display: "flex",
4830
+ alignItems: "center",
4831
+ gap: 5,
4832
+ minWidth: 0
3462
4833
  },
3463
- children: wallet.name || "Unnamed"
4834
+ children: /* @__PURE__ */ jsx11(
4835
+ "p",
4836
+ {
4837
+ style: {
4838
+ margin: 0,
4839
+ fontSize: 12.5,
4840
+ lineHeight: "1rem",
4841
+ fontWeight: 500,
4842
+ color: isAgentExpired ? EXPIRED_AGENT_COLOR : profileColors.text,
4843
+ overflow: "hidden",
4844
+ textOverflow: "ellipsis",
4845
+ whiteSpace: "nowrap"
4846
+ },
4847
+ children: wallet.name || "Unnamed"
4848
+ }
4849
+ )
3464
4850
  }
3465
4851
  ),
3466
- /* @__PURE__ */ jsxs7(
4852
+ /* @__PURE__ */ jsxs10(
3467
4853
  "p",
3468
4854
  {
3469
4855
  style: {
3470
4856
  margin: 0,
3471
4857
  fontSize: 12.5,
3472
4858
  lineHeight: "1rem",
3473
- color: profileColors.muted,
4859
+ color: isAgentExpired ? "rgba(245,158,11,0.76)" : profileColors.muted,
3474
4860
  fontFamily: fontFamily.mono
3475
4861
  },
3476
4862
  children: [
3477
- wallet.ethereumAddress?.slice(0, 6),
4863
+ displayAddress?.slice(0, 6),
3478
4864
  "...",
3479
- wallet.ethereumAddress?.slice(-4)
4865
+ displayAddress?.slice(-4)
3480
4866
  ]
3481
4867
  }
3482
4868
  )
3483
4869
  ] }),
3484
- /* @__PURE__ */ jsxs7(
4870
+ agentExpiryTitle && /* @__PURE__ */ jsx11(
4871
+ AgentExpiryWarningIcon,
4872
+ {
4873
+ message: agentExpiryTitle,
4874
+ onClick: onRenewAgentWallet
4875
+ }
4876
+ ),
4877
+ /* @__PURE__ */ jsxs10(
3485
4878
  "div",
3486
4879
  {
3487
4880
  style: {
@@ -3493,7 +4886,18 @@ function WalletRow({
3493
4886
  transition: "opacity 120ms"
3494
4887
  },
3495
4888
  children: [
3496
- onShowPortfolio && /* @__PURE__ */ jsx8(
4889
+ wallet.isAgent && onRenewAgentWallet && /* @__PURE__ */ jsx11(
4890
+ IconBtn,
4891
+ {
4892
+ color: isAgentExpired ? EXPIRED_AGENT_COLOR : colors.accent,
4893
+ hoverBackgroundColor: isAgentExpired ? "rgba(245,158,11,0.12)" : colors.accentHoverBackground,
4894
+ title: "Renew agent wallet",
4895
+ ariaLabel: `Renew agent wallet for ${wallet.name || "wallet"}`,
4896
+ onClick: onRenewAgentWallet,
4897
+ children: /* @__PURE__ */ jsx11(RefreshCw, { size: 13 })
4898
+ }
4899
+ ),
4900
+ onShowPortfolio && /* @__PURE__ */ jsx11(
3497
4901
  IconBtn,
3498
4902
  {
3499
4903
  color: colors.accent,
@@ -3501,10 +4905,10 @@ function WalletRow({
3501
4905
  title: "View portfolio",
3502
4906
  ariaLabel: `View portfolio for ${wallet.name || "wallet"}`,
3503
4907
  onClick: onShowPortfolio,
3504
- children: /* @__PURE__ */ jsx8(LayoutDashboard, { size: 13 })
4908
+ children: /* @__PURE__ */ jsx11(LayoutDashboard, { size: 13 })
3505
4909
  }
3506
4910
  ),
3507
- /* @__PURE__ */ jsx8(
4911
+ /* @__PURE__ */ jsx11(
3508
4912
  IconBtn,
3509
4913
  {
3510
4914
  color: colors.accent,
@@ -3512,10 +4916,10 @@ function WalletRow({
3512
4916
  title: "Rename wallet",
3513
4917
  ariaLabel: `Rename ${wallet.name || "wallet"}`,
3514
4918
  onClick: onRename,
3515
- children: /* @__PURE__ */ jsx8(Pencil, { size: 13 })
4919
+ children: /* @__PURE__ */ jsx11(Pencil, { size: 13 })
3516
4920
  }
3517
4921
  ),
3518
- /* @__PURE__ */ jsx8(
4922
+ /* @__PURE__ */ jsx11(
3519
4923
  IconBtn,
3520
4924
  {
3521
4925
  color: "#ef4444",
@@ -3523,7 +4927,7 @@ function WalletRow({
3523
4927
  title: "Delete wallet",
3524
4928
  ariaLabel: `Delete ${wallet.name || "wallet"}`,
3525
4929
  onClick: onDelete,
3526
- children: /* @__PURE__ */ jsx8(Trash2, { size: 13 })
4930
+ children: /* @__PURE__ */ jsx11(Trash2, { size: 13 })
3527
4931
  }
3528
4932
  )
3529
4933
  ]
@@ -3541,8 +4945,8 @@ function IconBtn({
3541
4945
  ariaLabel,
3542
4946
  onClick
3543
4947
  }) {
3544
- const [hovered, setHovered] = useState4(false);
3545
- return /* @__PURE__ */ jsx8(
4948
+ const [hovered, setHovered] = useState7(false);
4949
+ return /* @__PURE__ */ jsx11(
3546
4950
  "button",
3547
4951
  {
3548
4952
  onMouseEnter: () => setHovered(true),
@@ -3568,7 +4972,7 @@ function IconBtn({
3568
4972
  }
3569
4973
 
3570
4974
  // src/WalletSelectorDropdown.tsx
3571
- import { Fragment as Fragment6, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
4975
+ import { Fragment as Fragment9, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
3572
4976
  var DEFAULT_BACKGROUND_COLOR2 = "rgba(20,20,20,0.95)";
3573
4977
  var getWalletNameParts = (name) => (name ?? "").split("/").map((part) => part.trim()).filter(Boolean);
3574
4978
  var buildWalletListEntries = (wallets) => {
@@ -3638,6 +5042,28 @@ var formatCompactAddress = (addr) => {
3638
5042
  if (!addr) return "";
3639
5043
  return `${addr.slice(0, 4)}...${addr.slice(-2)}`;
3640
5044
  };
5045
+ var getDisplayAddress = (wallet) => wallet.isAgent && wallet.agentEthereumAddress?.value ? wallet.agentEthereumAddress.value : wallet.ethereumAddress;
5046
+ function getWalletTypeMeta2(wallet) {
5047
+ if (wallet.isAgent) {
5048
+ return {
5049
+ label: "Agent wallet",
5050
+ color: "#38bdf8",
5051
+ icon: /* @__PURE__ */ jsx12(Bot, { size: 12 })
5052
+ };
5053
+ }
5054
+ if (wallet.isReadOnly) {
5055
+ return {
5056
+ label: "Read-only wallet",
5057
+ color: "#a78bfa",
5058
+ icon: /* @__PURE__ */ jsx12(Eye, { size: 12 })
5059
+ };
5060
+ }
5061
+ return {
5062
+ label: "Private-key wallet",
5063
+ color: "#34d399",
5064
+ icon: /* @__PURE__ */ jsx12(KeyRound, { size: 12 })
5065
+ };
5066
+ }
3641
5067
  var rootStyle = {
3642
5068
  position: "absolute",
3643
5069
  right: 0,
@@ -3680,6 +5106,7 @@ function WalletSelectorDropdown({
3680
5106
  onClose,
3681
5107
  onAddWallet,
3682
5108
  onShowPortfolio,
5109
+ onRenewAgentWallet,
3683
5110
  onLogout,
3684
5111
  onNotify,
3685
5112
  vipThreshold = 10,
@@ -3692,19 +5119,20 @@ function WalletSelectorDropdown({
3692
5119
  onWalletRenamed,
3693
5120
  accentColor,
3694
5121
  principalColors,
3695
- backgroundColor = DEFAULT_BACKGROUND_COLOR2
5122
+ backgroundColor = DEFAULT_BACKGROUND_COLOR2,
5123
+ extraFooterItems
3696
5124
  }) {
3697
5125
  const { user, wallets, selectedWalletId, selectWallet, logout, authMethod } = useHypurrConnectInternal();
3698
- const [profileOpen, setProfileOpen] = useState5(false);
3699
- const openProfile = useCallback6(() => {
5126
+ const [profileOpen, setProfileOpen] = useState8(false);
5127
+ const openProfile = useCallback9(() => {
3700
5128
  setProfileOpen(true);
3701
5129
  onClose();
3702
5130
  }, [onClose]);
3703
- const walletListEntries = useMemo2(
5131
+ const walletListEntries = useMemo3(
3704
5132
  () => buildWalletListEntries(Array.isArray(wallets) ? wallets : void 0),
3705
5133
  [wallets]
3706
5134
  );
3707
- const handleCopyAddress = useCallback6(
5135
+ const handleCopyAddress = useCallback9(
3708
5136
  (address) => {
3709
5137
  if (!address) return;
3710
5138
  navigator.clipboard.writeText(address);
@@ -3712,7 +5140,7 @@ function WalletSelectorDropdown({
3712
5140
  },
3713
5141
  [onNotify]
3714
5142
  );
3715
- const handleLogout = useCallback6(() => {
5143
+ const handleLogout = useCallback9(() => {
3716
5144
  onLogout?.();
3717
5145
  logout();
3718
5146
  onClose();
@@ -3725,13 +5153,19 @@ function WalletSelectorDropdown({
3725
5153
  const renderWalletRow = (item, depth) => {
3726
5154
  const { wallet, label } = item;
3727
5155
  const isSelected = wallet.id === selectedWalletId;
3728
- const compactAddress = formatCompactAddress(wallet.ethereumAddress);
3729
- return /* @__PURE__ */ jsx9(
5156
+ const displayAddress = getDisplayAddress(wallet);
5157
+ const compactAddress = formatCompactAddress(displayAddress);
5158
+ const agentExpiryTitle = getAgentExpiryTitle({
5159
+ isAgent: !!wallet.isAgent,
5160
+ agentExpiresAt: wallet.agentExpiresAt
5161
+ });
5162
+ return /* @__PURE__ */ jsx12(
3730
5163
  WalletRow2,
3731
5164
  {
3732
5165
  depth,
3733
5166
  isSelected,
3734
5167
  label,
5168
+ walletType: getWalletTypeMeta2(wallet),
3735
5169
  compactAddress,
3736
5170
  onSelect: () => {
3737
5171
  selectWallet(wallet.id);
@@ -3741,15 +5175,20 @@ function WalletSelectorDropdown({
3741
5175
  onShowPortfolio(wallet);
3742
5176
  onClose();
3743
5177
  } : void 0,
3744
- onCopy: () => handleCopyAddress(wallet.ethereumAddress),
5178
+ onCopy: () => handleCopyAddress(displayAddress),
5179
+ agentExpiryTitle,
5180
+ onRenewAgentWallet: wallet.isAgent && onRenewAgentWallet ? () => {
5181
+ onRenewAgentWallet(wallet);
5182
+ onClose();
5183
+ } : void 0,
3745
5184
  colors
3746
5185
  },
3747
5186
  wallet.id
3748
5187
  );
3749
5188
  };
3750
- return /* @__PURE__ */ jsxs8(Fragment6, { children: [
3751
- /* @__PURE__ */ jsx9(AnimatePresence5, { children: isOpen && /* @__PURE__ */ jsxs8(
3752
- motion5.div,
5189
+ return /* @__PURE__ */ jsxs11(Fragment9, { children: [
5190
+ /* @__PURE__ */ jsx12(AnimatePresence7, { children: isOpen && /* @__PURE__ */ jsxs11(
5191
+ motion7.div,
3753
5192
  {
3754
5193
  style: { ...rootStyle, background: backgroundColor },
3755
5194
  initial: { opacity: 0, scale: 0.95 },
@@ -3757,7 +5196,7 @@ function WalletSelectorDropdown({
3757
5196
  exit: { opacity: 0, scale: 0.95 },
3758
5197
  transition: { duration: 0.15, ease: "easeOut" },
3759
5198
  children: [
3760
- /* @__PURE__ */ jsxs8(
5199
+ /* @__PURE__ */ jsxs11(
3761
5200
  "button",
3762
5201
  {
3763
5202
  onClick: openProfile,
@@ -3780,7 +5219,7 @@ function WalletSelectorDropdown({
3780
5219
  onMouseEnter: (e) => e.currentTarget.style.background = "rgba(255,255,255,0.06)",
3781
5220
  onMouseLeave: (e) => e.currentTarget.style.background = "transparent",
3782
5221
  children: [
3783
- profilePic ? /* @__PURE__ */ jsxs8(
5222
+ profilePic ? /* @__PURE__ */ jsxs11(
3784
5223
  "div",
3785
5224
  {
3786
5225
  style: {
@@ -3790,7 +5229,7 @@ function WalletSelectorDropdown({
3790
5229
  background: isVip ? "linear-gradient(to right, #fde047, #eab308, #ca8a04)" : "transparent"
3791
5230
  },
3792
5231
  children: [
3793
- /* @__PURE__ */ jsx9(
5232
+ /* @__PURE__ */ jsx12(
3794
5233
  "img",
3795
5234
  {
3796
5235
  src: profilePic,
@@ -3803,7 +5242,7 @@ function WalletSelectorDropdown({
3803
5242
  }
3804
5243
  }
3805
5244
  ),
3806
- isVip && /* @__PURE__ */ jsx9(
5245
+ isVip && /* @__PURE__ */ jsx12(
3807
5246
  Crown,
3808
5247
  {
3809
5248
  size: 12,
@@ -3819,7 +5258,7 @@ function WalletSelectorDropdown({
3819
5258
  )
3820
5259
  ]
3821
5260
  }
3822
- ) : authMethod === "eoa" ? /* @__PURE__ */ jsx9(
5261
+ ) : authMethod === "eoa" ? /* @__PURE__ */ jsx12(
3823
5262
  "div",
3824
5263
  {
3825
5264
  style: {
@@ -3833,9 +5272,9 @@ function WalletSelectorDropdown({
3833
5272
  justifyContent: "center",
3834
5273
  flexShrink: 0
3835
5274
  },
3836
- children: /* @__PURE__ */ jsx9(Wallet, { size: 14, color: colors.accentText })
5275
+ children: /* @__PURE__ */ jsx12(Wallet, { size: 14, color: colors.accentText })
3837
5276
  }
3838
- ) : /* @__PURE__ */ jsxs8(
5277
+ ) : /* @__PURE__ */ jsxs11(
3839
5278
  "div",
3840
5279
  {
3841
5280
  style: {
@@ -3854,7 +5293,7 @@ function WalletSelectorDropdown({
3854
5293
  },
3855
5294
  children: [
3856
5295
  displayName.charAt(0),
3857
- isVip && /* @__PURE__ */ jsx9(
5296
+ isVip && /* @__PURE__ */ jsx12(
3858
5297
  Crown,
3859
5298
  {
3860
5299
  size: 12,
@@ -3871,8 +5310,8 @@ function WalletSelectorDropdown({
3871
5310
  ]
3872
5311
  }
3873
5312
  ),
3874
- /* @__PURE__ */ jsx9("div", { style: { overflow: "hidden", flex: 1 }, children: /* @__PURE__ */ jsxs8("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
3875
- /* @__PURE__ */ jsx9(
5313
+ /* @__PURE__ */ jsx12("div", { style: { overflow: "hidden", flex: 1 }, children: /* @__PURE__ */ jsxs11("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
5314
+ /* @__PURE__ */ jsx12(
3876
5315
  "p",
3877
5316
  {
3878
5317
  style: {
@@ -3887,7 +5326,7 @@ function WalletSelectorDropdown({
3887
5326
  children: displayName
3888
5327
  }
3889
5328
  ),
3890
- hfunScore > 0 && /* @__PURE__ */ jsxs8(
5329
+ hfunScore > 0 && /* @__PURE__ */ jsxs11(
3891
5330
  "span",
3892
5331
  {
3893
5332
  style: {
@@ -3902,7 +5341,7 @@ function WalletSelectorDropdown({
3902
5341
  borderRadius: 4
3903
5342
  },
3904
5343
  children: [
3905
- /* @__PURE__ */ jsx9(Star, { size: 10, color: "#eab308", fill: "#eab308" }),
5344
+ /* @__PURE__ */ jsx12(Star, { size: 10, color: "#eab308", fill: "#eab308" }),
3906
5345
  hfunScore.toFixed(0)
3907
5346
  ]
3908
5347
  }
@@ -3911,9 +5350,9 @@ function WalletSelectorDropdown({
3911
5350
  ]
3912
5351
  }
3913
5352
  ),
3914
- /* @__PURE__ */ jsxs8("div", { style: { borderBottom: sectionBorder }, children: [
3915
- /* @__PURE__ */ jsx9("div", { style: sectionHeaderStyle, children: "Wallets" }),
3916
- /* @__PURE__ */ jsx9(
5353
+ /* @__PURE__ */ jsxs11("div", { style: { borderBottom: sectionBorder }, children: [
5354
+ /* @__PURE__ */ jsx12("div", { style: sectionHeaderStyle, children: "Wallets" }),
5355
+ /* @__PURE__ */ jsx12(
3917
5356
  "div",
3918
5357
  {
3919
5358
  style: {
@@ -3928,8 +5367,8 @@ function WalletSelectorDropdown({
3928
5367
  const isSelectedGroup = entry.items.some(
3929
5368
  (item) => item.wallet.id === selectedWalletId
3930
5369
  );
3931
- return /* @__PURE__ */ jsxs8(Fragment5, { children: [
3932
- /* @__PURE__ */ jsxs8(
5370
+ return /* @__PURE__ */ jsxs11(Fragment8, { children: [
5371
+ /* @__PURE__ */ jsxs11(
3933
5372
  "div",
3934
5373
  {
3935
5374
  style: {
@@ -3944,8 +5383,8 @@ function WalletSelectorDropdown({
3944
5383
  color: isSelectedGroup ? "#e5e7eb" : "#6b7280"
3945
5384
  },
3946
5385
  children: [
3947
- /* @__PURE__ */ jsx9(Folder, { size: 12, style: { flexShrink: 0 } }),
3948
- /* @__PURE__ */ jsx9(
5386
+ /* @__PURE__ */ jsx12(Folder, { size: 12, style: { flexShrink: 0 } }),
5387
+ /* @__PURE__ */ jsx12(
3949
5388
  "span",
3950
5389
  {
3951
5390
  style: {
@@ -3958,7 +5397,7 @@ function WalletSelectorDropdown({
3958
5397
  children: entry.path
3959
5398
  }
3960
5399
  ),
3961
- /* @__PURE__ */ jsx9(
5400
+ /* @__PURE__ */ jsx12(
3962
5401
  "span",
3963
5402
  {
3964
5403
  style: {
@@ -3977,7 +5416,7 @@ function WalletSelectorDropdown({
3977
5416
  })
3978
5417
  }
3979
5418
  ),
3980
- authMethod !== "eoa" && onAddWallet && /* @__PURE__ */ jsxs8(
5419
+ authMethod !== "eoa" && onAddWallet && /* @__PURE__ */ jsxs11(
3981
5420
  "button",
3982
5421
  {
3983
5422
  onClick: () => {
@@ -4001,26 +5440,36 @@ function WalletSelectorDropdown({
4001
5440
  onMouseEnter: (e) => e.currentTarget.style.background = "rgba(255,255,255,0.06)",
4002
5441
  onMouseLeave: (e) => e.currentTarget.style.background = "transparent",
4003
5442
  children: [
4004
- /* @__PURE__ */ jsx9(Plus, { size: 14 }),
5443
+ /* @__PURE__ */ jsx12(Plus, { size: 14 }),
4005
5444
  "Add Wallet"
4006
5445
  ]
4007
5446
  }
4008
5447
  )
4009
5448
  ] }),
4010
- /* @__PURE__ */ jsxs8("div", { children: [
4011
- /* @__PURE__ */ jsx9(
5449
+ /* @__PURE__ */ jsxs11("div", { children: [
5450
+ /* @__PURE__ */ jsx12(
4012
5451
  FooterBtn,
4013
5452
  {
4014
5453
  onClick: openProfile,
4015
- icon: /* @__PURE__ */ jsx9(User, { size: 14 }),
5454
+ icon: /* @__PURE__ */ jsx12(User, { size: 14 }),
4016
5455
  label: "Profile & Settings"
4017
5456
  }
4018
5457
  ),
4019
- /* @__PURE__ */ jsx9(
5458
+ extraFooterItems?.map((item) => /* @__PURE__ */ jsx12(
5459
+ FooterBtn,
5460
+ {
5461
+ onClick: item.onClick,
5462
+ icon: item.icon,
5463
+ label: item.label,
5464
+ hoverColor: item.hoverColor
5465
+ },
5466
+ item.key
5467
+ )),
5468
+ /* @__PURE__ */ jsx12(
4020
5469
  FooterBtn,
4021
5470
  {
4022
5471
  onClick: handleLogout,
4023
- icon: /* @__PURE__ */ jsx9(LogOut, { size: 14 }),
5472
+ icon: /* @__PURE__ */ jsx12(LogOut, { size: 14 }),
4024
5473
  label: "Logout",
4025
5474
  hoverColor: "#ef4444"
4026
5475
  }
@@ -4029,7 +5478,7 @@ function WalletSelectorDropdown({
4029
5478
  ]
4030
5479
  }
4031
5480
  ) }),
4032
- /* @__PURE__ */ jsx9(
5481
+ /* @__PURE__ */ jsx12(
4033
5482
  UserProfileModal,
4034
5483
  {
4035
5484
  isOpen: profileOpen,
@@ -4043,6 +5492,7 @@ function WalletSelectorDropdown({
4043
5492
  principalColors,
4044
5493
  onWalletDeleted,
4045
5494
  onWalletRenamed,
5495
+ onRenewAgentWallet,
4046
5496
  onShowPortfolio: onShowPortfolio ? (wallet) => {
4047
5497
  onShowPortfolio(wallet);
4048
5498
  setProfileOpen(false);
@@ -4058,7 +5508,7 @@ function FooterBtn({
4058
5508
  label,
4059
5509
  hoverColor = "#fff"
4060
5510
  }) {
4061
- return /* @__PURE__ */ jsxs8(
5511
+ return /* @__PURE__ */ jsxs11(
4062
5512
  "button",
4063
5513
  {
4064
5514
  onClick,
@@ -4082,13 +5532,19 @@ function WalletRow2({
4082
5532
  depth,
4083
5533
  isSelected,
4084
5534
  label,
5535
+ walletType,
4085
5536
  compactAddress,
4086
5537
  onSelect,
4087
5538
  onShowPortfolio,
4088
5539
  onCopy,
5540
+ agentExpiryTitle,
5541
+ onRenewAgentWallet,
4089
5542
  colors
4090
5543
  }) {
4091
- return /* @__PURE__ */ jsxs8(
5544
+ const isAgentExpired = !!agentExpiryTitle;
5545
+ const walletTextColor = isAgentExpired ? EXPIRED_AGENT_COLOR : "#d1d5db";
5546
+ const mutedTextColor = isAgentExpired ? "rgba(245,158,11,0.78)" : "#6b7280";
5547
+ return /* @__PURE__ */ jsxs11(
4092
5548
  "div",
4093
5549
  {
4094
5550
  style: {
@@ -4098,7 +5554,7 @@ function WalletRow2({
4098
5554
  paddingTop: 6,
4099
5555
  paddingBottom: 6,
4100
5556
  fontSize: 14,
4101
- color: "#d1d5db",
5557
+ color: walletTextColor,
4102
5558
  display: "flex",
4103
5559
  alignItems: "center",
4104
5560
  background: isSelected ? "rgba(255,255,255,0.06)" : "transparent",
@@ -4115,7 +5571,7 @@ function WalletRow2({
4115
5571
  if (actions) actions.style.opacity = "0";
4116
5572
  },
4117
5573
  children: [
4118
- /* @__PURE__ */ jsx9(
5574
+ /* @__PURE__ */ jsxs11(
4119
5575
  "button",
4120
5576
  {
4121
5577
  onClick: onSelect,
@@ -4132,50 +5588,74 @@ function WalletRow2({
4132
5588
  cursor: "pointer",
4133
5589
  padding: 0
4134
5590
  },
4135
- children: label ? /* @__PURE__ */ jsxs8(Fragment6, { children: [
4136
- /* @__PURE__ */ jsx9(
5591
+ children: [
5592
+ /* @__PURE__ */ jsx12(
4137
5593
  "span",
4138
5594
  {
5595
+ title: walletType.label,
5596
+ "aria-label": walletType.label,
4139
5597
  style: {
4140
- overflow: "hidden",
4141
- textOverflow: "ellipsis",
4142
- whiteSpace: "nowrap",
4143
- color: isSelected ? "#fff" : void 0,
4144
- fontWeight: isSelected ? 500 : void 0
5598
+ display: "inline-flex",
5599
+ alignItems: "center",
5600
+ justifyContent: "center",
5601
+ flexShrink: 0,
5602
+ color: isAgentExpired ? walletTextColor : walletType.color
4145
5603
  },
4146
- children: label
5604
+ children: walletType.icon
4147
5605
  }
4148
5606
  ),
4149
- /* @__PURE__ */ jsxs8(
5607
+ label ? /* @__PURE__ */ jsxs11(Fragment9, { children: [
5608
+ /* @__PURE__ */ jsx12(
5609
+ "span",
5610
+ {
5611
+ style: {
5612
+ overflow: "hidden",
5613
+ textOverflow: "ellipsis",
5614
+ whiteSpace: "nowrap",
5615
+ color: isAgentExpired ? walletTextColor : isSelected ? "#fff" : void 0,
5616
+ fontWeight: isSelected ? 500 : void 0
5617
+ },
5618
+ children: label
5619
+ }
5620
+ ),
5621
+ /* @__PURE__ */ jsxs11(
5622
+ "span",
5623
+ {
5624
+ style: {
5625
+ fontSize: 12,
5626
+ fontWeight: 400,
5627
+ flexShrink: 0,
5628
+ color: mutedTextColor
5629
+ },
5630
+ children: [
5631
+ "(",
5632
+ compactAddress,
5633
+ ")"
5634
+ ]
5635
+ }
5636
+ )
5637
+ ] }) : /* @__PURE__ */ jsx12(
4150
5638
  "span",
4151
5639
  {
4152
5640
  style: {
4153
5641
  fontSize: 12,
4154
- fontWeight: 400,
4155
- flexShrink: 0,
4156
- color: "#6b7280"
5642
+ color: isAgentExpired ? walletTextColor : isSelected ? "#fff" : "#9ca3af",
5643
+ fontWeight: isSelected ? 500 : void 0
4157
5644
  },
4158
- children: [
4159
- "(",
4160
- compactAddress,
4161
- ")"
4162
- ]
5645
+ children: compactAddress
4163
5646
  }
4164
5647
  )
4165
- ] }) : /* @__PURE__ */ jsx9(
4166
- "span",
4167
- {
4168
- style: {
4169
- fontSize: 12,
4170
- color: isSelected ? "#fff" : "#9ca3af",
4171
- fontWeight: isSelected ? 500 : void 0
4172
- },
4173
- children: compactAddress
4174
- }
4175
- )
5648
+ ]
5649
+ }
5650
+ ),
5651
+ agentExpiryTitle && /* @__PURE__ */ jsx12(
5652
+ AgentExpiryWarningIcon,
5653
+ {
5654
+ message: agentExpiryTitle,
5655
+ onClick: onRenewAgentWallet
4176
5656
  }
4177
5657
  ),
4178
- /* @__PURE__ */ jsxs8(
5658
+ /* @__PURE__ */ jsxs11(
4179
5659
  "div",
4180
5660
  {
4181
5661
  "data-row-actions": true,
@@ -4186,7 +5666,19 @@ function WalletRow2({
4186
5666
  transition: "opacity 120ms"
4187
5667
  },
4188
5668
  children: [
4189
- onShowPortfolio && /* @__PURE__ */ jsx9(
5669
+ onRenewAgentWallet && /* @__PURE__ */ jsx12(
5670
+ RowIconBtn,
5671
+ {
5672
+ title: "Renew agent wallet",
5673
+ hoverColor: isAgentExpired ? EXPIRED_AGENT_COLOR : colors.accent,
5674
+ onClick: (e) => {
5675
+ e.stopPropagation();
5676
+ onRenewAgentWallet();
5677
+ },
5678
+ children: /* @__PURE__ */ jsx12(RefreshCw, { size: 12 })
5679
+ }
5680
+ ),
5681
+ onShowPortfolio && /* @__PURE__ */ jsx12(
4190
5682
  RowIconBtn,
4191
5683
  {
4192
5684
  title: "View portfolio",
@@ -4195,10 +5687,10 @@ function WalletRow2({
4195
5687
  e.stopPropagation();
4196
5688
  onShowPortfolio();
4197
5689
  },
4198
- children: /* @__PURE__ */ jsx9(LayoutDashboard, { size: 12 })
5690
+ children: /* @__PURE__ */ jsx12(LayoutDashboard, { size: 12 })
4199
5691
  }
4200
5692
  ),
4201
- /* @__PURE__ */ jsx9(
5693
+ /* @__PURE__ */ jsx12(
4202
5694
  RowIconBtn,
4203
5695
  {
4204
5696
  title: "Copy address",
@@ -4207,7 +5699,7 @@ function WalletRow2({
4207
5699
  e.stopPropagation();
4208
5700
  onCopy();
4209
5701
  },
4210
- children: /* @__PURE__ */ jsx9(Copy, { size: 12 })
5702
+ children: /* @__PURE__ */ jsx12(Copy, { size: 12 })
4211
5703
  }
4212
5704
  )
4213
5705
  ]
@@ -4223,7 +5715,7 @@ function RowIconBtn({
4223
5715
  onClick,
4224
5716
  hoverColor = profileColors.text
4225
5717
  }) {
4226
- return /* @__PURE__ */ jsx9(
5718
+ return /* @__PURE__ */ jsx12(
4227
5719
  "button",
4228
5720
  {
4229
5721
  onClick,
@@ -4258,16 +5750,21 @@ function createEoaSigner(signTypedDataAsync, chainId, options = {}) {
4258
5750
  };
4259
5751
  }
4260
5752
  export {
5753
+ AGENT_APPROVAL_DURATION_OPTIONS,
5754
+ AddWalletModal,
5755
+ DEFAULT_AGENT_APPROVAL_DURATION_MS,
4261
5756
  DeleteWalletModal,
4262
5757
  GrpcExchangeTransport,
4263
5758
  HypurrConnectProvider,
4264
5759
  LoginModal,
4265
5760
  PrivateKeySigner,
4266
5761
  RenameWalletModal,
5762
+ RenewAgentModal,
4267
5763
  UserProfileModal,
4268
5764
  WalletSelectorDropdown,
4269
5765
  createEoaSigner,
4270
5766
  createStaticClient,
5767
+ createTelegramAgentApprovalName,
4271
5768
  createTelegramClient,
4272
5769
  useHypurrConnect
4273
5770
  };