@hfunlabs/hypurr-connect 0.1.23 → 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/README.md +2 -3
- package/dist/index.d.ts +0 -2
- package/dist/index.js +273 -24
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/HypurrConnectProvider.tsx +61 -20
- package/src/UserProfileModal.tsx +205 -4
- package/src/agent.ts +35 -4
- package/src/types.ts +0 -2
package/README.md
CHANGED
|
@@ -49,7 +49,6 @@ const config = {
|
|
|
49
49
|
grpcUrl: "https://grpc.hypurr.fun",
|
|
50
50
|
telegram: {
|
|
51
51
|
authHubUrl: "https://auth.hypurr.fun/login",
|
|
52
|
-
// tokenUrl defaults to https://auth.hypurr.fun/token
|
|
53
52
|
scope: [
|
|
54
53
|
"telegram:user:read",
|
|
55
54
|
"telegram:wallet:read",
|
|
@@ -127,7 +126,6 @@ interface HypurrConnectConfig {
|
|
|
127
126
|
isTestnet?: boolean; // Use testnet endpoints (default: false)
|
|
128
127
|
telegram: {
|
|
129
128
|
authHubUrl?: string; // Auth hub URL (default: https://auth.hypurr.fun/login)
|
|
130
|
-
tokenUrl?: string; // Token exchange URL (default: auth hub /token)
|
|
131
129
|
returnTo?: string | (() => string); // Callback URL (default: current page)
|
|
132
130
|
scope?: string | string[]; // Requested JWT scopes
|
|
133
131
|
};
|
|
@@ -157,7 +155,8 @@ for generated protobuf service clients.
|
|
|
157
155
|
4. The popup callback page posts `{ token, state }` or `{ code, state }` to the
|
|
158
156
|
opener with `postMessage` and closes.
|
|
159
157
|
5. The opener validates `state`. Legacy tokens are stored directly; auth codes
|
|
160
|
-
are exchanged at the
|
|
158
|
+
are exchanged at the OAuth metadata `token_endpoint` with the stored PKCE
|
|
159
|
+
verifier.
|
|
161
160
|
6. The SDK calls the Hypurr gRPC backend with `Authorization: Bearer <jwt>`
|
|
162
161
|
metadata.
|
|
163
162
|
7. An `ExchangeClient` is created with `GrpcExchangeTransport`; exchange
|
package/dist/index.d.ts
CHANGED
|
@@ -27,8 +27,6 @@ interface HypurrConnectConfig {
|
|
|
27
27
|
telegram?: {
|
|
28
28
|
/** Auth hub login URL. Defaults to https://auth.hypurr.fun/login. */
|
|
29
29
|
authHubUrl?: string;
|
|
30
|
-
/** Auth hub token exchange URL. Defaults to the auth hub login URL with `/login` replaced by `/token`. */
|
|
31
|
-
tokenUrl?: string;
|
|
32
30
|
/** Optional callback URL. Defaults to the current page without auth query params. */
|
|
33
31
|
returnTo?: string | (() => string);
|
|
34
32
|
/** Requested hub scopes. Defaults to the scopes required by this SDK. */
|
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
|
|
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();
|
|
@@ -542,17 +561,51 @@ function takeTelegramAuthSession(state) {
|
|
|
542
561
|
sessionStorage.removeItem(returnToKey);
|
|
543
562
|
return { codeVerifier, returnTo };
|
|
544
563
|
}
|
|
545
|
-
function
|
|
546
|
-
const configuredTokenUrl = tokenUrl?.trim();
|
|
547
|
-
if (configuredTokenUrl) return configuredTokenUrl;
|
|
564
|
+
function fallbackAuthTokenUrl(authHubUrl) {
|
|
548
565
|
const url = new URL(authHubUrl || DEFAULT_AUTH_HUB_URL);
|
|
549
|
-
|
|
550
|
-
const basePath = pathWithoutTrailingSlash.replace(/\/[^/]*$/, "");
|
|
551
|
-
url.pathname = `${basePath}/token`;
|
|
566
|
+
url.pathname = "/oauth/token";
|
|
552
567
|
url.search = "";
|
|
553
568
|
url.hash = "";
|
|
554
569
|
return url.toString();
|
|
555
570
|
}
|
|
571
|
+
function authMetadataUrls(authHubUrl) {
|
|
572
|
+
const authUrl = new URL(authHubUrl || DEFAULT_AUTH_HUB_URL);
|
|
573
|
+
const urls = [
|
|
574
|
+
new URL("/.well-known/oauth-authorization-server", authUrl).toString(),
|
|
575
|
+
new URL("/.well-known/openid-configuration", authUrl).toString()
|
|
576
|
+
];
|
|
577
|
+
const authPath = authUrl.pathname.replace(/\/+$/, "");
|
|
578
|
+
const basePath = authPath.replace(/\/[^/]*$/, "");
|
|
579
|
+
if (basePath) {
|
|
580
|
+
urls.push(
|
|
581
|
+
new URL(
|
|
582
|
+
`/.well-known/oauth-authorization-server${basePath}`,
|
|
583
|
+
authUrl
|
|
584
|
+
).toString()
|
|
585
|
+
);
|
|
586
|
+
}
|
|
587
|
+
return Array.from(new Set(urls));
|
|
588
|
+
}
|
|
589
|
+
async function tokenUrlFromMetadata(authHubUrl) {
|
|
590
|
+
for (const metadataUrl of authMetadataUrls(authHubUrl)) {
|
|
591
|
+
try {
|
|
592
|
+
const response = await fetch(metadataUrl, {
|
|
593
|
+
headers: { accept: "application/json" }
|
|
594
|
+
});
|
|
595
|
+
if (!response.ok) continue;
|
|
596
|
+
const metadata = await response.json();
|
|
597
|
+
const tokenEndpoint = metadata.token_endpoint;
|
|
598
|
+
if (typeof tokenEndpoint === "string" && tokenEndpoint.trim()) {
|
|
599
|
+
return tokenEndpoint.trim();
|
|
600
|
+
}
|
|
601
|
+
} catch {
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
return void 0;
|
|
605
|
+
}
|
|
606
|
+
async function resolveAuthTokenUrl(authHubUrl) {
|
|
607
|
+
return await tokenUrlFromMetadata(authHubUrl) || fallbackAuthTokenUrl(authHubUrl);
|
|
608
|
+
}
|
|
556
609
|
function getTokenFromExchangeResponse(data) {
|
|
557
610
|
if (typeof data === "string") {
|
|
558
611
|
const token = data.trim();
|
|
@@ -570,8 +623,7 @@ async function exchangeTelegramAuthCode({
|
|
|
570
623
|
clientId,
|
|
571
624
|
code,
|
|
572
625
|
codeVerifier,
|
|
573
|
-
returnTo
|
|
574
|
-
tokenUrl
|
|
626
|
+
returnTo
|
|
575
627
|
}) {
|
|
576
628
|
const body = new URLSearchParams({
|
|
577
629
|
client_id: clientId,
|
|
@@ -580,7 +632,7 @@ async function exchangeTelegramAuthCode({
|
|
|
580
632
|
grant_type: "authorization_code",
|
|
581
633
|
return_to: returnTo
|
|
582
634
|
});
|
|
583
|
-
const response = await fetch(resolveAuthTokenUrl(authHubUrl
|
|
635
|
+
const response = await fetch(await resolveAuthTokenUrl(authHubUrl), {
|
|
584
636
|
method: "POST",
|
|
585
637
|
headers: {
|
|
586
638
|
accept: "application/json",
|
|
@@ -697,8 +749,7 @@ function HypurrConnectProvider({
|
|
|
697
749
|
clientId: normalizeClientId(config.clientId),
|
|
698
750
|
code: callback.code,
|
|
699
751
|
codeVerifier: authSession.codeVerifier,
|
|
700
|
-
returnTo: authSession.returnTo || currentReturnTo()
|
|
701
|
-
tokenUrl: config.telegram?.tokenUrl
|
|
752
|
+
returnTo: authSession.returnTo || currentReturnTo()
|
|
702
753
|
}).then(acceptTelegramToken).catch(
|
|
703
754
|
(err) => setTgError(err instanceof Error ? err.message : String(err))
|
|
704
755
|
).finally(() => setTgLoading(false));
|
|
@@ -713,8 +764,7 @@ function HypurrConnectProvider({
|
|
|
713
764
|
[
|
|
714
765
|
acceptTelegramToken,
|
|
715
766
|
config.clientId,
|
|
716
|
-
config.telegram?.authHubUrl
|
|
717
|
-
config.telegram?.tokenUrl
|
|
767
|
+
config.telegram?.authHubUrl
|
|
718
768
|
]
|
|
719
769
|
);
|
|
720
770
|
useEffect(() => {
|
|
@@ -1715,6 +1765,7 @@ function HypurrConnectProvider({
|
|
|
1715
1765
|
agent,
|
|
1716
1766
|
agentReady,
|
|
1717
1767
|
clearAgent: handleClearAgent,
|
|
1768
|
+
eoaAddress,
|
|
1718
1769
|
authDataMap,
|
|
1719
1770
|
authToken: tgAuthToken,
|
|
1720
1771
|
telegramRpcOptions,
|
|
@@ -1758,6 +1809,7 @@ function HypurrConnectProvider({
|
|
|
1758
1809
|
agent,
|
|
1759
1810
|
agentReady,
|
|
1760
1811
|
handleClearAgent,
|
|
1812
|
+
eoaAddress,
|
|
1761
1813
|
authDataMap,
|
|
1762
1814
|
tgAuthToken,
|
|
1763
1815
|
telegramRpcOptions,
|
|
@@ -3265,7 +3317,7 @@ import { AnimatePresence as AnimatePresence7, motion as motion7 } from "framer-m
|
|
|
3265
3317
|
import {
|
|
3266
3318
|
Fragment as Fragment8,
|
|
3267
3319
|
useCallback as useCallback9,
|
|
3268
|
-
useMemo as
|
|
3320
|
+
useMemo as useMemo4,
|
|
3269
3321
|
useState as useState8
|
|
3270
3322
|
} from "react";
|
|
3271
3323
|
|
|
@@ -3371,6 +3423,8 @@ function AgentExpiryWarningIcon({
|
|
|
3371
3423
|
import { AnimatePresence as AnimatePresence6, motion as motion6 } from "framer-motion";
|
|
3372
3424
|
import {
|
|
3373
3425
|
useCallback as useCallback8,
|
|
3426
|
+
useEffect as useEffect3,
|
|
3427
|
+
useMemo as useMemo3,
|
|
3374
3428
|
useState as useState7
|
|
3375
3429
|
} from "react";
|
|
3376
3430
|
|
|
@@ -4329,11 +4383,40 @@ function UserProfileModal({
|
|
|
4329
4383
|
wallets: userWallets,
|
|
4330
4384
|
deleteWallet,
|
|
4331
4385
|
renameWallet,
|
|
4332
|
-
authMethod
|
|
4386
|
+
authMethod,
|
|
4387
|
+
agent,
|
|
4388
|
+
eoaAddress,
|
|
4389
|
+
clearAgent: clearContextAgent
|
|
4333
4390
|
} = useHypurrConnectInternal();
|
|
4334
4391
|
const [settingsTab, setSettingsTab] = useState7("ui");
|
|
4335
4392
|
const [walletToDelete, setWalletToDelete] = useState7(null);
|
|
4336
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
|
+
);
|
|
4337
4420
|
const profilePic = user?.photoUrl || "";
|
|
4338
4421
|
const displayName = user?.displayName || "";
|
|
4339
4422
|
const hfunScore = user?.hfunScore ?? null;
|
|
@@ -4356,10 +4439,11 @@ function UserProfileModal({
|
|
|
4356
4439
|
[renameWallet, onWalletRenamed]
|
|
4357
4440
|
);
|
|
4358
4441
|
const handleCopyAddress = useCallback8(() => {
|
|
4359
|
-
|
|
4360
|
-
|
|
4442
|
+
const address = user?.address || eoaAddress || displayName;
|
|
4443
|
+
if (!address) return;
|
|
4444
|
+
navigator.clipboard.writeText(address);
|
|
4361
4445
|
onNotify?.({ type: "success", message: "Address copied" });
|
|
4362
|
-
}, [displayName, onNotify]);
|
|
4446
|
+
}, [user?.address, eoaAddress, displayName, onNotify]);
|
|
4363
4447
|
return /* @__PURE__ */ jsxs10("div", { className: "hypurr-connect", style: { display: "contents" }, children: [
|
|
4364
4448
|
/* @__PURE__ */ jsx11(AnimatePresence6, { children: isOpen && /* @__PURE__ */ jsxs10(Fragment7, { children: [
|
|
4365
4449
|
/* @__PURE__ */ jsx11(SpinKeyframes, {}),
|
|
@@ -4873,7 +4957,51 @@ function UserProfileModal({
|
|
|
4873
4957
|
" linked"
|
|
4874
4958
|
]
|
|
4875
4959
|
}
|
|
4876
|
-
)
|
|
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
|
+
] })
|
|
4877
5005
|
]
|
|
4878
5006
|
}
|
|
4879
5007
|
)
|
|
@@ -5117,6 +5245,127 @@ function WalletRow({
|
|
|
5117
5245
|
}
|
|
5118
5246
|
);
|
|
5119
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
|
+
}
|
|
5120
5369
|
function IconBtn({
|
|
5121
5370
|
children,
|
|
5122
5371
|
color,
|
|
@@ -5291,7 +5540,7 @@ function WalletSelectorDropdown({
|
|
|
5291
5540
|
setProfileOpen(true);
|
|
5292
5541
|
onClose();
|
|
5293
5542
|
}, [onClose]);
|
|
5294
|
-
const walletListEntries =
|
|
5543
|
+
const walletListEntries = useMemo4(
|
|
5295
5544
|
() => buildWalletListEntries(Array.isArray(wallets) ? wallets : void 0),
|
|
5296
5545
|
[wallets]
|
|
5297
5546
|
);
|