@hfunlabs/hypurr-connect 0.1.24 → 0.1.25

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
@@ -80,6 +80,28 @@ function saveAgent(masterAddress, agent) {
80
80
  function clearAgent(masterAddress) {
81
81
  localStorage.removeItem(storageKey(masterAddress));
82
82
  }
83
+ function loadAllAgents() {
84
+ const agents = [];
85
+ try {
86
+ for (let i = 0; i < localStorage.length; i++) {
87
+ const key = localStorage.key(i);
88
+ if (!key || !key.startsWith(`${AGENT_STORAGE_PREFIX}:`)) continue;
89
+ const raw = localStorage.getItem(key);
90
+ if (!raw) continue;
91
+ try {
92
+ const agent = JSON.parse(raw);
93
+ agents.push({
94
+ ...agent,
95
+ masterAddress: key.slice(key.indexOf(":") + 1)
96
+ });
97
+ } catch {
98
+ }
99
+ }
100
+ } catch {
101
+ return [];
102
+ }
103
+ return agents.sort((a, b) => b.approvedAt - a.approvedAt);
104
+ }
83
105
  async function generateAgentKey() {
84
106
  const bytes = crypto.getRandomValues(new Uint8Array(32));
85
107
  const hex = Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
@@ -100,10 +122,7 @@ async function fetchExtraAgents(userAddress, isTestnet) {
100
122
  if (!res.ok) return [];
101
123
  const agents = await res.json();
102
124
  if (!Array.isArray(agents)) return [];
103
- return agents.map((agent) => ({
104
- ...agent,
105
- validUntil: agent.validUntil * 1e3
106
- }));
125
+ return agents;
107
126
  }
108
127
  async function fetchActiveAgent(userAddress, isTestnet) {
109
128
  const nowMs = Date.now();
@@ -1746,6 +1765,7 @@ function HypurrConnectProvider({
1746
1765
  agent,
1747
1766
  agentReady,
1748
1767
  clearAgent: handleClearAgent,
1768
+ eoaAddress,
1749
1769
  authDataMap,
1750
1770
  authToken: tgAuthToken,
1751
1771
  telegramRpcOptions,
@@ -1789,6 +1809,7 @@ function HypurrConnectProvider({
1789
1809
  agent,
1790
1810
  agentReady,
1791
1811
  handleClearAgent,
1812
+ eoaAddress,
1792
1813
  authDataMap,
1793
1814
  tgAuthToken,
1794
1815
  telegramRpcOptions,
@@ -3296,7 +3317,7 @@ import { AnimatePresence as AnimatePresence7, motion as motion7 } from "framer-m
3296
3317
  import {
3297
3318
  Fragment as Fragment8,
3298
3319
  useCallback as useCallback9,
3299
- useMemo as useMemo3,
3320
+ useMemo as useMemo4,
3300
3321
  useState as useState8
3301
3322
  } from "react";
3302
3323
 
@@ -3402,6 +3423,8 @@ function AgentExpiryWarningIcon({
3402
3423
  import { AnimatePresence as AnimatePresence6, motion as motion6 } from "framer-motion";
3403
3424
  import {
3404
3425
  useCallback as useCallback8,
3426
+ useEffect as useEffect3,
3427
+ useMemo as useMemo3,
3405
3428
  useState as useState7
3406
3429
  } from "react";
3407
3430
 
@@ -4360,11 +4383,40 @@ function UserProfileModal({
4360
4383
  wallets: userWallets,
4361
4384
  deleteWallet,
4362
4385
  renameWallet,
4363
- authMethod
4386
+ authMethod,
4387
+ agent,
4388
+ eoaAddress,
4389
+ clearAgent: clearContextAgent
4364
4390
  } = useHypurrConnectInternal();
4365
4391
  const [settingsTab, setSettingsTab] = useState7("ui");
4366
4392
  const [walletToDelete, setWalletToDelete] = useState7(null);
4367
4393
  const [walletToRename, setWalletToRename] = useState7(null);
4394
+ const [storedAgents, setStoredAgents] = useState7([]);
4395
+ useEffect3(() => {
4396
+ if (isOpen) setStoredAgents(loadAllAgents());
4397
+ }, [isOpen]);
4398
+ const localAgents = useMemo3(() => {
4399
+ const byOwner = /* @__PURE__ */ new Map();
4400
+ for (const a of storedAgents) byOwner.set(a.masterAddress.toLowerCase(), a);
4401
+ if (agent && eoaAddress && !byOwner.has(eoaAddress.toLowerCase())) {
4402
+ byOwner.set(eoaAddress.toLowerCase(), {
4403
+ ...agent,
4404
+ masterAddress: eoaAddress
4405
+ });
4406
+ }
4407
+ return [...byOwner.values()].sort((a, b) => b.approvedAt - a.approvedAt);
4408
+ }, [storedAgents, agent, eoaAddress]);
4409
+ const handleRemoveLocalAgent = useCallback8(
4410
+ (masterAddress) => {
4411
+ if (eoaAddress && masterAddress.toLowerCase() === eoaAddress.toLowerCase()) {
4412
+ clearContextAgent();
4413
+ } else {
4414
+ clearAgent(masterAddress);
4415
+ }
4416
+ setStoredAgents(loadAllAgents());
4417
+ },
4418
+ [eoaAddress, clearContextAgent]
4419
+ );
4368
4420
  const profilePic = user?.photoUrl || "";
4369
4421
  const displayName = user?.displayName || "";
4370
4422
  const hfunScore = user?.hfunScore ?? null;
@@ -4387,10 +4439,11 @@ function UserProfileModal({
4387
4439
  [renameWallet, onWalletRenamed]
4388
4440
  );
4389
4441
  const handleCopyAddress = useCallback8(() => {
4390
- if (!displayName) return;
4391
- navigator.clipboard.writeText(displayName);
4442
+ const address = user?.address || eoaAddress || displayName;
4443
+ if (!address) return;
4444
+ navigator.clipboard.writeText(address);
4392
4445
  onNotify?.({ type: "success", message: "Address copied" });
4393
- }, [displayName, onNotify]);
4446
+ }, [user?.address, eoaAddress, displayName, onNotify]);
4394
4447
  return /* @__PURE__ */ jsxs10("div", { className: "hypurr-connect", style: { display: "contents" }, children: [
4395
4448
  /* @__PURE__ */ jsx11(AnimatePresence6, { children: isOpen && /* @__PURE__ */ jsxs10(Fragment7, { children: [
4396
4449
  /* @__PURE__ */ jsx11(SpinKeyframes, {}),
@@ -4904,7 +4957,51 @@ function UserProfileModal({
4904
4957
  " linked"
4905
4958
  ]
4906
4959
  }
4907
- )
4960
+ ),
4961
+ localAgents.length > 0 && /* @__PURE__ */ jsxs10("div", { style: { marginTop: 8 }, children: [
4962
+ /* @__PURE__ */ jsx11(
4963
+ "p",
4964
+ {
4965
+ style: {
4966
+ margin: "0 0 8px",
4967
+ color: profileColors.muted,
4968
+ ...upperLabelStyle
4969
+ },
4970
+ children: "Agent wallets"
4971
+ }
4972
+ ),
4973
+ /* @__PURE__ */ jsx11(
4974
+ "div",
4975
+ {
4976
+ style: {
4977
+ display: "flex",
4978
+ flexDirection: "column",
4979
+ gap: 6
4980
+ },
4981
+ children: localAgents.map((agent2) => /* @__PURE__ */ jsx11(
4982
+ LocalAgentRow,
4983
+ {
4984
+ agent: agent2,
4985
+ onRemove: () => handleRemoveLocalAgent(agent2.masterAddress)
4986
+ },
4987
+ agent2.masterAddress
4988
+ ))
4989
+ }
4990
+ ),
4991
+ /* @__PURE__ */ jsx11(
4992
+ "p",
4993
+ {
4994
+ style: {
4995
+ margin: "8px 0 0",
4996
+ fontSize: 12.5,
4997
+ lineHeight: "1rem",
4998
+ color: profileColors.subdued,
4999
+ textAlign: "center"
5000
+ },
5001
+ children: "Approved on this device"
5002
+ }
5003
+ )
5004
+ ] })
4908
5005
  ]
4909
5006
  }
4910
5007
  )
@@ -5148,6 +5245,127 @@ function WalletRow({
5148
5245
  }
5149
5246
  );
5150
5247
  }
5248
+ function shortAddress(address) {
5249
+ return `${address.slice(0, 6)}...${address.slice(-4)}`;
5250
+ }
5251
+ function normalizeExpiryMs(validUntil) {
5252
+ return validUntil > 1e14 ? Math.round(validUntil / 1e3) : validUntil;
5253
+ }
5254
+ function LocalAgentRow({
5255
+ agent,
5256
+ onRemove
5257
+ }) {
5258
+ const [hovered, setHovered] = useState7(false);
5259
+ const expiresAtMs = normalizeExpiryMs(agent.validUntil);
5260
+ const isExpired = expiresAtMs <= Date.now();
5261
+ const agentTypeColor = "rgb(var(--blue-500))";
5262
+ return /* @__PURE__ */ jsxs10(
5263
+ "div",
5264
+ {
5265
+ style: {
5266
+ ...walletRowStyle,
5267
+ background: hovered ? profileColors.surfaceBtnHover : profileColors.surfaceBtn,
5268
+ borderColor: hovered ? profileColors.surfaceBdHover : profileColors.surfaceBd
5269
+ },
5270
+ onMouseEnter: () => setHovered(true),
5271
+ onMouseLeave: () => setHovered(false),
5272
+ children: [
5273
+ /* @__PURE__ */ jsx11(
5274
+ "div",
5275
+ {
5276
+ style: {
5277
+ width: 32,
5278
+ height: 32,
5279
+ borderRadius: 6,
5280
+ background: "rgb(var(--blue-500) / 0.16)",
5281
+ border: "1px solid rgb(var(--blue-500) / 0.34)",
5282
+ display: "flex",
5283
+ alignItems: "center",
5284
+ justifyContent: "center",
5285
+ flexShrink: 0,
5286
+ color: agentTypeColor
5287
+ },
5288
+ children: /* @__PURE__ */ jsx11(Bot, { size: 15 })
5289
+ }
5290
+ ),
5291
+ /* @__PURE__ */ jsxs10("div", { style: { flex: 1, minWidth: 0 }, children: [
5292
+ /* @__PURE__ */ jsx11(
5293
+ "p",
5294
+ {
5295
+ style: {
5296
+ margin: 0,
5297
+ fontSize: 12.5,
5298
+ lineHeight: "1rem",
5299
+ fontWeight: 500,
5300
+ color: profileColors.text,
5301
+ fontFamily: fontFamily.mono,
5302
+ overflow: "hidden",
5303
+ textOverflow: "ellipsis",
5304
+ whiteSpace: "nowrap"
5305
+ },
5306
+ children: shortAddress(agent.address)
5307
+ }
5308
+ ),
5309
+ /* @__PURE__ */ jsxs10(
5310
+ "p",
5311
+ {
5312
+ style: {
5313
+ margin: "2px 0 0",
5314
+ fontSize: 12.5,
5315
+ lineHeight: "1rem",
5316
+ color: isExpired ? EXPIRED_AGENT_COLOR : profileColors.muted
5317
+ },
5318
+ children: [
5319
+ isExpired ? "Expired" : "Valid until",
5320
+ " ",
5321
+ formatAgentExpiry(expiresAtMs)
5322
+ ]
5323
+ }
5324
+ ),
5325
+ /* @__PURE__ */ jsxs10(
5326
+ "p",
5327
+ {
5328
+ style: {
5329
+ margin: "2px 0 0",
5330
+ fontSize: 12.5,
5331
+ lineHeight: "1rem",
5332
+ color: profileColors.subdued,
5333
+ fontFamily: fontFamily.mono
5334
+ },
5335
+ children: [
5336
+ "Owner ",
5337
+ shortAddress(agent.masterAddress)
5338
+ ]
5339
+ }
5340
+ )
5341
+ ] }),
5342
+ /* @__PURE__ */ jsx11(
5343
+ "div",
5344
+ {
5345
+ style: {
5346
+ display: "flex",
5347
+ alignItems: "center",
5348
+ flexShrink: 0,
5349
+ opacity: hovered ? 1 : 0,
5350
+ transition: "opacity 120ms"
5351
+ },
5352
+ children: /* @__PURE__ */ jsx11(
5353
+ IconBtn,
5354
+ {
5355
+ color: "#ef4444",
5356
+ hoverBackgroundColor: "rgba(239,68,68,0.1)",
5357
+ title: "Remove local agent",
5358
+ ariaLabel: `Remove local agent for ${shortAddress(agent.masterAddress)}`,
5359
+ onClick: onRemove,
5360
+ children: /* @__PURE__ */ jsx11(Trash2, { size: 13 })
5361
+ }
5362
+ )
5363
+ }
5364
+ )
5365
+ ]
5366
+ }
5367
+ );
5368
+ }
5151
5369
  function IconBtn({
5152
5370
  children,
5153
5371
  color,
@@ -5322,7 +5540,7 @@ function WalletSelectorDropdown({
5322
5540
  setProfileOpen(true);
5323
5541
  onClose();
5324
5542
  }, [onClose]);
5325
- const walletListEntries = useMemo3(
5543
+ const walletListEntries = useMemo4(
5326
5544
  () => buildWalletListEntries(Array.isArray(wallets) ? wallets : void 0),
5327
5545
  [wallets]
5328
5546
  );