@chipi-stack/chipi-react 11.22.0 → 12.0.0

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/hooks.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { useMutation, useQueryClient, useQuery } from '@tanstack/react-query';
2
- import { createContext, useContext } from 'react';
2
+ import { createContext, useMemo, useCallback, useState, useEffect, useContext } from 'react';
3
3
  import '@chipi-stack/backend';
4
4
  import 'react/jsx-runtime';
5
5
  import { ChipiApiError } from '@chipi-stack/shared';
@@ -80,6 +80,367 @@ function useGetWallet(input) {
80
80
  fetchWallet
81
81
  };
82
82
  }
83
+ function useChipiWallet(config) {
84
+ const { chipiSDK } = useChipiContext();
85
+ const queryClient = useQueryClient();
86
+ const {
87
+ externalUserId,
88
+ getBearerToken,
89
+ defaultToken = "USDC",
90
+ enabled = true
91
+ } = config;
92
+ const isEnabled = Boolean(
93
+ enabled && externalUserId && externalUserId.trim() !== ""
94
+ );
95
+ const walletQuery = useQuery({
96
+ queryKey: ["chipi-wallet", externalUserId],
97
+ queryFn: async () => {
98
+ if (!externalUserId) return null;
99
+ const bearerToken = await getBearerToken();
100
+ if (!bearerToken) throw new Error("Bearer token is required");
101
+ return chipiSDK.getWallet({ externalUserId }, bearerToken);
102
+ },
103
+ enabled: isEnabled,
104
+ retry: (failureCount, error) => {
105
+ if (error instanceof ChipiApiError || error?.status) {
106
+ return false;
107
+ }
108
+ return failureCount < 3;
109
+ }
110
+ });
111
+ const walletPublicKey = walletQuery.data?.wallet.publicKey;
112
+ const balanceQuery = useQuery({
113
+ queryKey: ["chipi-wallet-balance", walletPublicKey, defaultToken],
114
+ queryFn: async () => {
115
+ if (!walletPublicKey) throw new Error("No wallet");
116
+ const bearerToken = await getBearerToken();
117
+ if (!bearerToken) throw new Error("Bearer token is required");
118
+ return chipiSDK.getTokenBalance(
119
+ {
120
+ chain: "STARKNET",
121
+ chainToken: defaultToken,
122
+ walletPublicKey
123
+ },
124
+ bearerToken
125
+ );
126
+ },
127
+ enabled: Boolean(walletPublicKey),
128
+ retry: (failureCount, error) => {
129
+ if (error instanceof ChipiApiError || error?.status) {
130
+ return false;
131
+ }
132
+ return failureCount < 3;
133
+ }
134
+ });
135
+ const createWalletMutation = useMutation({
136
+ mutationFn: async ({ encryptKey, walletType = "CHIPI" }) => {
137
+ if (!externalUserId) throw new Error("External user ID is required");
138
+ const bearerToken = await getBearerToken();
139
+ if (!bearerToken) throw new Error("Bearer token is required");
140
+ return chipiSDK.createWallet({
141
+ params: {
142
+ encryptKey,
143
+ externalUserId,
144
+ walletType
145
+ },
146
+ bearerToken
147
+ });
148
+ },
149
+ onSuccess: () => {
150
+ queryClient.invalidateQueries({
151
+ queryKey: ["chipi-wallet", externalUserId]
152
+ });
153
+ }
154
+ });
155
+ const wallet = useMemo(() => {
156
+ if (walletQuery.isLoading) return void 0;
157
+ if (!walletQuery.data) return null;
158
+ const data = walletQuery.data;
159
+ return {
160
+ ...data,
161
+ supportsSessionKeys: data.wallet.walletType === "CHIPI",
162
+ shortAddress: formatAddress(data.wallet.publicKey)
163
+ };
164
+ }, [walletQuery.data, walletQuery.isLoading]);
165
+ const formattedBalance = useMemo(() => {
166
+ if (!balanceQuery.data?.balance) return "0.00";
167
+ const num = Number(balanceQuery.data.balance);
168
+ return num.toLocaleString(void 0, {
169
+ minimumFractionDigits: 2,
170
+ maximumFractionDigits: defaultToken === "ETH" || defaultToken === "STRK" ? 6 : 2
171
+ });
172
+ }, [balanceQuery.data, defaultToken]);
173
+ const refetchWallet = useCallback(async () => {
174
+ await walletQuery.refetch();
175
+ }, [walletQuery]);
176
+ const refetchBalance = useCallback(async () => {
177
+ await balanceQuery.refetch();
178
+ }, [balanceQuery]);
179
+ const refetchAll = useCallback(async () => {
180
+ await Promise.all([walletQuery.refetch(), balanceQuery.refetch()]);
181
+ }, [walletQuery, balanceQuery]);
182
+ const createWallet = useCallback(
183
+ async (params) => {
184
+ return createWalletMutation.mutateAsync(params);
185
+ },
186
+ [createWalletMutation]
187
+ );
188
+ return {
189
+ // Wallet data
190
+ wallet,
191
+ hasWallet: wallet !== null && wallet !== void 0,
192
+ isLoadingWallet: walletQuery.isLoading,
193
+ walletError: walletQuery.error,
194
+ // Balance data
195
+ balance: balanceQuery.data,
196
+ formattedBalance,
197
+ isLoadingBalance: balanceQuery.isLoading,
198
+ // Create wallet
199
+ createWallet,
200
+ isCreating: createWalletMutation.isPending,
201
+ createdWallet: createWalletMutation.data,
202
+ // Actions
203
+ refetchWallet,
204
+ refetchBalance,
205
+ refetchAll
206
+ };
207
+ }
208
+ function formatAddress(address, chars = 6) {
209
+ if (!address || address.length < chars * 2) return address;
210
+ return `${address.slice(0, chars + 2)}...${address.slice(-chars)}`;
211
+ }
212
+ function useChipiSession(config) {
213
+ const { chipiSDK } = useChipiContext();
214
+ const queryClient = useQueryClient();
215
+ const {
216
+ wallet,
217
+ encryptKey,
218
+ getBearerToken,
219
+ storedSession,
220
+ onSessionCreated,
221
+ defaultDurationSeconds = 21600,
222
+ // 6 hours
223
+ defaultMaxCalls = 1e3,
224
+ autoCheckStatus = true
225
+ } = config;
226
+ const [localSession, setLocalSession] = useState(
227
+ storedSession ?? null
228
+ );
229
+ const [error, setError] = useState(null);
230
+ useEffect(() => {
231
+ if (storedSession) {
232
+ setLocalSession(storedSession);
233
+ }
234
+ }, [storedSession]);
235
+ const supportsSession = useMemo(() => {
236
+ if (!wallet) return false;
237
+ return wallet.walletType === "CHIPI";
238
+ }, [wallet]);
239
+ const sessionStatusQuery = useQuery({
240
+ queryKey: ["chipi-session-status", wallet?.publicKey, localSession?.publicKey],
241
+ queryFn: async () => {
242
+ if (!wallet?.publicKey || !localSession?.publicKey) return null;
243
+ return chipiSDK.sessions.getSessionData({
244
+ walletAddress: wallet.publicKey,
245
+ sessionPublicKey: localSession.publicKey
246
+ });
247
+ },
248
+ enabled: Boolean(
249
+ autoCheckStatus && wallet?.publicKey && localSession?.publicKey && supportsSession
250
+ ),
251
+ staleTime: 3e4
252
+ // 30 seconds
253
+ });
254
+ const sessionState = useMemo(() => {
255
+ if (!localSession) return "none";
256
+ const status = sessionStatusQuery.data;
257
+ if (status) {
258
+ if (!status.isActive) return "revoked";
259
+ if (status.validUntil * 1e3 < Date.now()) return "expired";
260
+ if (status.remainingCalls <= 0) return "expired";
261
+ return "active";
262
+ }
263
+ if (localSession.validUntil * 1e3 < Date.now()) return "expired";
264
+ return "created";
265
+ }, [localSession, sessionStatusQuery.data]);
266
+ const hasActiveSession = sessionState === "active";
267
+ const isSessionExpired = sessionState === "expired";
268
+ const remainingCalls = sessionStatusQuery.data?.remainingCalls;
269
+ const createSessionMutation = useMutation({
270
+ mutationFn: async (params = {}) => {
271
+ if (!encryptKey) throw new Error("Encryption key (PIN) is required");
272
+ if (!supportsSession) throw new Error("Wallet does not support sessions. Only CHIPI wallets support session keys.");
273
+ const sessionData = chipiSDK.sessions.createSessionKey({
274
+ encryptKey,
275
+ durationSeconds: params.durationSeconds ?? defaultDurationSeconds
276
+ });
277
+ return sessionData;
278
+ },
279
+ onSuccess: async (sessionData) => {
280
+ setLocalSession(sessionData);
281
+ setError(null);
282
+ if (onSessionCreated) {
283
+ await onSessionCreated(sessionData);
284
+ }
285
+ },
286
+ onError: (err) => {
287
+ setError(err);
288
+ }
289
+ });
290
+ const registerSessionMutation = useMutation({
291
+ mutationFn: async (sessionConfig = {}) => {
292
+ if (!wallet) throw new Error("Wallet is required");
293
+ if (!localSession) throw new Error("No session to register. Call createSession first.");
294
+ if (!encryptKey) throw new Error("Encryption key (PIN) is required");
295
+ if (!supportsSession) throw new Error("Wallet does not support sessions");
296
+ const bearerToken = await getBearerToken();
297
+ if (!bearerToken) throw new Error("Bearer token is required");
298
+ const txHash = await chipiSDK.sessions.addSessionKeyToContract(
299
+ {
300
+ encryptKey,
301
+ wallet,
302
+ sessionConfig: {
303
+ sessionPublicKey: localSession.publicKey,
304
+ validUntil: sessionConfig.validUntil ?? localSession.validUntil,
305
+ maxCalls: sessionConfig.maxCalls ?? defaultMaxCalls,
306
+ allowedEntrypoints: sessionConfig.allowedEntrypoints ?? []
307
+ }
308
+ },
309
+ bearerToken
310
+ );
311
+ return txHash;
312
+ },
313
+ onSuccess: () => {
314
+ setError(null);
315
+ queryClient.invalidateQueries({
316
+ queryKey: ["chipi-session-status", wallet?.publicKey, localSession?.publicKey]
317
+ });
318
+ },
319
+ onError: (err) => {
320
+ setError(err);
321
+ }
322
+ });
323
+ const revokeSessionMutation = useMutation({
324
+ mutationFn: async () => {
325
+ if (!wallet) throw new Error("Wallet is required");
326
+ if (!localSession) throw new Error("No session to revoke");
327
+ if (!encryptKey) throw new Error("Encryption key (PIN) is required");
328
+ if (!supportsSession) throw new Error("Wallet does not support sessions");
329
+ const bearerToken = await getBearerToken();
330
+ if (!bearerToken) throw new Error("Bearer token is required");
331
+ const txHash = await chipiSDK.sessions.revokeSessionKey(
332
+ {
333
+ encryptKey,
334
+ wallet,
335
+ sessionPublicKey: localSession.publicKey
336
+ },
337
+ bearerToken
338
+ );
339
+ return txHash;
340
+ },
341
+ onSuccess: () => {
342
+ setError(null);
343
+ queryClient.invalidateQueries({
344
+ queryKey: ["chipi-session-status", wallet?.publicKey, localSession?.publicKey]
345
+ });
346
+ },
347
+ onError: (err) => {
348
+ setError(err);
349
+ }
350
+ });
351
+ const executeWithSessionMutation = useMutation({
352
+ mutationFn: async (calls) => {
353
+ if (!wallet) throw new Error("Wallet is required");
354
+ if (!localSession) throw new Error("No active session");
355
+ if (!encryptKey) throw new Error("Encryption key (PIN) is required");
356
+ if (!hasActiveSession) throw new Error("Session is not active. Register the session first.");
357
+ const bearerToken = await getBearerToken();
358
+ if (!bearerToken) throw new Error("Bearer token is required");
359
+ const txHash = await chipiSDK.executeTransactionWithSession({
360
+ params: {
361
+ encryptKey,
362
+ wallet,
363
+ session: localSession,
364
+ calls
365
+ },
366
+ bearerToken
367
+ });
368
+ return txHash;
369
+ },
370
+ onSuccess: () => {
371
+ setError(null);
372
+ queryClient.invalidateQueries({
373
+ queryKey: ["chipi-session-status", wallet?.publicKey, localSession?.publicKey]
374
+ });
375
+ },
376
+ onError: (err) => {
377
+ setError(err);
378
+ }
379
+ });
380
+ const createSession = useCallback(
381
+ async (params) => {
382
+ return createSessionMutation.mutateAsync(params ?? {});
383
+ },
384
+ [createSessionMutation]
385
+ );
386
+ const registerSession = useCallback(
387
+ async (sessionConfig) => {
388
+ return registerSessionMutation.mutateAsync(sessionConfig ?? {});
389
+ },
390
+ [registerSessionMutation]
391
+ );
392
+ const revokeSession = useCallback(async () => {
393
+ return revokeSessionMutation.mutateAsync();
394
+ }, [revokeSessionMutation]);
395
+ const executeWithSession = useCallback(
396
+ async (calls) => {
397
+ return executeWithSessionMutation.mutateAsync(calls);
398
+ },
399
+ [executeWithSessionMutation]
400
+ );
401
+ const clearSession = useCallback(() => {
402
+ setLocalSession(null);
403
+ setError(null);
404
+ }, []);
405
+ const refetchStatus = useCallback(async () => {
406
+ await sessionStatusQuery.refetch();
407
+ }, [sessionStatusQuery]);
408
+ const combinedError = useMemo(() => {
409
+ return error || createSessionMutation.error || registerSessionMutation.error || revokeSessionMutation.error || executeWithSessionMutation.error || sessionStatusQuery.error || null;
410
+ }, [
411
+ error,
412
+ createSessionMutation.error,
413
+ registerSessionMutation.error,
414
+ revokeSessionMutation.error,
415
+ executeWithSessionMutation.error,
416
+ sessionStatusQuery.error
417
+ ]);
418
+ return {
419
+ // Session data
420
+ session: localSession,
421
+ sessionStatus: sessionStatusQuery.data ?? void 0,
422
+ sessionState,
423
+ hasActiveSession,
424
+ isSessionExpired,
425
+ remainingCalls,
426
+ supportsSession,
427
+ // Actions
428
+ createSession,
429
+ registerSession,
430
+ revokeSession,
431
+ executeWithSession,
432
+ clearSession,
433
+ refetchStatus,
434
+ // Loading states
435
+ isCreating: createSessionMutation.isPending,
436
+ isRegistering: registerSessionMutation.isPending,
437
+ isRevoking: revokeSessionMutation.isPending,
438
+ isExecuting: executeWithSessionMutation.isPending,
439
+ isLoadingStatus: sessionStatusQuery.isLoading,
440
+ // Errors
441
+ error: combinedError
442
+ };
443
+ }
83
444
  function useTransfer() {
84
445
  const { chipiSDK } = useChipiContext();
85
446
  const mutation = useMutation(
@@ -530,7 +891,102 @@ function useCreateUser() {
530
891
  reset: mutation.reset
531
892
  };
532
893
  }
894
+ function useCreateSessionKey() {
895
+ const { chipiSDK } = useChipiContext();
896
+ const mutation = useMutation({
897
+ mutationFn: async (params) => chipiSDK.sessions.createSessionKey(params)
898
+ });
899
+ return {
900
+ createSessionKey: mutation.mutate,
901
+ createSessionKeyAsync: mutation.mutateAsync,
902
+ data: mutation.data,
903
+ isLoading: mutation.isPending,
904
+ isError: mutation.isError,
905
+ error: mutation.error,
906
+ isSuccess: mutation.isSuccess,
907
+ reset: mutation.reset
908
+ };
909
+ }
910
+ function useAddSessionKeyToContract() {
911
+ const { chipiSDK } = useChipiContext();
912
+ const mutation = useMutation({
913
+ mutationFn: (input) => chipiSDK.sessions.addSessionKeyToContract(
914
+ input.params,
915
+ input.bearerToken
916
+ )
917
+ });
918
+ return {
919
+ addSessionKeyToContract: mutation.mutate,
920
+ addSessionKeyToContractAsync: mutation.mutateAsync,
921
+ data: mutation.data,
922
+ isLoading: mutation.isPending,
923
+ isError: mutation.isError,
924
+ error: mutation.error,
925
+ isSuccess: mutation.isSuccess,
926
+ reset: mutation.reset
927
+ };
928
+ }
929
+ function useRevokeSessionKey() {
930
+ const { chipiSDK } = useChipiContext();
931
+ const mutation = useMutation({
932
+ mutationFn: (input) => chipiSDK.sessions.revokeSessionKey(input.params, input.bearerToken)
933
+ });
934
+ return {
935
+ revokeSessionKey: mutation.mutate,
936
+ revokeSessionKeyAsync: mutation.mutateAsync,
937
+ data: mutation.data,
938
+ isLoading: mutation.isPending,
939
+ isError: mutation.isError,
940
+ error: mutation.error,
941
+ isSuccess: mutation.isSuccess,
942
+ reset: mutation.reset
943
+ };
944
+ }
945
+ function useGetSessionData(params, options) {
946
+ const { chipiSDK } = useChipiContext();
947
+ const query = useQuery({
948
+ queryKey: [
949
+ "sessionData",
950
+ params?.walletAddress,
951
+ params?.sessionPublicKey
952
+ ],
953
+ queryFn: () => {
954
+ if (!params) {
955
+ throw new Error("Session data params are required");
956
+ }
957
+ return chipiSDK.sessions.getSessionData(params);
958
+ },
959
+ enabled: options?.enabled !== false && params !== null
960
+ });
961
+ return {
962
+ data: query.data,
963
+ isLoading: query.isLoading,
964
+ isError: query.isError,
965
+ error: query.error,
966
+ isSuccess: query.isSuccess,
967
+ refetch: query.refetch
968
+ };
969
+ }
970
+ function useExecuteWithSession() {
971
+ const { chipiSDK } = useChipiContext();
972
+ const mutation = useMutation({
973
+ mutationFn: (input) => chipiSDK.executeTransactionWithSession({
974
+ params: input.params,
975
+ bearerToken: input.bearerToken
976
+ })
977
+ });
978
+ return {
979
+ executeWithSession: mutation.mutate,
980
+ executeWithSessionAsync: mutation.mutateAsync,
981
+ data: mutation.data,
982
+ isLoading: mutation.isPending,
983
+ isError: mutation.isError,
984
+ error: mutation.error,
985
+ isSuccess: mutation.isSuccess,
986
+ reset: mutation.reset
987
+ };
988
+ }
533
989
 
534
- export { useApprove, useCallAnyContract, useCreateSkuTransaction, useCreateUser, useCreateWallet, useGetSku, useGetSkuList, useGetSkuTransaction, useGetTokenBalance, useGetTransactionList, useGetUser, useGetWallet, useRecordSendTransaction, useStakeVesuUsdc, useTransfer, useWithdrawVesuUsdc };
990
+ export { useAddSessionKeyToContract, useApprove, useCallAnyContract, useChipiSession, useChipiWallet, useCreateSessionKey, useCreateSkuTransaction, useCreateUser, useCreateWallet, useExecuteWithSession, useGetSessionData, useGetSku, useGetSkuList, useGetSkuTransaction, useGetTokenBalance, useGetTransactionList, useGetUser, useGetWallet, useRecordSendTransaction, useRevokeSessionKey, useStakeVesuUsdc, useTransfer, useWithdrawVesuUsdc };
535
991
  //# sourceMappingURL=hooks.mjs.map
536
992
  //# sourceMappingURL=hooks.mjs.map