Skip to content

Commit e83ffea

Browse files
committed
feat: add baseUrl option
1 parent 816cd7e commit e83ffea

File tree

7 files changed

+75
-26
lines changed

7 files changed

+75
-26
lines changed

src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export { SiweProvider } from "./siweProvider.js";
22
export { getSession, useSession } from "./useSession.js"
33
export { createMessage, getMessageBody, verify, useSignIn } from "./useSignIn.js"
44
export { signOut, useSignOut } from "./useSignOut.js"
5+
export type { UseSiweOptions } from "./types.js"

src/parseOptions.ts

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { UseSiweOptions } from "./types.js"
2+
3+
const defaultOptions: Required<UseSiweOptions> = {
4+
baseUrl: "/api/auth",
5+
}
6+
7+
export const parseOptions = (options: UseSiweOptions = {}) => {
8+
return { ...defaultOptions, ...options };
9+
}

src/siweProvider.tsx

+13-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
22
import React, { createContext, PropsWithChildren } from "react";
3+
import { UseSiweOptions } from "./types.js";
34

4-
export const siweContext = createContext<QueryClient | undefined>(undefined);
5+
export const queryContext = createContext<QueryClient | undefined>(undefined);
6+
export const optionsContext = createContext<UseSiweOptions>({});
57
const queryClient = new QueryClient({
68
defaultOptions: {
79
queries: {
@@ -10,8 +12,14 @@ const queryClient = new QueryClient({
1012
},
1113
});
1214

13-
export const SiweProvider = ({ children }: PropsWithChildren) => (
14-
<QueryClientProvider client={queryClient} context={siweContext}>
15-
{children}
16-
</QueryClientProvider>
15+
type SiweProviderProps = PropsWithChildren & {
16+
options?: UseSiweOptions,
17+
};
18+
19+
export const SiweProvider = ({ children, options = {} }: SiweProviderProps) => (
20+
<optionsContext.Provider value={options}>
21+
<QueryClientProvider client={queryClient} context={queryContext}>
22+
{children}
23+
</QueryClientProvider>
24+
</optionsContext.Provider>
1725
);

src/types.ts

+4
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,7 @@ export type SignInRequest = z.infer<typeof signInRequestSchema>;
3939
export type SignInResponse = string;
4040

4141
export type SignOutResponse = string;
42+
43+
export type UseSiweOptions = {
44+
baseUrl?: string,
45+
};

src/useSession.ts

+10-6
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
import { useQuery } from "@tanstack/react-query";
2-
import { siweContext as context } from "./siweProvider.js";
3-
import { GetSessionResponse } from "./types.js";
2+
import { useContext } from "react";
3+
import { parseOptions } from "./parseOptions.js";
4+
import { queryContext, optionsContext } from "./siweProvider.js";
5+
import { GetSessionResponse, UseSiweOptions } from "./types.js";
46

5-
export const getSession = async () => {
6-
const res = await fetch("/api/auth");
7+
export const getSession = async (options?: UseSiweOptions) => {
8+
const { baseUrl } = parseOptions(options);
9+
const res = await fetch(baseUrl);
710
if (!res.ok) throw new Error(res.statusText);
811
return res.json() as Promise<GetSessionResponse>;
912
}
1013

1114
export const useSession = () => {
15+
const options = useContext(optionsContext);
1216
const { data, ...rest } = useQuery({
1317
queryKey: ["session"],
14-
queryFn: getSession,
15-
context,
18+
queryFn: () => getSession(options),
19+
context: queryContext,
1620
});
1721

1822
return { ...rest, ...data };

src/useSignIn.ts

+25-9
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,26 @@
11
import { useMutation, useQueryClient, UseQueryOptions } from "@tanstack/react-query";
2+
import { useContext } from "react";
23
import { SiweMessage } from "siwe";
34
import { useAccount, useNetwork, useSignMessage } from "wagmi";
4-
import { siweContext as context } from "./siweProvider.js";
5+
import { parseOptions } from "./parseOptions.js";
6+
import { optionsContext, queryContext } from "./siweProvider.js";
7+
import { UseSiweOptions } from "./types.js";
58
import { useSession } from "./useSession.js";
69

710
type UseSignInOptions = Pick<UseQueryOptions<void>, "onSuccess" | "onError">
11+
type MessageArgs = {
12+
address: string,
13+
chainId: number,
14+
nonce: string,
15+
};
16+
type VerifyArgs = {
17+
message: string,
18+
signature: string,
19+
};
820

9-
export const createMessage = (options: { address: string, chainId: number, nonce: string }) =>
21+
export const createMessage = (args: MessageArgs) =>
1022
new SiweMessage({
11-
...options,
23+
...args,
1224
domain: window.location.host,
1325
uri: window.location.origin,
1426
version: "1",
@@ -17,10 +29,11 @@ export const createMessage = (options: { address: string, chainId: number, nonce
1729
export const getMessageBody = ({ message }: { message: SiweMessage }) =>
1830
message.prepareMessage();
1931

20-
export const verify = async ({ message, signature}: { message: string, signature: string }) => {
21-
const res = await fetch("/api/auth/signin", {
32+
export const verify = async (args: VerifyArgs, options?: UseSiweOptions) => {
33+
const { baseUrl } = parseOptions(options);
34+
const res = await fetch(`${baseUrl}/signin`, {
2235
method: "POST",
23-
body: JSON.stringify({ message, signature }),
36+
body: JSON.stringify(args),
2437
});
2538

2639
return res.ok;
@@ -31,14 +44,17 @@ export const useSignIn = ({ onSuccess, onError }: UseSignInOptions = {}) => {
3144
const { chain } = useNetwork();
3245
const { nonce } = useSession();
3346
const { signMessageAsync } = useSignMessage();
34-
const queryClient = useQueryClient({ context });
47+
const queryClient = useQueryClient({
48+
context: queryContext,
49+
});
50+
const options = useContext(optionsContext);
3551

3652
const { mutate, mutateAsync, ...rest } = useMutation(
3753
async () => {
3854
const rawMessage = createMessage({ address, chainId: chain.id, nonce });
3955
const message = getMessageBody({ message: rawMessage });
4056
const signature = await signMessageAsync({ message });
41-
const result = await verify({ message, signature });
57+
const result = await verify({ message, signature }, options);
4258
if (!result) throw new Error("Verification Failed");
4359
},
4460
{
@@ -47,7 +63,7 @@ export const useSignIn = ({ onSuccess, onError }: UseSignInOptions = {}) => {
4763
if (onSuccess) onSuccess();
4864
},
4965
onError,
50-
context,
66+
context: queryContext,
5167
},
5268
);
5369

src/useSignOut.ts

+13-6
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,31 @@
11
import { useMutation, useQueryClient, UseQueryOptions } from "@tanstack/react-query";
2+
import { useContext } from "react";
23
import { useAccount, useDisconnect } from "wagmi";
3-
import { siweContext as context } from "./siweProvider.js";
4+
import { parseOptions } from "./parseOptions.js";
5+
import { optionsContext, queryContext } from "./siweProvider.js";
6+
import { UseSiweOptions } from "./types.js";
47
import { useSession } from "./useSession.js";
58

69
type UseSignOutOptions = Pick<UseQueryOptions<void>, "onSuccess" | "onError">
710

8-
export const signOut = async () => {
9-
const res = await fetch("/api/auth/signout", { method: "POST" });
11+
export const signOut = async (options?: UseSiweOptions) => {
12+
const { baseUrl } = parseOptions(options);
13+
const res = await fetch(`${baseUrl}/signout`, { method: "POST" });
1014
if (!res.ok) throw new Error(res.statusText);
1115
};
1216

1317
export const useSignOut = ({ onSuccess, onError }: UseSignOutOptions = {}) => {
1418
const { authenticated } = useSession();
1519
const { isConnected } = useAccount();
1620
const { disconnectAsync } = useDisconnect();
17-
const queryClient = useQueryClient({ context });
21+
const queryClient = useQueryClient({
22+
context: queryContext,
23+
});
24+
const options = useContext(optionsContext);
1825

1926
const { mutate, mutateAsync, ...rest } = useMutation(
2027
async () => {
21-
if (authenticated) await signOut();
28+
if (authenticated) await signOut(options);
2229
if (isConnected) await disconnectAsync();
2330
},
2431
{
@@ -27,7 +34,7 @@ export const useSignOut = ({ onSuccess, onError }: UseSignOutOptions = {}) => {
2734
if (onSuccess) onSuccess();
2835
},
2936
onError,
30-
context,
37+
context: queryContext,
3138
},
3239
);
3340

0 commit comments

Comments
 (0)