Skip to content

Commit

Permalink
🐛 (SIWE): fix Unknown Error bug
Browse files Browse the repository at this point in the history
  • Loading branch information
nickadamson committed Jan 11, 2024
1 parent ba71c46 commit 717e435
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 72 deletions.
5 changes: 5 additions & 0 deletions .changeset/smooth-rings-breathe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@valorem-labs-inc/react-hooks": patch
---

fix SIWE `Unknown Error` bug
38 changes: 20 additions & 18 deletions src/context/SIWEProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import type { SIWESession } from 'connectkit';
import { SIWEProvider as Provider } from 'connectkit';
import type { PropsWithChildren } from 'react';
import { useMemo } from 'react';
import { SIWEProvider as Provider, type SIWESession } from 'connectkit';
import { type PropsWithChildren, useMemo } from 'react';
import { useAccount } from 'wagmi';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { getSIWEConfig } from '../utils/siwe';
Expand All @@ -25,7 +23,7 @@ export interface SIWEProps extends PropsWithChildren {

// Configuration for SIWE queries.
const siweQueryProps = {
enabled: true,
enabled: false,
refetchInterval: 0,
refetchOnWindowFocus: false,
refetchOnMount: false,
Expand All @@ -47,15 +45,17 @@ export function SIWEProvider({ onSignIn, onSignOut, children }: SIWEProps) {
const authClient = usePromiseClient(Auth);
const queryClient = useQueryClient();

// Queries for nonce, authentication, session, and sign-out.
const nonceQuery = useQuery({
...nonce.useQuery({}),
// Queries for authentication, nonce, session, and sign-out.
const authenticateQuery = useQuery({
...authenticate.useQuery({}),
...siweQueryProps,
enabled: false,
enabled: true,
refetchOnMount: true,
retry: false,
});

const authenticateQuery = useQuery({
...authenticate.useQuery({}),
const nonceQuery = useQuery({
...nonce.useQuery({}),
...siweQueryProps,
});

Expand All @@ -67,11 +67,9 @@ export function SIWEProvider({ onSignIn, onSignOut, children }: SIWEProps) {
const signOutQuery = useQuery({
...signOut.useQuery({}),
...siweQueryProps,
enabled: false,
});

// Configuration for the SIWE process.
const siweConfig = useMemo(() => {
const SIWEConfig = useMemo(() => {
return getSIWEConfig({
authClient,
queryClient,
Expand All @@ -82,6 +80,7 @@ export function SIWEProvider({ onSignIn, onSignOut, children }: SIWEProps) {
address,
logger,
});
// eslint-disable-next-line react-hooks/exhaustive-deps -- don't want to recompute when logger changes
}, [
authClient,
queryClient,
Expand All @@ -90,19 +89,22 @@ export function SIWEProvider({ onSignIn, onSignOut, children }: SIWEProps) {
sessionQuery,
signOutQuery,
address,
logger,
/* logger, */
]);

// Return null while nonce is initially loading.
if (nonceQuery.isInitialLoading) return null;
// wait for authenticate query to finish before mounting SIWEProvider
// this prevents a set-cookie race condition on the auth routes
if (!authenticateQuery.isFetchedAfterMount) {
return null;
}

return (
<Provider
onSignIn={onSignIn}
onSignOut={() => {
onSignOut?.();
}}
{...siweConfig}
{...SIWEConfig}
>
{children}
</Provider>
Expand Down
60 changes: 6 additions & 54 deletions src/utils/siwe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,35 +60,16 @@ export const getSIWEConfig = ({
logger,
}: GetSIWEConfigProps): SIWEConfig => {
const config: SIWEConfig = {
// Indicate whether the SIWE process is enabled.
enabled: true,
// Specify the nonce refetch interval. Set to 0 to prevent creating new sessions.
nonceRefetchInterval: 0,
// Determines the session refetch interval.
sessionRefetchInterval: 60 * 1000 * 2, // 2 minutes
// Determines whether to sign out on account change.
signOutOnAccountChange: true,
// Determines whether to sign out on disconnect.
signOutOnDisconnect: true,
// Determines whether to sign out on network change.
signOutOnNetworkChange: true,
// Provide a message creation function for the SIWE message.
createMessage: createSIWEMessage,

// Returns a promise which, upon resolution, returns the nonce.
async getNonce() {
let nonce: string | undefined = queryClient.getQueryData([
'valorem.trade.v1.Auth',
'Nonce',
]);
if (nonce === undefined) {
logger.debug('Fetching nonce...');
const { data } = await nonceQuery.refetch();
if (data?.nonce === undefined) throw new Error('Could not fetch nonce');
nonce = data.nonce;
}
logger.debug(`Current nonce: ${nonce}`);
return nonce;
logger.debug('Fetching nonce...');
const { data } = await nonceQuery.refetch();
if (data?.nonce === undefined) throw new Error('Could not fetch nonce');
logger.debug(`Current nonce: ${data.nonce}`);
return data.nonce;
},

// Returns a promise which, upon resolution, verifies the contents of the SIWE message.
Expand All @@ -109,16 +90,6 @@ export const getSIWEConfig = ({
logger.debug('Signing out...');
try {
await signOutQuery.refetch();
queryClient.setQueryData(['valorem.trade.v1.Auth', 'Nonce'], undefined);
queryClient.setQueryData(
['valorem.trade.v1.Auth', 'Session'],
undefined,
);
queryClient.setQueryData(
['valorem.trade.v1.Auth', 'Authenticate'],
undefined,
);
queryClient.setQueryData(['valorem.trade.v1.Auth', 'signed-out'], true);
logger.info('Signed out');
return true;
} catch (error) {
Expand All @@ -130,26 +101,6 @@ export const getSIWEConfig = ({
// Returns a promise which, upon await, gets details about the current session.
async getSession() {
logger.debug('Getting session...');
await new Promise((resolve) => {
setTimeout(resolve, 250);
});
if (
queryClient.getQueryData(['valorem.trade.v1.Auth', 'signed-out']) ===
true
) {
logger.debug('User is signed out');
queryClient.setQueryData(
['valorem.trade.v1.Auth', 'signed-out'],
false,
);
return null;
}
queryClient.setQueryData(['valorem.trade.v1.Auth', 'Nonce'], undefined);
queryClient.setQueryData(['valorem.trade.v1.Auth', 'Session'], undefined);
queryClient.setQueryData(
['valorem.trade.v1.Auth', 'Authenticate'],
undefined,
);

// check auth endpoint to ensure session is valid
const { data: authData } = await authenticateQuery.refetch({});
Expand All @@ -162,6 +113,7 @@ export const getSIWEConfig = ({
logger.error('Authorized address does not match connected address');
return null;
}

// get session data
const { data: sessionData } = await sessionQuery.refetch();
if (!sessionData?.address || !sessionData.chainId) {
Expand Down

0 comments on commit 717e435

Please sign in to comment.