@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.
@@ -35,16 +35,15 @@ type UseSymmAuthParams = {
35
35
  siweDomain?: string;
36
36
  };
37
37
  /**
38
- * Use case: Manage SYMM auth token lifecycle (read, refresh, clear) for an address and chain.
38
+ * Manages SYMM auth token state. Reads cached / persisted tokens on mount
39
+ * without any side effects — the wallet signature flow is only triggered
40
+ * when the caller explicitly invokes `signIn()`.
39
41
  */
40
42
  declare function useSymmAuth(params?: UseSymmAuthParams): {
41
43
  accessToken: string | null;
42
- authToken: string | null;
43
44
  isAuthenticated: boolean;
44
- isLoading: boolean;
45
- isFetching: boolean;
46
45
  error: Error | null;
47
- refresh: (accountAddress?: Address, options?: {
46
+ signIn: (accountAddress?: Address, options?: {
48
47
  force?: boolean;
49
48
  }) => Promise<string | null>;
50
49
  refreshAuth: (accountAddress?: Address, options?: {
@@ -35,16 +35,15 @@ type UseSymmAuthParams = {
35
35
  siweDomain?: string;
36
36
  };
37
37
  /**
38
- * Use case: Manage SYMM auth token lifecycle (read, refresh, clear) for an address and chain.
38
+ * Manages SYMM auth token state. Reads cached / persisted tokens on mount
39
+ * without any side effects — the wallet signature flow is only triggered
40
+ * when the caller explicitly invokes `signIn()`.
39
41
  */
40
42
  declare function useSymmAuth(params?: UseSymmAuthParams): {
41
43
  accessToken: string | null;
42
- authToken: string | null;
43
44
  isAuthenticated: boolean;
44
- isLoading: boolean;
45
- isFetching: boolean;
46
45
  error: Error | null;
47
- refresh: (accountAddress?: Address, options?: {
46
+ signIn: (accountAddress?: Address, options?: {
48
47
  force?: boolean;
49
48
  }) => Promise<string | null>;
50
49
  refreshAuth: (accountAddress?: Address, options?: {
@@ -906,27 +906,116 @@ async function fetchAccessTokenEntry(walletClient, signerAddress, accountAddress
906
906
  writeStoredToken(accountAddress, chainId, cachedToken);
907
907
  return cachedToken;
908
908
  }
909
+ function authStoreKey(accountAddress, chainId, signerAddress) {
910
+ return `${accountAddress}:${chainId}:${signerAddress ?? ""}`;
911
+ }
912
+ function getEntryFromSnapshot(state, accountAddress, chainId, signerAddress) {
913
+ const signerScoped = state.entries[authStoreKey(accountAddress, chainId, signerAddress)];
914
+ if (signerScoped) {
915
+ return signerScoped;
916
+ }
917
+ return state.entries[authStoreKey(accountAddress, chainId)] ?? null;
918
+ }
919
+ function getStatusFromSnapshot(state, accountAddress, chainId, signerAddress) {
920
+ const signerScoped = state.status[authStoreKey(accountAddress, chainId, signerAddress)];
921
+ if (signerScoped) {
922
+ return signerScoped;
923
+ }
924
+ return state.status[authStoreKey(accountAddress, chainId)] ?? {
925
+ error: null,
926
+ isLoading: false
927
+ };
928
+ }
929
+ var useSymmAuthStore = zustand.create((set) => ({
930
+ entries: {},
931
+ status: {},
932
+ setEntry: (accountAddress, chainId, signerAddress, entry) => set((state) => ({
933
+ entries: {
934
+ ...state.entries,
935
+ [authStoreKey(accountAddress, chainId, signerAddress)]: entry
936
+ },
937
+ status: {
938
+ ...state.status,
939
+ [authStoreKey(accountAddress, chainId, signerAddress)]: {
940
+ error: null,
941
+ isLoading: false
942
+ }
943
+ }
944
+ })),
945
+ clearEntry: (accountAddress, chainId, signerAddress) => set((state) => {
946
+ const nextEntries = { ...state.entries };
947
+ const nextStatus = { ...state.status };
948
+ delete nextEntries[authStoreKey(accountAddress, chainId, signerAddress)];
949
+ delete nextStatus[authStoreKey(accountAddress, chainId, signerAddress)];
950
+ return {
951
+ entries: nextEntries,
952
+ status: nextStatus
953
+ };
954
+ }),
955
+ setStatus: (accountAddress, chainId, signerAddress, status) => set((state) => ({
956
+ status: {
957
+ ...state.status,
958
+ [authStoreKey(accountAddress, chainId, signerAddress)]: {
959
+ error: null,
960
+ isLoading: false,
961
+ ...state.status[authStoreKey(accountAddress, chainId, signerAddress)],
962
+ ...status
963
+ }
964
+ }
965
+ })),
966
+ reset: () => set({
967
+ entries: {},
968
+ status: {}
969
+ })
970
+ }));
971
+ function getAuthStoreEntry(accountAddress, chainId, signerAddress) {
972
+ return getEntryFromSnapshot(
973
+ useSymmAuthStore.getState(),
974
+ accountAddress,
975
+ chainId,
976
+ signerAddress
977
+ );
978
+ }
979
+ function selectAuthStoreEntry(state, accountAddress, chainId, signerAddress) {
980
+ if (!accountAddress || chainId == null) {
981
+ return null;
982
+ }
983
+ return getEntryFromSnapshot(state, accountAddress, chainId, signerAddress);
984
+ }
985
+ function selectAuthStoreStatus(state, accountAddress, chainId, signerAddress) {
986
+ if (!accountAddress || chainId == null) {
987
+ return {
988
+ error: null,
989
+ isLoading: false
990
+ };
991
+ }
992
+ return getStatusFromSnapshot(state, accountAddress, chainId, signerAddress);
993
+ }
994
+ function setAuthStoreEntry(accountAddress, chainId, signerAddress, entry) {
995
+ useSymmAuthStore.getState().setEntry(accountAddress, chainId, signerAddress, entry);
996
+ }
997
+ function setAuthStoreStatus(accountAddress, chainId, signerAddress, status) {
998
+ useSymmAuthStore.getState().setStatus(accountAddress, chainId, signerAddress, status);
999
+ }
1000
+ function clearAuthStoreEntry(accountAddress, chainId, signerAddress) {
1001
+ useSymmAuthStore.getState().clearEntry(accountAddress, chainId, signerAddress);
1002
+ }
909
1003
 
910
1004
  // src/react/auth-cache.ts
911
- function getAuthQueryData(queryClient, accountAddress, chainId, signerAddress) {
912
- return queryClient.getQueryData(
913
- symmKeys.auth(accountAddress, chainId, signerAddress)
914
- ) ?? null;
1005
+ function getAuthQueryData(accountAddress, chainId, signerAddress) {
1006
+ return getAuthStoreEntry(accountAddress, chainId, signerAddress);
915
1007
  }
916
- function setAuthQueryData(queryClient, accountAddress, chainId, signerAddress, entry) {
917
- queryClient.setQueryData(symmKeys.auth(accountAddress, chainId, signerAddress), entry);
1008
+ function setAuthQueryData(accountAddress, chainId, signerAddress, entry) {
1009
+ setAuthStoreEntry(accountAddress, chainId, signerAddress, entry);
918
1010
  }
919
- function clearAuthQueryData(queryClient, accountAddress, chainId, signerAddress) {
920
- queryClient.removeQueries({
921
- queryKey: symmKeys.auth(accountAddress, chainId, signerAddress),
922
- exact: true
923
- });
1011
+ function clearAuthQueryData(accountAddress, chainId, signerAddress) {
1012
+ clearAuthStoreEntry(accountAddress, chainId, signerAddress);
924
1013
  }
925
1014
  function clearPersistedAuthState(accountAddress, chainId) {
926
1015
  clearCachedToken(accountAddress, chainId);
927
1016
  }
928
- function getAuthTokenFromRuntimeCache(queryClient, accountAddress, chainId, signerAddress) {
929
- const inQuery = getAuthQueryData(queryClient, accountAddress, chainId, signerAddress) ?? getAuthQueryData(queryClient, accountAddress, chainId);
1017
+ function getAuthTokenFromRuntimeCache(accountAddress, chainId, signerAddress) {
1018
+ const inQuery = getAuthQueryData(accountAddress, chainId, signerAddress) ?? getAuthQueryData(accountAddress, chainId);
930
1019
  if (inQuery && inQuery.expiresAt > Date.now()) {
931
1020
  return inQuery.token;
932
1021
  }
@@ -934,11 +1023,10 @@ function getAuthTokenFromRuntimeCache(queryClient, accountAddress, chainId, sign
934
1023
  if (!persisted) {
935
1024
  return null;
936
1025
  }
937
- setAuthQueryData(queryClient, accountAddress, chainId, signerAddress, persisted);
1026
+ setAuthQueryData(accountAddress, chainId, signerAddress, persisted);
938
1027
  return persisted.token;
939
1028
  }
940
1029
  async function resolveAuthTokenEntry({
941
- queryClient,
942
1030
  walletClient,
943
1031
  signerAddress,
944
1032
  accountAddress,
@@ -950,13 +1038,13 @@ async function resolveAuthTokenEntry({
950
1038
  return null;
951
1039
  }
952
1040
  if (!force) {
953
- const inQuery = getAuthQueryData(queryClient, accountAddress, chainId, signerAddress);
1041
+ const inQuery = getAuthQueryData(accountAddress, chainId, signerAddress);
954
1042
  if (inQuery && inQuery.expiresAt > Date.now()) {
955
1043
  return inQuery;
956
1044
  }
957
1045
  const persisted = getCachedTokenEntry(accountAddress, chainId);
958
1046
  if (persisted) {
959
- setAuthQueryData(queryClient, accountAddress, chainId, signerAddress, persisted);
1047
+ setAuthQueryData(accountAddress, chainId, signerAddress, persisted);
960
1048
  return persisted;
961
1049
  }
962
1050
  }
@@ -967,25 +1055,33 @@ async function resolveAuthTokenEntry({
967
1055
  chainId,
968
1056
  siweDomain
969
1057
  );
970
- setAuthQueryData(queryClient, accountAddress, chainId, signerAddress, fresh);
1058
+ setAuthQueryData(accountAddress, chainId, signerAddress, fresh);
971
1059
  return fresh;
972
1060
  }
973
- function clearAuthState(queryClient, accountAddress, chainId, signerAddress) {
1061
+ function clearAuthState(accountAddress, chainId, signerAddress) {
974
1062
  clearPersistedAuthState(accountAddress, chainId);
975
- clearAuthQueryData(queryClient, accountAddress, chainId, signerAddress);
1063
+ clearAuthQueryData(accountAddress, chainId, signerAddress);
976
1064
  }
977
1065
 
978
1066
  // src/react/hooks/use-symm-auth.ts
979
1067
  function useSymmAuth(params) {
980
1068
  const context = useSymmContext();
981
- const queryClient = reactQuery.useQueryClient();
982
1069
  const address = params?.address ?? context.address;
983
1070
  const chainId = params?.chainId ?? context.chainId ?? 42161;
984
1071
  const walletClient = params?.walletClient ?? context.walletClient;
985
1072
  const siweDomain = params?.siweDomain;
986
1073
  const activeAccountAddress = params?.activeAccountAddress;
987
- const canBootstrap = !!walletClient && !!address && !!activeAccountAddress;
988
- const refreshAuth = react.useCallback(
1074
+ const authEntry = useSymmAuthStore(
1075
+ (state) => selectAuthStoreEntry(state, activeAccountAddress, chainId, address)
1076
+ );
1077
+ useSymmAuthStore(
1078
+ (state) => selectAuthStoreStatus(state, activeAccountAddress, chainId, address).isLoading
1079
+ );
1080
+ const error = useSymmAuthStore(
1081
+ (state) => selectAuthStoreStatus(state, activeAccountAddress, chainId, address).error
1082
+ );
1083
+ const persistedEntry = !authEntry && activeAccountAddress ? getCachedTokenEntry(activeAccountAddress, chainId) : null;
1084
+ const signIn = react.useCallback(
989
1085
  async (accountAddress, options) => {
990
1086
  const resolvedAccountAddress = accountAddress ?? activeAccountAddress;
991
1087
  if (!resolvedAccountAddress) {
@@ -993,8 +1089,11 @@ function useSymmAuth(params) {
993
1089
  }
994
1090
  if (!walletClient || !address) return null;
995
1091
  try {
996
- const tokenEntry = await resolveAuthTokenEntry({
997
- queryClient,
1092
+ setAuthStoreStatus(resolvedAccountAddress, chainId, address, {
1093
+ error: null,
1094
+ isLoading: true
1095
+ });
1096
+ const tokenEntry2 = await resolveAuthTokenEntry({
998
1097
  walletClient,
999
1098
  signerAddress: address,
1000
1099
  accountAddress: resolvedAccountAddress,
@@ -1002,10 +1101,16 @@ function useSymmAuth(params) {
1002
1101
  siweDomain,
1003
1102
  force: options?.force
1004
1103
  });
1005
- const token2 = tokenEntry?.token ?? null;
1006
- return token2;
1007
- } catch (error) {
1008
- clearPersistedAuthState(resolvedAccountAddress, chainId);
1104
+ setAuthStoreStatus(resolvedAccountAddress, chainId, address, {
1105
+ error: null,
1106
+ isLoading: false
1107
+ });
1108
+ return tokenEntry2?.token ?? null;
1109
+ } catch (error2) {
1110
+ clearAuthState(resolvedAccountAddress, chainId, address);
1111
+ setAuthStoreStatus(resolvedAccountAddress, chainId, address, {
1112
+ error: error2 instanceof Error ? error2 : new Error("failed to sign in")
1113
+ });
1009
1114
  return null;
1010
1115
  }
1011
1116
  },
@@ -1014,46 +1119,22 @@ function useSymmAuth(params) {
1014
1119
  address,
1015
1120
  activeAccountAddress,
1016
1121
  chainId,
1017
- siweDomain,
1018
- queryClient
1122
+ siweDomain
1019
1123
  ]
1020
1124
  );
1021
- const authQuery = reactQuery.useQuery({
1022
- queryKey: symmKeys.auth(activeAccountAddress, chainId, address),
1023
- queryFn: async () => {
1024
- const tokenEntry = await resolveAuthTokenEntry({
1025
- queryClient,
1026
- walletClient,
1027
- signerAddress: address,
1028
- accountAddress: activeAccountAddress,
1029
- chainId,
1030
- siweDomain
1031
- });
1032
- if (!tokenEntry) {
1033
- return null;
1034
- }
1035
- return tokenEntry;
1036
- },
1037
- enabled: canBootstrap,
1038
- retry: false,
1039
- refetchOnWindowFocus: false,
1040
- refetchOnReconnect: false
1041
- });
1042
1125
  const clearAuth = react.useCallback(() => {
1043
1126
  if (activeAccountAddress) {
1044
- clearAuthState(queryClient, activeAccountAddress, chainId, address);
1127
+ clearAuthState(activeAccountAddress, chainId, address);
1045
1128
  }
1046
- }, [activeAccountAddress, address, chainId, queryClient]);
1047
- const token = authQuery.data?.token ?? null;
1129
+ }, [activeAccountAddress, address, chainId]);
1130
+ const tokenEntry = authEntry ?? persistedEntry;
1131
+ const token = tokenEntry?.token ?? null;
1048
1132
  return {
1049
1133
  accessToken: token,
1050
- authToken: token,
1051
1134
  isAuthenticated: !!token,
1052
- isLoading: authQuery.isLoading,
1053
- isFetching: authQuery.isFetching,
1054
- error: authQuery.error,
1055
- refresh: refreshAuth,
1056
- refreshAuth,
1135
+ error,
1136
+ signIn,
1137
+ refreshAuth: signIn,
1057
1138
  clear: clearAuth
1058
1139
  };
1059
1140
  }
@@ -1857,7 +1938,6 @@ async function ensureInstantTradeReady(deps, queryClient, request) {
1857
1938
  throw new Error("at least one delegation selector is required");
1858
1939
  }
1859
1940
  const accessToken = getAuthTokenFromRuntimeCache(
1860
- queryClient,
1861
1941
  accountAddress,
1862
1942
  chainId,
1863
1943
  signerAddress
@@ -2267,7 +2347,6 @@ function splitTradeHookArgs(paramsOrOptions, options) {
2267
2347
  }
2268
2348
  function useResolveTradeAuthToken(params = {}) {
2269
2349
  const context = useSymmContext();
2270
- const queryClient = reactQuery.useQueryClient();
2271
2350
  const address = params.address ?? context.address;
2272
2351
  const chainId = params.chainId ?? context.chainId;
2273
2352
  return react.useCallback(
@@ -2281,7 +2360,6 @@ function useResolveTradeAuthToken(params = {}) {
2281
2360
  return null;
2282
2361
  }
2283
2362
  const inMemoryToken = getAuthTokenFromRuntimeCache(
2284
- queryClient,
2285
2363
  resolvedAccountAddress,
2286
2364
  resolvedChainId,
2287
2365
  address
@@ -2291,7 +2369,7 @@ function useResolveTradeAuthToken(params = {}) {
2291
2369
  }
2292
2370
  return null;
2293
2371
  },
2294
- [address, chainId, queryClient]
2372
+ [address, chainId]
2295
2373
  );
2296
2374
  }
2297
2375
 
@@ -26253,7 +26331,6 @@ function useSymmPendingInstantOpens(params) {
26253
26331
  chainId: ctxChainId,
26254
26332
  address
26255
26333
  } = useSymmContext();
26256
- const queryClient = reactQuery.useQueryClient();
26257
26334
  const { accountAddress, authToken: providedAuthToken } = params;
26258
26335
  const chainId = params.chainId ?? ctxChainId;
26259
26336
  const internalEnabled = !!symmCoreClient && !!accountAddress;
@@ -26262,7 +26339,6 @@ function useSymmPendingInstantOpens(params) {
26262
26339
  queryKey: symmKeys.pendingInstantOpens(accountAddress, chainId),
26263
26340
  queryFn: async () => {
26264
26341
  const authToken = providedAuthToken ?? getAuthTokenFromRuntimeCache(
26265
- queryClient,
26266
26342
  accountAddress,
26267
26343
  chainId,
26268
26344
  address