@pear-protocol/symmio-client 0.3.3 → 0.3.5

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.
@@ -2,7 +2,7 @@
2
2
  import { createContext, useContext, useMemo, useCallback, useRef, useEffect } from 'react';
3
3
  import { createSymmSDK, isAuthExpiredError, isNetworkError, isInsufficientMarginError, isRateLimitedError, isTimeoutError } from '@pear-protocol/symm-core';
4
4
  import { create } from 'zustand';
5
- import { useQueryClient, useQuery, useMutation } from '@tanstack/react-query';
5
+ import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query';
6
6
  import { jsx } from 'react/jsx-runtime';
7
7
  import { SiweMessage } from 'siwe';
8
8
  import { isAddress, encodeFunctionData } from 'viem';
@@ -904,27 +904,116 @@ async function fetchAccessTokenEntry(walletClient, signerAddress, accountAddress
904
904
  writeStoredToken(accountAddress, chainId, cachedToken);
905
905
  return cachedToken;
906
906
  }
907
+ function authStoreKey(accountAddress, chainId, signerAddress) {
908
+ return `${accountAddress}:${chainId}:${signerAddress ?? ""}`;
909
+ }
910
+ function getEntryFromSnapshot(state, accountAddress, chainId, signerAddress) {
911
+ const signerScoped = state.entries[authStoreKey(accountAddress, chainId, signerAddress)];
912
+ if (signerScoped) {
913
+ return signerScoped;
914
+ }
915
+ return state.entries[authStoreKey(accountAddress, chainId)] ?? null;
916
+ }
917
+ function getStatusFromSnapshot(state, accountAddress, chainId, signerAddress) {
918
+ const signerScoped = state.status[authStoreKey(accountAddress, chainId, signerAddress)];
919
+ if (signerScoped) {
920
+ return signerScoped;
921
+ }
922
+ return state.status[authStoreKey(accountAddress, chainId)] ?? {
923
+ error: null,
924
+ isLoading: false
925
+ };
926
+ }
927
+ var useSymmAuthStore = create((set) => ({
928
+ entries: {},
929
+ status: {},
930
+ setEntry: (accountAddress, chainId, signerAddress, entry) => set((state) => ({
931
+ entries: {
932
+ ...state.entries,
933
+ [authStoreKey(accountAddress, chainId, signerAddress)]: entry
934
+ },
935
+ status: {
936
+ ...state.status,
937
+ [authStoreKey(accountAddress, chainId, signerAddress)]: {
938
+ error: null,
939
+ isLoading: false
940
+ }
941
+ }
942
+ })),
943
+ clearEntry: (accountAddress, chainId, signerAddress) => set((state) => {
944
+ const nextEntries = { ...state.entries };
945
+ const nextStatus = { ...state.status };
946
+ delete nextEntries[authStoreKey(accountAddress, chainId, signerAddress)];
947
+ delete nextStatus[authStoreKey(accountAddress, chainId, signerAddress)];
948
+ return {
949
+ entries: nextEntries,
950
+ status: nextStatus
951
+ };
952
+ }),
953
+ setStatus: (accountAddress, chainId, signerAddress, status) => set((state) => ({
954
+ status: {
955
+ ...state.status,
956
+ [authStoreKey(accountAddress, chainId, signerAddress)]: {
957
+ error: null,
958
+ isLoading: false,
959
+ ...state.status[authStoreKey(accountAddress, chainId, signerAddress)],
960
+ ...status
961
+ }
962
+ }
963
+ })),
964
+ reset: () => set({
965
+ entries: {},
966
+ status: {}
967
+ })
968
+ }));
969
+ function getAuthStoreEntry(accountAddress, chainId, signerAddress) {
970
+ return getEntryFromSnapshot(
971
+ useSymmAuthStore.getState(),
972
+ accountAddress,
973
+ chainId,
974
+ signerAddress
975
+ );
976
+ }
977
+ function selectAuthStoreEntry(state, accountAddress, chainId, signerAddress) {
978
+ if (!accountAddress || chainId == null) {
979
+ return null;
980
+ }
981
+ return getEntryFromSnapshot(state, accountAddress, chainId, signerAddress);
982
+ }
983
+ function selectAuthStoreStatus(state, accountAddress, chainId, signerAddress) {
984
+ if (!accountAddress || chainId == null) {
985
+ return {
986
+ error: null,
987
+ isLoading: false
988
+ };
989
+ }
990
+ return getStatusFromSnapshot(state, accountAddress, chainId, signerAddress);
991
+ }
992
+ function setAuthStoreEntry(accountAddress, chainId, signerAddress, entry) {
993
+ useSymmAuthStore.getState().setEntry(accountAddress, chainId, signerAddress, entry);
994
+ }
995
+ function setAuthStoreStatus(accountAddress, chainId, signerAddress, status) {
996
+ useSymmAuthStore.getState().setStatus(accountAddress, chainId, signerAddress, status);
997
+ }
998
+ function clearAuthStoreEntry(accountAddress, chainId, signerAddress) {
999
+ useSymmAuthStore.getState().clearEntry(accountAddress, chainId, signerAddress);
1000
+ }
907
1001
 
