@hfunlabs/hypurr-connect 0.1.0 → 0.1.2

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.
@@ -1,19 +1,33 @@
1
- import { ExchangeClient, HttpTransport, InfoClient } from "@hfunlabs/hyperliquid";
1
+ import {
2
+ ExchangeClient,
3
+ HttpTransport,
4
+ type IRequestTransport,
5
+ } from "@hfunlabs/hyperliquid";
6
+ import { approveAgent as sdkApproveAgent } from "@hfunlabs/hyperliquid/api/exchange";
2
7
  import { PrivateKeySigner } from "@hfunlabs/hyperliquid/signing";
3
8
  import type { TelegramUserResponse } from "hypurr-grpc/ts/hypurr/telegram/telegram_service";
4
- import type { TelegramUser as HypurrTelegramUser } from "hypurr-grpc/ts/hypurr/user";
9
+ import type {
10
+ TelegramUser as HypurrTelegramUser,
11
+ TelegramChatWalletPack,
12
+ } from "hypurr-grpc/ts/hypurr/user";
13
+ import type { HyperliquidWallet } from "hypurr-grpc/ts/hypurr/wallet";
5
14
  import {
6
15
  createContext,
7
16
  useCallback,
8
17
  useContext,
9
18
  useEffect,
10
19
  useMemo,
20
+ useRef,
11
21
  useState,
12
22
  type ReactNode,
13
23
  } from "react";
14
24
  import {
25
+ AGENT_NAME,
15
26
  clearAgent as clearStoredAgent,
27
+ fetchActiveAgent,
16
28
  generateAgentKey,
29
+ isAgentValid,
30
+ isDeadAgentError,
17
31
  loadAgent,
18
32
  saveAgent,
19
33
  } from "./agent";
@@ -29,6 +43,11 @@ import type {
29
43
  TelegramLoginData,
30
44
  } from "./types";
31
45
 
46
+ /** @internal context value — extends the public type with fields used only by library internals */
47
+ interface InternalConnectState extends HypurrConnectState {
48
+ loginTelegram: (data: TelegramLoginData) => void;
49
+ }
50
+
32
51
  const TELEGRAM_STORAGE_KEY = "hypurr-connect-tg-user";
33
52
 
