@chipi-stack/chipi-react 13.13.0 → 14.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/index.mjs CHANGED
@@ -32,11 +32,7 @@ var createDefaultQueryClient = () => new QueryClient({
32
32
  }
33
33
  }
34
34
  });
35
- function ChipiProvider({
36
- children,
37
- config,
38
- passkeyAdapter
39
- }) {
35
+ function ChipiProvider({ children, config, passkeyAdapter }) {
40
36
  const queryClient = React.useMemo(() => createDefaultQueryClient(), []);
41
37
  const chipiSDK = React.useMemo(() => new ChipiSDK(config), [config]);
42
38
  const resolvedPasskeyAdapter = passkeyAdapter ?? defaultPasskeyAdapter;
@@ -80,6 +76,9 @@ function useCreateWallet() {
80
76
  throw new Error("Failed to create passkey for wallet");
81
77
  }
82
78
  }
79
+ if (!encryptKey) {
80
+ throw new Error("encryptKey is required when usePasskey is false");
81
+ }
83
82
  return chipiSDK.createWallet({
84
83
  params: {
85
84
  ...input.params,
@@ -106,8 +105,7 @@ function useGetWallet(input) {
106
105
  const query = useQuery({
107
106
  queryKey: ["wallet", input?.params?.externalUserId],
108
107
  queryFn: async () => {
109
- if (!input || !input.params || !input.getBearerToken)
110
- throw new Error("Input is required");
108
+ if (!input || !input.params || !input.getBearerToken) throw new Error("Input is required");
111
109
  const bearerToken = await input.getBearerToken();
112
110
  if (!bearerToken) throw new Error("Bearer token is required");
113
111
  return chipiSDK.getWallet(input.params, bearerToken);
@@ -149,22 +147,16 @@ function useGetWallet(input) {
149
147
  function useChipiWallet(config) {
150
148
  const { chipiSDK } = useChipiContext();
151
149
  const queryClient = useQueryClient();
152
- const {
153
- externalUserId,
154
- getBearerToken,
155
- defaultToken = "USDC",
156
- enabled = true
157
- } = config;
158
- const isEnabled = Boolean(
159
- enabled && externalUserId && externalUserId.trim() !== ""
160
- );
150
+ const { externalUserId, getBearerToken, defaultToken = "USDC", enabled = true } = config;
151
+ const trimmedUserId = externalUserId?.trim() || null;
152
+ const isEnabled = Boolean(enabled && trimmedUserId);
161
153
  const walletQuery = useQuery({
162
- queryKey: ["chipi-wallet", externalUserId],
154
+ queryKey: ["chipi-wallet", trimmedUserId],
163
155
  queryFn: async () => {
164
- if (!externalUserId) return null;
156
+ if (!trimmedUserId) return null;
165
157
  const bearerToken = await getBearerToken();
166
158
  if (!bearerToken) throw new Error("Bearer token is required");
167
- return chipiSDK.getWallet({ externalUserId }, bearerToken);
159
+ return chipiSDK.getWallet({ externalUserId: trimmedUserId }, bearerToken);
168
160
  },
169
161
  enabled: isEnabled,
170
162
  retry: (failureCount, error) => {
@@ -190,7 +182,7 @@ function useChipiWallet(config) {
190
182
  bearerToken
191
183
  );
192
184
  },
193
- enabled: Boolean(walletPublicKey),
185
+ enabled: Boolean(isEnabled && walletPublicKey),
194
186
  retry: (failureCount, error) => {
195
187
  if (error instanceof ChipiApiError || error?.status) {
196
188
  return false;
@@ -200,14 +192,14 @@ function useChipiWallet(config) {
200
192
  });
201
193
  const createWalletMutation = useMutation({
202
194
  mutationFn: async ({ encryptKey, walletType = "CHIPI" }) => {
203
- if (!externalUserId) throw new Error("External user ID is required");
195
+ if (!trimmedUserId) throw new Error("External user ID is required");
204
196
  const bearerToken = await getBearerToken();
205
197
  if (!bearerToken) throw new Error("Bearer token is required");
206
198
  return chipiSDK.createWallet({
207
199
  params: {
208
200
  chain: Chain.STARKNET,
209
201
  encryptKey,
210
- externalUserId,
202
+ externalUserId: trimmedUserId,
211
203
  walletType
212
204
  },
213
205
  bearerToken
@@ -215,7 +207,7 @@ function useChipiWallet(config) {
215
207
  },
216
208
  onSuccess: () => {
217
209
  queryClient.invalidateQueries({
218
- queryKey: ["chipi-wallet", externalUserId]
210
+ queryKey: ["chipi-wallet", trimmedUserId]
219
211
  });
220
212
  }
221
213
  });
@@ -290,14 +282,10 @@ function useChipiSession(config) {
290
282
  defaultMaxCalls = 1e3,
291
283
  autoCheckStatus = true
292
284
  } = config;
293
- const [localSession, setLocalSession] = useState(
294
- storedSession ?? null
295
- );
285
+ const [localSession, setLocalSession] = useState(storedSession ?? null);
296
286
  const [error, setError] = useState(null);
297
287
  useEffect(() => {
298
- if (storedSession) {
299
- setLocalSession(storedSession);
300
- }
288
+ setLocalSession(storedSession ?? null);
301
289
  }, [storedSession]);
302
290
  const supportsSession = useMemo(() => {
303
291
  if (!wallet) return false;
@@ -333,27 +321,32 @@ function useChipiSession(config) {
333
321
  const hasActiveSession = sessionState === "active";
334
322
  const isSessionExpired = sessionState === "expired";
335
323
  const remainingCalls = sessionStatusQuery.data?.remainingCalls;
336
- const createSessionMutation = useMutation({
337
- mutationFn: async (params = {}) => {
338
- if (!encryptKey) throw new Error("Encryption key (PIN) is required");
339
- if (!supportsSession) throw new Error("Wallet does not support sessions. Only CHIPI wallets support session keys.");
340
- const sessionData = chipiSDK.sessions.createSessionKey({
341
- encryptKey,
342
- durationSeconds: params.durationSeconds ?? defaultDurationSeconds
343
- });
344
- return sessionData;
345
- },
346
- onSuccess: async (sessionData) => {
347
- setLocalSession(sessionData);
348
- setError(null);
349
- if (onSessionCreated) {
350
- await onSessionCreated(sessionData);
324
+ const createSessionMutation = useMutation(
325
+ {
326
+ mutationFn: async (params = {}) => {
327
+ if (!encryptKey) throw new Error("Encryption key (PIN) is required");
328
+ if (!supportsSession)
329
+ throw new Error(
330
+ "Wallet does not support sessions. Only CHIPI wallets support session keys."
331
+ );
332
+ const sessionData = chipiSDK.sessions.createSessionKey({
333
+ encryptKey,
334
+ durationSeconds: params.durationSeconds ?? defaultDurationSeconds
335
+ });
336
+ return sessionData;
337
+ },
338
+ onSuccess: async (sessionData) => {
339
+ setLocalSession(sessionData);
340
+ setError(null);
341
+ if (onSessionCreated) {
342
+ await onSessionCreated(sessionData);
343
+ }
344
+ },
345
+ onError: (err) => {
346
+ setError(err);
351
347
  }
352
- },
353
- onError: (err) => {
354
- setError(err);
355
348
  }
356
- });
349
+ );
357
350
  const registerSessionMutation = useMutation({
358
351
  mutationFn: async (sessionConfig = {}) => {
359
352
  if (!wallet) throw new Error("Wallet is required");
@@ -514,22 +507,19 @@ function useMigrateWalletToPasskey() {
514
507
  mutationFn: async (input) => {
515
508
  const { wallet, oldEncryptKey, externalUserId, bearerToken } = input;
516
509
  try {
517
- const passkeyResult = await createWalletPasskey(
518
- externalUserId,
519
- externalUserId
520
- // Using externalUserId as userName
521
- );
522
510
  let decryptedPrivateKey;
523
511
  try {
524
- decryptedPrivateKey = decryptPrivateKey(
525
- wallet.encryptedPrivateKey,
526
- oldEncryptKey
527
- );
528
- } catch (error) {
512
+ decryptedPrivateKey = decryptPrivateKey(wallet.encryptedPrivateKey, oldEncryptKey);
513
+ } catch {
529
514
  throw new Error(
530
515
  "Failed to decrypt wallet with provided encryptKey. Please verify your PIN/password is correct."
531
516
  );
532
517
  }
518
+ const passkeyResult = await createWalletPasskey(
519
+ externalUserId,
520
+ externalUserId
521
+ // Using externalUserId as userName
522
+ );
533
523
  const newEncryptedPrivateKey = encryptPrivateKey(
534
524
  decryptedPrivateKey,
535
525
  passkeyResult.encryptKey
@@ -589,44 +579,49 @@ function useUpdateWalletEncryption() {
589
579
  }
590
580
  function useTransfer() {
591
581
  const { chipiSDK, passkeyAdapter } = useChipiContext();
592
- const mutation = useMutation(
593
- {
594
- mutationFn: async (input) => {
595
- let encryptKey = input.params.encryptKey;
596
- if (input.params.usePasskey) {
597
- if (!input.params.externalUserId) {
598
- throw new Error(
599
- "externalUserId is required when usePasskey is true"
600
- );
582
+ const mutation = useMutation({
583
+ mutationFn: async (input) => {
584
+ let encryptKey = input.params.encryptKey;
585
+ if (input.params.usePasskey) {
586
+ if (!input.params.externalUserId) {
587
+ throw new Error("externalUserId is required when usePasskey is true");
588
+ }
589
+ try {
590
+ const key = await passkeyAdapter.getWalletEncryptKey({
591
+ externalUserId: input.params.externalUserId
592
+ });
593
+ if (!key) {
594
+ throw new Error("Passkey authentication was cancelled");
601
595
  }
602
- try {
603
- const key = await passkeyAdapter.getWalletEncryptKey({
604
- externalUserId: input.params.externalUserId
605
- });
606
- if (!key) {
607
- throw new Error("Passkey authentication was cancelled");
608
- }
609
- encryptKey = key;
610
- } catch (error) {
611
- if (error instanceof Error) {
612
- throw new Error(
613
- `Passkey authentication failed: ${error.message}`
614
- );
615
- }
616
- throw new Error("Failed to authenticate with passkey");
596
+ encryptKey = key;
597
+ } catch (error) {
598
+ if (error instanceof DOMException && error.name === "NotAllowedError") {
599
+ throw new Error("Passkey authentication was cancelled by the user");
600
+ }
601
+ if (error instanceof Error) {
602
+ throw error;
617
603
  }
604
+ throw new Error("Failed to authenticate with passkey");
618
605
  }
619
- return chipiSDK.transfer({
620
- params: {
621
- ...input.params,
622
- amount: String(input.params.amount),
623
- encryptKey
624
- },
625
- bearerToken: input.bearerToken
626
- });
627
606
  }
607
+ if (!encryptKey) {
608
+ throw new Error("encryptKey is required when usePasskey is false");
609
+ }
610
+ const {
611
+ usePasskey: _usePasskey,
612
+ externalUserId: _externalUserId,
613
+ ...transferParams
614
+ } = input.params;
615
+ return chipiSDK.transfer({
616
+ params: {
617
+ ...transferParams,
618
+ amount: String(transferParams.amount),
619
+ encryptKey
620
+ },
621
+ bearerToken: input.bearerToken
622
+ });
628
623
  }
629
- );
624
+ });
630
625
  return {
631
626
  transfer: mutation.mutate,
632
627
  transferAsync: mutation.mutateAsync,
@@ -662,10 +657,20 @@ function useApprove() {
662
657
  throw new Error("Failed to authenticate with passkey");
663
658
  }
664
659
  }
660
+ if (!encryptKey) {
661
+ throw new Error(
662
+ "encryptKey is required when usePasskey is false. Provide a PIN or enable usePasskey."
663
+ );
664
+ }
665
+ const {
666
+ usePasskey: _usePasskey,
667
+ externalUserId: _externalUserId,
668
+ ...approveParams
669
+ } = params.params;
665
670
  return chipiSDK.approve({
666
671
  params: {
667
- ...params.params,
668
- amount: String(params.params.amount),
672
+ ...approveParams,
673
+ amount: String(approveParams.amount),
669
674
  encryptKey
670
675
  },
671
676
  bearerToken: params.bearerToken
@@ -715,9 +720,8 @@ function useGetTransactionList(input) {
715
720
  });
716
721
  const fetchTransactionList = async (newInput) => {
717
722
  return queryClient.fetchQuery({
718
- queryKey: buildQueryKey(newInput?.query),
723
+ queryKey: buildQueryKey(newInput.query),
719
724
  queryFn: async () => {
720
- if (!newInput?.getBearerToken) throw new Error("getBearerToken is required");
721
725
  const bearerToken = await newInput.getBearerToken();
722
726
  if (!bearerToken) throw new Error("Bearer token is required");
723
727
  return chipiSDK.getTransactionList(newInput.query, bearerToken);
@@ -774,8 +778,7 @@ function useGetSkuPurchase(input) {
774
778
  queryKey: ["sku-purchase", newInput?.id],
775
779
  queryFn: async () => {
776
780
  if (!newInput?.id) throw new Error("id is required");
777
- if (!newInput?.getBearerToken)
778
- throw new Error("getBearerToken is required");
781
+ if (!newInput?.getBearerToken) throw new Error("getBearerToken is required");
779
782
  const bearerToken = await newInput.getBearerToken();
780
783
  if (!bearerToken) throw new Error("Bearer token is required");
781
784
  return chipiSDK.getSkuPurchase(newInput.id, bearerToken);
@@ -849,9 +852,7 @@ function useGetSku(input) {
849
852
  if (!bearerToken) throw new Error("Bearer token is required");
850
853
  return chipiSDK.getSku(input.id, bearerToken);
851
854
  },
852
- enabled: Boolean(
853
- input?.id && input?.getBearerToken && input.id.trim() !== ""
854
- ),
855
+ enabled: Boolean(input?.id && input?.getBearerToken && input.id.trim() !== ""),
855
856
  retry: (failureCount, error) => {
856
857
  if (error instanceof ChipiApiError || error?.status) {
857
858
  return false;
@@ -864,14 +865,13 @@ function useGetSku(input) {
864
865
  return queryClient.fetchQuery({
865
866
  queryKey: ["sku", input2?.id],
866
867
  queryFn: async () => {
867
- if (!input2?.getBearerToken)
868
- throw new Error("getBearerToken is required");
868
+ if (!input2?.getBearerToken) throw new Error("getBearerToken is required");
869
869
  const bearerToken = await input2.getBearerToken();
870
870
  if (!bearerToken) throw new Error("Bearer token is required");
871
871
  return chipiSDK.getSku(input2.id, bearerToken);
872
872
  },
873
873
  retry: (failureCount, error) => {
874
- if (error instanceof ChipiApiError || error?.code) {
874
+ if (error instanceof ChipiApiError || error?.status) {
875
875
  return false;
876
876
  }
877
877
  return failureCount < 3;
@@ -890,9 +890,7 @@ function useCallAnyContract() {
890
890
  let encryptKey = params.params.encryptKey;
891
891
  if (params.params.usePasskey) {
892
892
  if (!params.params.externalUserId) {
893
- throw new Error(
894
- "externalUserId is required when usePasskey is true"
895
- );
893
+ throw new Error("externalUserId is required when usePasskey is true");
896
894
  }
897
895
  try {
898
896
  const key = await passkeyAdapter.getWalletEncryptKey({
@@ -903,17 +901,26 @@ function useCallAnyContract() {
903
901
  }
904
902
  encryptKey = key;
905
903
  } catch (error) {
904
+ if (error instanceof DOMException && error.name === "NotAllowedError") {
905
+ throw new Error("Passkey authentication was cancelled by the user");
906
+ }
906
907
  if (error instanceof Error) {
907
- throw new Error(
908
- `Passkey authentication failed: ${error.message}`
909
- );
908
+ throw error;
910
909
  }
911
910
  throw new Error("Failed to authenticate with passkey");
912
911
  }
913
912
  }
913
+ if (!encryptKey) {
914
+ throw new Error("encryptKey is required when usePasskey is false");
915
+ }
916
+ const {
917
+ usePasskey: _usePasskey,
918
+ externalUserId: _externalUserId,
919
+ ...contractParams
920
+ } = params.params;
914
921
  return chipiSDK.callAnyContract({
915
922
  params: {
916
- ...params.params,
923
+ ...contractParams,
917
924
  encryptKey
918
925
  },
919
926
  bearerToken: params.bearerToken
@@ -981,7 +988,8 @@ function useGetTokenBalance(input) {
981
988
  return queryClient.fetchQuery({
982
989
  queryKey: buildQueryKey(newInput?.params),
983
990
  queryFn: async () => {
984
- if (!newInput || !newInput.getBearerToken || !newInput.params) throw new Error("Input is required");
991
+ if (!newInput || !newInput.getBearerToken || !newInput.params)
992
+ throw new Error("Input is required");
985
993
  const bearerToken = await newInput.getBearerToken();
986
994
  if (!bearerToken) throw new Error("Bearer token is required");
987
995
  return chipiSDK.getTokenBalance(newInput.params, bearerToken);
@@ -1018,10 +1026,7 @@ function useCreateSessionKey() {
1018
1026
  function useAddSessionKeyToContract() {
1019
1027
  const { chipiSDK } = useChipiContext();
1020
1028
  const mutation = useMutation({
1021
- mutationFn: (input) => chipiSDK.sessions.addSessionKeyToContract(
1022
- input.params,
1023
- input.bearerToken
1024
- )
1029
+ mutationFn: (input) => chipiSDK.sessions.addSessionKeyToContract(input.params, input.bearerToken)
1025
1030
  });
1026
1031
  return {
1027
1032
  addSessionKeyToContract: mutation.mutate,
@@ -1053,11 +1058,7 @@ function useRevokeSessionKey() {
1053
1058
  function useGetSessionData(params, options) {
1054
1059
  const { chipiSDK } = useChipiContext();
1055
1060
  const query = useQuery({
1056
- queryKey: [
1057
- "sessionData",
1058
- params?.walletAddress,
1059
- params?.sessionPublicKey
1060
- ],
1061
+ queryKey: ["sessionData", params?.walletAddress, params?.sessionPublicKey],
1061
1062
  queryFn: () => {
1062
1063
  if (!params) {
1063
1064
  throw new Error("Session data params are required");