908
1002
  // src/react/auth-cache.ts
909
- function getAuthQueryData(queryClient, accountAddress, chainId, signerAddress) {
910
- return queryClient.getQueryData(
911
- symmKeys.auth(accountAddress, chainId, signerAddress)
912
- ) ?? null;
1003
+ function getAuthQueryData(accountAddress, chainId, signerAddress) {
1004
+ return getAuthStoreEntry(accountAddress, chainId, signerAddress);
913
1005
  }
914
- function setAuthQueryData(queryClient, accountAddress, chainId, signerAddress, entry) {
915
- queryClient.setQueryData(symmKeys.auth(accountAddress, chainId, signerAddress), entry);
1006
+ function setAuthQueryData(accountAddress, chainId, signerAddress, entry) {
1007
+ setAuthStoreEntry(accountAddress, chainId, signerAddress, entry);
916
1008
  }
917
- function clearAuthQueryData(queryClient, accountAddress, chainId, signerAddress) {
918
- queryClient.removeQueries({
919
- queryKey: symmKeys.auth(accountAddress, chainId, signerAddress),
920
- exact: true
921
- });
1009
+ function clearAuthQueryData(accountAddress, chainId, signerAddress) {
1010
+ clearAuthStoreEntry(accountAddress, chainId, signerAddress);
922
1011
  }
923
1012
  function clearPersistedAuthState(accountAddress, chainId) {
924
1013
  clearCachedToken(accountAddress, chainId);
925
1014
  }
926
- function getAuthTokenFromRuntimeCache(queryClient, accountAddress, chainId, signerAddress) {
927
- const inQuery = getAuthQueryData(queryClient, accountAddress, chainId, signerAddress) ?? getAuthQueryData(queryClient, accountAddress, chainId);
1015
+ function getAuthTokenFromRuntimeCache(accountAddress, chainId, signerAddress) {
1016
+ const inQuery = getAuthQueryData(accountAddress, chainId, signerAddress) ?? getAuthQueryData(accountAddress, chainId);
928
1017
  if (inQuery && inQuery.expiresAt > Date.now()) {
929
1018
  return inQuery.token;
930
1019
  }
@@ -932,11 +1021,10 @@ function getAuthTokenFromRuntimeCache(queryClient, accountAddress, chainId, sign
932
1021
  if (!persisted) {
933
1022
  return null;
934
1023
  }
935
- setAuthQueryData(queryClient, accountAddress, chainId, signerAddress, persisted);
1024
+ setAuthQueryData(accountAddress, chainId, signerAddress, persisted);
936
1025
  return persisted.token;
937
1026
  }
938
1027
  async function resolveAuthTokenEntry({
939
- queryClient,
940
1028
  walletClient,
941
1029
  signerAddress,
942
1030
  accountAddress,
@@ -948,13 +1036,13 @@ async function resolveAuthTokenEntry({
948
1036
  return null;
949
1037
  }
950
1038
  if (!force) {
951
- const inQuery = getAuthQueryData(queryClient, accountAddress, chainId, signerAddress);
1039
+ const inQuery = getAuthQueryData(accountAddress, chainId, signerAddress);
952
1040
  if (inQuery && inQuery.expiresAt > Date.now()) {
953
1041
  return inQuery;
954
1042
  }
955
1043
  const persisted = getCachedTokenEntry(accountAddress, chainId);
956
1044
  if (persisted) {
957
- setAuthQueryData(queryClient, accountAddress, chainId, signerAddress, persisted);
1045
+ setAuthQueryData(accountAddress, chainId, signerAddress, persisted);
958
1046
  return persisted;
959
1047
  }
960
1048
  }
@@ -965,25 +1053,33 @@ async function resolveAuthTokenEntry({
965
1053
  chainId,
966
1054
  siweDomain
967
1055
  );
968
- setAuthQueryData(queryClient, accountAddress, chainId, signerAddress, fresh);
1056
+ setAuthQueryData(accountAddress, chainId, signerAddress, fresh);
969
1057
  return fresh;
970
1058
  }
971
- function clearAuthState(queryClient, accountAddress, chainId, signerAddress) {
1059
+ function clearAuthState(accountAddress, chainId, signerAddress) {
972
1060
  clearPersistedAuthState(accountAddress, chainId);
973
- clearAuthQueryData(queryClient, accountAddress, chainId, signerAddress);
1061
+ clearAuthQueryData(accountAddress, chainId, signerAddress);
974
1062
  }
975
1063
 
976
1064
  // src/react/hooks/use-symm-auth.ts
977
1065
  function useSymmAuth(params) {
978
1066
  const context = useSymmContext();
979
- const queryClient = useQueryClient();
980
1067
  const address = params?.address ?? context.address;
981
1068
  const chainId = params?.chainId ?? context.chainId ?? 42161;
982
1069
  const walletClient = params?.walletClient ?? context.walletClient;
983
1070
  const siweDomain = params?.siweDomain;
984
1071
  const activeAccountAddress = params?.activeAccountAddress;
985
- const canBootstrap = !!walletClient && !!address && !!activeAccountAddress;
986
- const refreshAuth = useCallback(
1072
+ const authEntry = useSymmAuthStore(
1073
+ (state) => selectAuthStoreEntry(state, activeAccountAddress, chainId, address)
1074
+ );
1075
+ useSymmAuthStore(
1076
+ (state) => selectAuthStoreStatus(state, activeAccountAddress, chainId, address).isLoading
1077
+ );
1078
+ const error = useSymmAuthStore(
1079
+ (state) => selectAuthStoreStatus(state, activeAccountAddress, chainId, address).error
1080
+ );
1081
+ const persistedEntry = !authEntry && activeAccountAddress ? getCachedTokenEntry(activeAccountAddress, chainId) : null;
1082
+ const signIn = useCallback(
987
1083
  async (accountAddress, options) => {
988
1084
  const resolvedAccountAddress = accountAddress ?? activeAccountAddress;
989
1085
  if (!resolvedAccountAddress) {
@@ -991,8 +1087,11 @@ function useSymmAuth(params) {
991
1087
  }
992
1088
  if (!walletClient || !address) return null;
993
1089
  try {
994
- const tokenEntry = await resolveAuthTokenEntry({
995
- queryClient,
1090
+ setAuthStoreStatus(resolvedAccountAddress, chainId, address, {
1091
+ error: null,
1092
+ isLoading: true
1093
+ });
1094
+ const tokenEntry2 = await resolveAuthTokenEntry({
996
1095
  walletClient,
997
1096
  signerAddress: address,
998
1097
  accountAddress: resolvedAccountAddress,
@@ -1000,10 +1099,16 @@ function useSymmAuth(params) {
1000
1099
  siweDomain,
1001
1100
  force: options?.force
1002
1101
  });
1003
- const token2 = tokenEntry?.token ?? null;
1004
- return token2;
1005
- } catch (error) {
1006
- clearPersistedAuthState(resolvedAccountAddress, chainId);
1102
+ setAuthStoreStatus(resolvedAccountAddress, chainId, address, {
1103
+ error: null,
1104
+ isLoading: false
1105
+ });
1106
+ return tokenEntry2?.token ?? null;
1107
+ } catch (error2) {
1108
+ clearAuthState(resolvedAccountAddress, chainId, address);
1109
+ setAuthStoreStatus(resolvedAccountAddress, chainId, address, {
1110
+ error: error2 instanceof Error ? error2 : new Error("failed to sign in")
1111
+ });
1007
1112
  return null;
1008
1113
  }
1009
1114
  },
@@ -1012,46 +1117,22 @@ function useSymmAuth(params) {
1012
1117
  address,
1013
1118
  activeAccountAddress,
1014
1119
  chainId,
1015
- siweDomain,
1016
- queryClient
1120
+ siweDomain
1017
1121
  ]
1018
1122
  );
1019
- const authQuery = useQuery({
1020
- queryKey: symmKeys.auth(activeAccountAddress, chainId, address),
1021
- queryFn: async () => {
1022
- const tokenEntry = await resolveAuthTokenEntry({
1023
- queryClient,
1024
- walletClient,
1025
- signerAddress: address,
1026
- accountAddress: activeAccountAddress,
1027
- chainId,
1028
- siweDomain
1029
- });
1030
- if (!tokenEntry) {
1031
- return null;
1032
- }
1033
- return tokenEntry;
1034
- },
1035
- enabled: canBootstrap,
1036
- retry: false,
1037
- refetchOnWindowFocus: false,
1038
- refetchOnReconnect: false
1039
- });
1040
1123
  const clearAuth = useCallback(() => {
1041
1124
  if (activeAccountAddress) {
1042
- clearAuthState(queryClient, activeAccountAddress, chainId, address);
1125
+ clearAuthState(activeAccountAddress, chainId, address);
1043
1126
  }
1044
- }, [activeAccountAddress, address, chainId, queryClient]);
1045
- const token = authQuery.data?.token ?? null;
1127
+ }, [activeAccountAddress, address, chainId]);
1128
+ const tokenEntry = authEntry ?? persistedEntry;
1129
+ const token = tokenEntry?.token ?? null;
1046
1130
  return {
1047
1131
  accessToken: token,
1048
- authToken: token,
1049
1132
  isAuthenticated: !!token,
1050
- isLoading: authQuery.isLoading,
1051
- isFetching: authQuery.isFetching,
1052
- error: authQuery.error,
1053
- refresh: refreshAuth,
1054
- refreshAuth,
1133
+ error,
1134
+ signIn,
1135
+ refreshAuth: signIn,
1055
1136
  clear: clearAuth
1056
1137
  };
1057
1138
  }
@@ -1855,7 +1936,6 @@ async function ensureInstantTradeReady(deps, queryClient, request) {
1855
1936
  throw new Error("at least one delegation selector is required");
1856
1937
  }
1857
1938
  const accessToken = getAuthTokenFromRuntimeCache(
1858
- queryClient,
1859
1939
  accountAddress,
1860
1940
  chainId,
1861
1941
  signerAddress
@@ -2265,7 +2345,6 @@ function splitTradeHookArgs(paramsOrOptions, options) {
2265
2345
  }
2266
2346
  function useResolveTradeAuthToken(params = {}) {
2267
2347
  const context = useSymmContext();
2268
- const queryClient = useQueryClient();
2269
2348
  const address = params.address ?? context.address;
2270
2349
  const chainId = params.chainId ?? context.chainId;
2271
2350
  return useCallback(
@@ -2279,7 +2358,6 @@ function useResolveTradeAuthToken(params = {}) {
2279
2358
  return null;
2280
2359
  }
2281
2360
  const inMemoryToken = getAuthTokenFromRuntimeCache(
2282
- queryClient,
2283
2361
  resolvedAccountAddress,
2284
2362
  resolvedChainId,
2285
2363
  address
@@ -2289,7 +2367,7 @@ function useResolveTradeAuthToken(params = {}) {
2289
2367
  }
2290
2368
  return null;
2291
2369
  },
2292
- [address, chainId, queryClient]
2370
+ [address, chainId]
2293
2371
  );
2294
2372
  }
2295
2373
 
@@ -26251,7 +26329,6 @@ function useSymmPendingInstantOpens(params) {
26251
26329
  chainId: ctxChainId,
26252
26330
  address
26253
26331
  } = useSymmContext();
26254
- const queryClient = useQueryClient();
26255
26332
  const { accountAddress, authToken: providedAuthToken } = params;
26256
26333
  const chainId = params.chainId ?? ctxChainId;
26257
26334
  const internalEnabled = !!symmCoreClient && !!accountAddress;
@@ -26260,7 +26337,6 @@ function useSymmPendingInstantOpens(params) {
26260
26337
  queryKey: symmKeys.pendingInstantOpens(accountAddress, chainId),
26261
26338
  queryFn: async () => {
26262
26339
  const authToken = providedAuthToken ?? getAuthTokenFromRuntimeCache(
26263
- queryClient,
26264
26340
  accountAddress,
26265
26341
  chainId,
26266
26342
  address