34
53
  function toAuthDataMap(data: TelegramLoginData): Record<string, string> {
@@ -44,7 +63,7 @@ function toAuthDataMap(data: TelegramLoginData): Record<string, string> {
44
63
  return map;
45
64
  }
46
65
 
47
- const HypurrConnectContext = createContext<HypurrConnectState | null>(null);
66
+ const HypurrConnectContext = createContext<InternalConnectState | null>(null);
48
67
 
49
68
  export function useHypurrConnect(): HypurrConnectState {
50
69
  const ctx = useContext(HypurrConnectContext);
@@ -55,6 +74,16 @@ export function useHypurrConnect(): HypurrConnectState {
55
74
  return ctx;
56
75
  }
57
76
 
77
+ /** @internal — gives library components access to fields not on the public API */
78
+ export function useHypurrConnectInternal(): InternalConnectState {
79
+ const ctx = useContext(HypurrConnectContext);
80
+ if (!ctx)
81
+ throw new Error(
82
+ "useHypurrConnectInternal must be used within <HypurrConnectProvider>",
83
+ );
84
+ return ctx;
85
+ }
86
+
58
87
  export function HypurrConnectProvider({
59
88
  config,
60
89
  children,
@@ -85,6 +114,8 @@ export function HypurrConnectProvider({
85
114
  [tgLoginData],
86
115
  );
87
116
 
117
+ const [tgUserTick, setTgUserTick] = useState(0);
118
+
88
119
  useEffect(() => {
89
120
  if (!tgLoginData) return;
90
121
  let cancelled = false;
@@ -94,9 +125,7 @@ export function HypurrConnectProvider({
94
125
  (async () => {
95
126
  try {
96
127
  const authData = toAuthDataMap(tgLoginData);
97
- console.log(authData);
98
128
  const { response } = await tgClient.telegramUser({ authData });
99
- console.log(response);
100
129
  if (cancelled) return;
101
130
  setTgUser((response as TelegramUserResponse).user ?? null);
102
131
  } catch (err) {
@@ -111,19 +140,13 @@ export function HypurrConnectProvider({
111
140
  return () => {
112
141
  cancelled = true;
113
142
  };
114
- }, [tgLoginData, tgClient]);
143
+ }, [tgLoginData, tgClient, tgUserTick]);
115
144
 
116
145
  // ── EOA auth state ───────────────────────────────────────────
117
146
  const [eoaAddress, setEoaAddress] = useState<`0x${string}` | null>(null);
118
147
  const [agent, setAgent] = useState<StoredAgent | null>(null);
119
-
120
- useEffect(() => {
121
- if (eoaAddress) {
122
- setAgent(loadAgent(eoaAddress));
123
- } else {
124
- setAgent(null);
125
- }
126
- }, [eoaAddress]);
148
+ const [eoaLoading, setEoaLoading] = useState(false);
149
+ const [eoaError, setEoaError] = useState<string | null>(null);
127
150
 
128
151
  // ── Derived auth ─────────────────────────────────────────────
129
152
  const authMethod: AuthMethod = tgLoginData
@@ -132,19 +155,59 @@ export function HypurrConnectProvider({
132
155
  ? "eoa"
133
156
  : null;
134
157
 
135
- const tgWallet = tgUser?.wallet ?? (tgUser?.wallets ?? [])[0] ?? null;
158
+ // ── Multi-wallet state (Telegram) ─────────────────────────────
159
+ const [wallets, setWallets] = useState<HyperliquidWallet[]>([]);
160
+ const [selectedWalletId, setSelectedWalletId] = useState<number>(0);
161
+ const [packs, setPacks] = useState<TelegramChatWalletPack[]>([]);
162
+
163
+ const refreshWallets = useCallback(() => setTgUserTick((t) => t + 1), []);
164
+
165
+ useEffect(() => {
166
+ if (authMethod !== "telegram" || !tgUser) {
167
+ setWallets([]);
168
+ setSelectedWalletId(0);
169
+ setPacks([]);
170
+ return;
171
+ }
172
+
173
+ const userWallets = tgUser.wallets ?? [];
174
+ setWallets(userWallets);
175
+ setPacks(tgUser.packs ?? []);
176
+
177
+ const defaultId = tgUser.walletId || userWallets[0]?.id || 0;
178
+ setSelectedWalletId((prev) => {
179
+ if (prev && userWallets.some((w) => w.id === prev)) return prev;
180
+ return defaultId;
181
+ });
182
+ }, [authMethod, tgUser]);
183
+
184
+ const selectedWallet = useMemo(
185
+ () => wallets.find((w) => w.id === selectedWalletId) ?? wallets[0] ?? null,
186
+ [wallets, selectedWalletId],
187
+ );
188
+
189
+ const selectWallet = useCallback(
190
+ (walletId: number) => {
191
+ if (wallets.some((w) => w.id === walletId)) {
192
+ setSelectedWalletId(walletId);
193
+ }
194
+ },
195
+ [wallets],
196
+ );
136
197
 
137
198
  const user = useMemo<HypurrUser | null>(() => {
138
- if (tgLoginData && authMethod === "telegram") {
199
+ if (tgLoginData && authMethod === "telegram" && selectedWallet) {
139
200
  return {
140
- address: tgWallet?.ethereumAddress ?? "",
141
- walletId: tgUser?.walletId ?? tgWallet?.id ?? 0,
201
+ address: selectedWallet.ethereumAddress,
202
+ walletId: selectedWallet.id,
142
203
  displayName: tgLoginData.username
143
204
  ? `@${tgLoginData.username}`
144
205
  : tgLoginData.first_name,
145
206
  photoUrl: tgLoginData.photo_url,
146
207
  authMethod: "telegram",
147
208
  telegramId: String(tgLoginData.id),
209
+ hfunScore: tgUser?.reputation?.hfunScore,
210
+ reputationScore: tgUser?.reputation?.reputationScore,
148
211
  };
149
212
  }
150
213
  if (eoaAddress && authMethod === "eoa") {
@@ -156,11 +219,24 @@ export function HypurrConnectProvider({
156
219
  };
157
220
  }
158
221
  return null;
159
- }, [tgLoginData, tgUser, tgWallet, eoaAddress, authMethod]);
222
+ }, [tgLoginData, selectedWallet, eoaAddress, authMethod, tgUser]);
160
223
 
161
224
  // ── Exchange client ──────────────────────────────────────────
162
225
  // Telegram: GrpcExchangeTransport → HyperliquidCoreAction (server signs)
163
226
  // EOA: HttpTransport + agent wallet (SDK signs locally)
227
+
228
+ const onDeadAgentRef = useRef<((address: `0x${string}`) => void) | null>(
229
+ null,
230
+ );
231
+ onDeadAgentRef.current = (addr: `0x${string}`) => {
232
+ clearStoredAgent(addr);
233
+ setAgent(null);
234
+ setEoaError("Agent expired or was deregistered. Please reconnect.");
235
+ };
236
+
237
+ const agentReady =
238
+ authMethod === "telegram" || (authMethod === "eoa" && !!agent);
239
+
164
240
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
165
241
  const exchange = useMemo<ExchangeClient<any> | null>(() => {
166
242
  if (authMethod === "telegram" && user?.address) {
@@ -177,150 +253,153 @@ export function HypurrConnectProvider({
177
253
  });
178
254
  }
179
255
 
180
- if (authMethod === "eoa" && agent) {
256
+ if (authMethod === "eoa" && eoaAddress) {
257
+ if (!agent) {
258
+ const noAgentTransport: IRequestTransport = {
259
+ isTestnet: config.isTestnet ?? false,
260
+ request(): Promise<never> {
261
+ throw new Error(
262
+ "[HypurrConnect] No agent key approved. " +
263
+ "Call approveAgent(signTypedDataAsync) before using the exchange client. " +
264
+ "This is required for EOA wallets to sign transactions on Hyperliquid.",
265
+ );
266
+ },
267
+ };
268
+ return new ExchangeClient({
269
+ transport: noAgentTransport,
270
+ externalSigning: true,
271
+ userAddress: eoaAddress,
272
+ });
273
+ }
274
+
275
+ const inner = new HttpTransport({
276
+ isTestnet: config.isTestnet ?? false,
277
+ });
278
+ const deadAgentAddr = eoaAddress;
279
+ const guardedTransport: IRequestTransport = {
280
+ isTestnet: inner.isTestnet,
281
+ async request<T>(
282
+ endpoint: "info" | "exchange" | "explorer",
283
+ payload: unknown,
284
+ signal?: AbortSignal,
285
+ ): Promise<T> {
286
+ try {
287
+ return await inner.request<T>(endpoint, payload, signal);
288
+ } catch (err) {
289
+ if (endpoint === "exchange" && isDeadAgentError(err)) {
290
+ onDeadAgentRef.current?.(deadAgentAddr);
291
+ }
292
+ throw err;
293
+ }
294
+ },
295
+ };
181
296
  const wallet = new PrivateKeySigner(agent.privateKey);
182
297
  return new ExchangeClient({
183
- transport: new HttpTransport({
184
- isTestnet: config.isTestnet ?? false,
185
- }),
298
+ transport: guardedTransport,
186
299
  wallet,
187
300
  });
188
301
  }
189
302
 
190
303
  return null;
191
- }, [authMethod, user, agent, config.isTestnet, tgClient, authDataMap]);
192
-
193
- // ── USDC balance from Hyperliquid ──────────────────────────────
194
- const infoClient = useMemo(
195
- () =>
196
- new InfoClient({
197
- transport: new HttpTransport({
198
- isTestnet: config.isTestnet ?? false,
199
- }),
200
- }),
201
- [config.isTestnet],
202
- );
203
-
204
- const [usdcBalance, setUsdcBalance] = useState<string | null>(null);
205
- const [usdcBalanceLoading, setUsdcBalanceLoading] = useState(false);
206
- const [balanceTick, setBalanceTick] = useState(0);
207
-
208
- const refreshBalance = useCallback(() => setBalanceTick((t) => t + 1), []);
304
+ }, [
305
+ authMethod,
306
+ user,
307
+ agent,
308
+ eoaAddress,
309
+ config.isTestnet,
310
+ tgClient,
311
+ authDataMap,
312
+ ]);
209
313
 
210
- useEffect(() => {
211
- const addr = user?.address;
212
- if (!addr) {
213
- setUsdcBalance(null);
214
- return;
314
+ const handleClearAgent = useCallback(() => {
315
+ if (eoaAddress) {
316
+ clearStoredAgent(eoaAddress);
317
+ setAgent(null);
215
318
  }
319
+ }, [eoaAddress]);
216
320
 
217
- let cancelled = false;
218
- setUsdcBalanceLoading(true);
321
+ // ── Wallet management (Telegram only) ───────────────────────
322
+ const createWallet = useCallback(
323
+ async (name: string): Promise<HyperliquidWallet> => {
324
+ const { response } = await tgClient.hyperliquidWalletCreate({
325
+ authData: authDataMap,
326
+ name,
327
+ });
328
+ refreshWallets();
329
+ if (!response.wallet)
330
+ throw new Error("Wallet creation returned no wallet");
331
+ return response.wallet;
332
+ },
333
+ [tgClient, authDataMap, refreshWallets],
334
+ );
219
335
 
220
- (async () => {
221
- try {
222
- const state = await infoClient.clearinghouseState({
223
- user: addr as `0x${string}`,
224
- });
225
- if (!cancelled) {
226
- setUsdcBalance(state.withdrawable);
227
- }
228
- } catch (err) {
229
- console.error("[HypurrConnect] Failed to fetch USDC balance:", err);
230
- if (!cancelled) setUsdcBalance(null);
231
- } finally {
232
- if (!cancelled) setUsdcBalanceLoading(false);
336
+ const deleteWallet = useCallback(
337
+ async (walletId: number): Promise<void> => {
338
+ await tgClient.hyperliquidWalletDelete({
339
+ authData: authDataMap,
340
+ walletId,
341
+ });
342
+ if (walletId === selectedWalletId) {
343
+ const remaining = wallets.filter((w) => w.id !== walletId);
344
+ setSelectedWalletId(remaining[0]?.id ?? 0);
233
345
  }
234
- })();
235
-
236
- return () => {
237
- cancelled = true;
238
- };
239
- }, [user?.address, infoClient, balanceTick]);
240
-
241
- // ── Agent approval (EOA flow) ────────────────────────────────
242
- const approveAgent = useCallback(
243
- async (signTypedDataAsync: SignTypedDataFn) => {
244
- if (!eoaAddress) throw new Error("No EOA address connected");
245
-
246
- const { privateKey, address: agentAddress } = await generateAgentKey();
247
-
248
- const isTestnet = config.isTestnet ?? false;
249
- const nonce = Date.now();
250
- const action = {
251
- type: "approveAgent",
252
- signatureChainId: isTestnet ? "0x66eee" : "0xa4b1",
253
- hyperliquidChain: isTestnet ? "Testnet" : "Mainnet",
254
- agentAddress: agentAddress.toLowerCase() as `0x${string}`,
255
- agentName: null as string | null,
256
- nonce,
257
- };
258
- const types = {
259
- "HyperliquidTransaction:ApproveAgent": [
260
- { name: "hyperliquidChain", type: "string" },
261
- { name: "agentAddress", type: "address" },
262
- { name: "agentName", type: "string" },
263
- { name: "nonce", type: "uint64" },
264
- ],
265
- };
346
+ refreshWallets();
347
+ },
348
+ [tgClient, authDataMap, selectedWalletId, wallets, refreshWallets],
349
+ );
266
350
 
267
- const signature = await signTypedDataAsync({
268
- domain: {
269
- name: "HyperliquidSignTransaction",
270
- version: "1",
271
- chainId: isTestnet ? 421614 : 42161,
272
- verifyingContract: "0x0000000000000000000000000000000000000000",
273
- },
274
- types,
275
- primaryType: "HyperliquidTransaction:ApproveAgent",
276
- message: {
277
- hyperliquidChain: action.hyperliquidChain,
278
- agentAddress: action.agentAddress,
279
- agentName: "",
280
- nonce: BigInt(nonce),
281
- },
351
+ const createWalletPack = useCallback(
352
+ async (name: string): Promise<number> => {
353
+ const { response } = await tgClient.telegramChatWalletPackCreate({
354
+ authData: authDataMap,
355
+ name,
282
356
  });
357
+ refreshWallets();
358
+ return response.packId;
359
+ },
360
+ [tgClient, authDataMap, refreshWallets],
361
+ );
283
362
 
284
- const r = `0x${signature.slice(2, 66)}`;
285
- const s = `0x${signature.slice(66, 130)}`;
286
- const v = parseInt(signature.slice(130, 132), 16);
287
-
288
- const url = isTestnet
289
- ? "https://api.hyperliquid-testnet.xyz/exchange"
290
- : "https://api.hyperliquid.xyz/exchange";
291
-
292
- const res = await fetch(url, {
293
- method: "POST",
294
- headers: { "Content-Type": "application/json" },
295
- body: JSON.stringify({
296
- action,
297
- nonce,
298
- signature: { r, s, v },
299
- }),
363
+ const addPackLabel = useCallback(
364
+ async (params: {
365
+ walletAddress: string;
366
+ walletLabel: string;
367
+ packId: number;
368
+ }): Promise<void> => {
369
+ await tgClient.telegramChatWalletPackLabelAdd({
370
+ authData: authDataMap,
371
+ ...params,
300
372
  });
373
+ refreshWallets();
374
+ },
375
+ [tgClient, authDataMap, refreshWallets],
376
+ );
301
377
 
302
- const body = await res.json();
303
- if (body?.status !== "ok") {
304
- throw new Error(`approveAgent failed: ${JSON.stringify(body)}`);
305
- }
306
-
307
- const stored: StoredAgent = {
308
- privateKey,
309
- address: agentAddress,
310
- approvedAt: Date.now(),
311
- };
312
- saveAgent(eoaAddress, stored);
313
- setAgent(stored);
378
+ const modifyPackLabel = useCallback(
379
+ async (params: {
380
+ walletLabelOld: string;
381
+ walletLabelNew: string;
382
+ packId: number;
383
+ }): Promise<void> => {
384
+ await tgClient.telegramChatWalletPackLabelModify({
385
+ authData: authDataMap,
386
+ ...params,
387
+ });
388
+ refreshWallets();
314
389
  },
315
- [eoaAddress, config.isTestnet],
390
+ [tgClient, authDataMap, refreshWallets],
316
391
  );
317
392
 
318
- const handleClearAgent = useCallback(() => {
319
- if (eoaAddress) {
320
- clearStoredAgent(eoaAddress);
321
- setAgent(null);
322
- }
323
- }, [eoaAddress]);
393
+ const removePackLabel = useCallback(
394
+ async (params: { walletLabel: string; packId: number }): Promise<void> => {
395
+ await tgClient.telegramChatWalletPackLabelRemove({
396
+ authData: authDataMap,
397
+ ...params,
398
+ });
399
+ refreshWallets();
400
+ },
401
+ [tgClient, authDataMap, refreshWallets],
402
+ );
324
403
 
325
404
  // ── Login modal state ────────────────────────────────────────
326
405
  const [loginModalOpen, setLoginModalOpen] = useState(false);
@@ -333,50 +412,134 @@ export function HypurrConnectProvider({
333
412
  localStorage.setItem(TELEGRAM_STORAGE_KEY, JSON.stringify(data));
334
413
  setEoaAddress(null);
335
414
  setAgent(null);
415
+ setEoaError(null);
336
416
  }, []);
337
417
 
338
- const loginEoa = useCallback((address: `0x${string}`) => {
418
+ const connectEoa = useCallback((address: `0x${string}`) => {
339
419
  setEoaAddress(address);
340
420
  setTgLoginData(null);
341
421
  setTgUser(null);
342
422
  setTgError(null);
423
+ setEoaError(null);
343
424
  localStorage.removeItem(TELEGRAM_STORAGE_KEY);
425
+
426
+ const existing = loadAgent(address);
427
+ if (existing && existing.validUntil > Date.now()) {
428
+ setAgent(existing);
429
+ } else {
430
+ if (existing) clearStoredAgent(address);
431
+ setAgent(null);
432
+ }
344
433
  }, []);
345
434
 
435
+ const approveAgentFn = useCallback(
436
+ async (signTypedDataAsync: SignTypedDataFn, chainId: number) => {
437
+ if (!eoaAddress) {
438
+ throw new Error(
439
+ "[HypurrConnect] Cannot approve agent: no EOA wallet connected. Call connectEoa(address) first.",
440
+ );
441
+ }
442
+
443
+ setEoaLoading(true);
444
+ setEoaError(null);
445
+ try {
446
+ const existing = loadAgent(eoaAddress);
447
+ if (existing) {
448
+ const isTestnet = config.isTestnet ?? false;
449
+ const valid = await isAgentValid(existing, eoaAddress, isTestnet);
450
+ if (valid) {
451
+ setAgent(existing);
452
+ return;
453
+ }
454
+ clearStoredAgent(eoaAddress);
455
+ }
456
+
457
+ const { privateKey, address: agentAddress } = await generateAgentKey();
458
+ const isTestnet = config.isTestnet ?? false;
459
+
460
+ const wallet = {
461
+ signTypedData: signTypedDataAsync,
462
+ getAddresses: async () => [eoaAddress] as `0x${string}`[],
463
+ getChainId: async () => chainId,
464
+ };
465
+ const transport = new HttpTransport({ isTestnet });
466
+
467
+ await sdkApproveAgent(
468
+ { transport, wallet },
469
+ {
470
+ agentAddress: agentAddress.toLowerCase() as `0x${string}`,
471
+ agentName: AGENT_NAME,
472
+ },
473
+ );
474
+
475
+ const remote = await fetchActiveAgent(eoaAddress, isTestnet);
476
+ const validUntil =
477
+ remote?.validUntil ?? Date.now() + 7 * 24 * 60 * 60 * 1000;
478
+
479
+ const stored: StoredAgent = {
480
+ privateKey,
481
+ address: agentAddress,
482
+ approvedAt: Date.now(),
483
+ validUntil,
484
+ };
485
+ saveAgent(eoaAddress, stored);
486
+ setAgent(stored);
487
+ } catch (err) {
488
+ console.error("[HypurrConnect] EOA agent approval failed:", err);
489
+ setEoaError(err instanceof Error ? err.message : String(err));
490
+ setAgent(null);
491
+ } finally {
492
+ setEoaLoading(false);
493
+ }
494
+ },
495
+ [eoaAddress, config.isTestnet],
496
+ );
497
+
346
498
  const logout = useCallback(() => {
347
499
  setTgLoginData(null);
348
500
  setTgUser(null);
349
501
  setTgError(null);
350
502
  setEoaAddress(null);
351
503
  setAgent(null);
504
+ setEoaError(null);
352
505
  localStorage.removeItem(TELEGRAM_STORAGE_KEY);
353
506
  }, []);
354
507
 
355
508
  // ── Context value ────────────────────────────────────────────
356
- const value = useMemo<HypurrConnectState>(
509
+ const value = useMemo<InternalConnectState>(
357
510
  () => ({
358
511
  user,
359
512
  isLoggedIn: !!user,
360
- isLoading: tgLoading,
361
- error: tgError,
513
+ isLoading: tgLoading || eoaLoading,
514
+ error: tgError ?? eoaError,
362
515
  authMethod,
363
516
  exchange,
364
517
 
365
- usdcBalance,
366
- usdcBalanceLoading,
367
- refreshBalance,
518
+ wallets,
519
+ selectedWalletId,
520
+ selectWallet,
521
+
522
+ createWallet,
523
+ deleteWallet,
524
+ refreshWallets,
525
+
526
+ packs,
527
+ createWalletPack,
528
+ addPackLabel,
529
+ modifyPackLabel,
530
+ removePackLabel,
368
531
 
369
532
  loginModalOpen,
370
533
  openLoginModal,
371
534
  closeLoginModal,
372
535
 
373
536
  loginTelegram,
374
- loginEoa,
537
+ connectEoa,
538
+ approveAgent: approveAgentFn,
375
539
  logout,
376
540
 
377
541
  agent,
378
- agentReady: authMethod === "telegram" || !!agent,
379
- approveAgent,
542
+ agentReady,
380
543
  clearAgent: handleClearAgent,
381
544
 
382
545
  botId: config.telegram?.botId ?? "",
@@ -388,20 +551,31 @@ export function HypurrConnectProvider({
388
551
  [
389
552
  user,
390
553
  tgLoading,
554
+ eoaLoading,
391
555
  tgError,
556
+ eoaError,
392
557
  authMethod,
393
558
  exchange,
394
- usdcBalance,
395
- usdcBalanceLoading,
396
- refreshBalance,
559
+ wallets,
560
+ selectedWalletId,
561
+ selectWallet,
562
+ createWallet,
563
+ deleteWallet,
564
+ refreshWallets,
565
+ packs,
566
+ createWalletPack,
567
+ addPackLabel,
568
+ modifyPackLabel,
569
+ removePackLabel,
397
570
  loginModalOpen,
398
571
  openLoginModal,
399
572
  closeLoginModal,
400
573
  loginTelegram,
401
- loginEoa,
574
+ connectEoa,
575
+ approveAgentFn,
402
576
  logout,
403
577
  agent,
404
- approveAgent,
578
+ agentReady,
405
579
  handleClearAgent,
406
580
  config.telegram?.botId,
407
581
  authDataMap,