@tuwaio/satellite-siwe-next-auth 1.0.0-fix-test-alpha.42.b314afd → 1.0.0-fix-test-alpha.43.2b6e6fe

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.d.mts CHANGED
@@ -1,3 +1,4 @@
1
+ import { Config } from '@wagmi/core';
1
2
  import * as react from 'react';
2
3
  import { ReactNode } from 'react';
3
4
  import { Address } from 'viem';
@@ -153,6 +154,7 @@ interface UseSiweSignatureResult {
153
154
  * @property {ReactNode} children - Child components.
154
155
  */
155
156
  interface SiweNextAuthProviderProps {
157
+ wagmiConfig: Config;
156
158
  enabled?: boolean;
157
159
  nonceRefetchInterval?: number;
158
160
  onSignIn?: (session?: SIWESession) => void;
@@ -181,7 +183,7 @@ declare function useSiweAuth(options?: {
181
183
  * Internal hook containing the core SIWE/Iron Session logic, acting as the authentication adapter.
182
184
  * @returns {SiweAuthContextType}
183
185
  */
184
- declare function useSiweAuthAdapter({ enabled, nonceRefetchInterval, // 5 minutes (300,000 ms)
186
+ declare function useSiweAuthAdapter({ wagmiConfig, enabled, nonceRefetchInterval, // 5 minutes (300,000 ms)
185
187
  onSignIn: providerOnSignIn, onSignOut: providerOnSignOut, getSiweMessageOptions, }: SiweNextAuthProviderProps): SiweAuthContextType;
186
188
 
187
189
  /**
@@ -193,7 +195,9 @@ onSignIn: providerOnSignIn, onSignOut: providerOnSignOut, getSiweMessageOptions,
193
195
  * * @example
194
196
  * // const { getSiweSignature, isReadyToSign, isRejected } = useSiweSignature();
195
197
  */
196
- declare function useSiweSignature(): UseSiweSignatureResult;
198
+ declare function useSiweSignature({ wagmiConfig }: {
199
+ wagmiConfig: Config;
200
+ }): UseSiweSignatureResult;
197
201
 
198
202
  declare const SiweAuthContext: react.Context<SiweAuthContextType | undefined>;
199
203
 
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { Config } from '@wagmi/core';
1
2
  import * as react from 'react';
2
3
  import { ReactNode } from 'react';
3
4
  import { Address } from 'viem';
@@ -153,6 +154,7 @@ interface UseSiweSignatureResult {
153
154
  * @property {ReactNode} children - Child components.
154
155
  */
155
156
  interface SiweNextAuthProviderProps {
157
+ wagmiConfig: Config;
156
158
  enabled?: boolean;
157
159
  nonceRefetchInterval?: number;
158
160
  onSignIn?: (session?: SIWESession) => void;
@@ -181,7 +183,7 @@ declare function useSiweAuth(options?: {
181
183
  * Internal hook containing the core SIWE/Iron Session logic, acting as the authentication adapter.
182
184
  * @returns {SiweAuthContextType}
183
185
  */
184
- declare function useSiweAuthAdapter({ enabled, nonceRefetchInterval, // 5 minutes (300,000 ms)
186
+ declare function useSiweAuthAdapter({ wagmiConfig, enabled, nonceRefetchInterval, // 5 minutes (300,000 ms)
185
187
  onSignIn: providerOnSignIn, onSignOut: providerOnSignOut, getSiweMessageOptions, }: SiweNextAuthProviderProps): SiweAuthContextType;
186
188
 
187
189
  /**
@@ -193,7 +195,9 @@ onSignIn: providerOnSignIn, onSignOut: providerOnSignOut, getSiweMessageOptions,
193
195
  * * @example
194
196
  * // const { getSiweSignature, isReadyToSign, isRejected } = useSiweSignature();
195
197
  */
196
- declare function useSiweSignature(): UseSiweSignatureResult;
198
+ declare function useSiweSignature({ wagmiConfig }: {
199
+ wagmiConfig: Config;
200
+ }): UseSiweSignatureResult;
197
201
 
198
202
  declare const SiweAuthContext: react.Context<SiweAuthContextType | undefined>;
199
203
 
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var react=require('react'),core=require('@wagmi/core'),wagmi=require('wagmi'),siwe=require('viem/siwe'),jsxRuntime=require('react/jsx-runtime');function L(e,t){let i=react.useRef(e);react.useEffect(()=>{i.current=e;},[e]),react.useEffect(()=>{if(t!==null&&typeof window<"u"&&window.setInterval){let n=window.setInterval(()=>i.current(),t);return ()=>window.clearInterval(n)}},[t]);}var C=react.createContext(void 0);function Se(e){let t=react.useContext(C);if(t===void 0)throw new Error("useSiweAuth must be used within a SiweNextAuthProvider");let i=react.useCallback(async()=>t.signInWithSiwe(e?.onSignIn),[t.signInWithSiwe,e?.onSignIn]),n=react.useCallback(async()=>t.signOutSiwe(e?.onSignOut),[t.signOutSiwe,e?.onSignOut]);return react.useMemo(()=>({...t,signInWithSiwe:i,signOutSiwe:n}),[t,i,n])}async function Y(){return crypto.randomUUID().replace(/-/g,"")}function k(){let e=wagmi.useConfig(),{isConnected:t,address:i,chainId:n}=wagmi.useAccount({config:e}),[p,c]=react.useState(false),f=react.useMemo(()=>t&&!!i&&!!n,[t,i,n]);return react.useEffect(()=>{f&&c(false);},[f]),{getSiweSignature:async a=>{c(false);let u=core.getAccount(e);if(!u.isConnected||!u.address||!u.chainId)throw new Error("Wallet not connected or connection details are missing from Wagmi snapshot.");try{let o=await Y();if(!o)throw new Error("Failed to retrieve CSRF token/nonce.");let d=siwe.createSiweMessage({domain:window.location.host,statement:"Sign in with Ethereum to the application.",uri:window.location.origin,version:"1",...a?a():{},address:u.address,chainId:u.chainId,nonce:o}),h=await core.signMessage(e,{message:d});if(!h)throw c(!0),await core.disconnect(e),new Error("Message signing cancelled by user or failed.");return {message:d,signature:h}}catch(o){await core.disconnect(e),console.error("Error during signature generation:",o);let d=o;throw (d.name==="UserRejectedRequestError"||d.code===4001||/user rejected/i.test(d.message))&&c(true),o}},isReadyToSign:f,isRejected:p}}async function ne(){try{let e=await fetch("/api/siwe/session");if(e.status===401||e.status===404)return {session:void 0,status:"unauthenticated"};if(!e.ok)throw new Error("Failed to fetch session data.");let t=await e.json();return t.isLoggedIn&&t.address&&t.chainId?{session:{address:t.address,chainId:t.chainId},status:"authenticated"}:{session:void 0,status:"unauthenticated"}}catch(e){return console.error("Error fetching session:",e),{session:void 0,status:"unauthenticated"}}}function O({enabled:e=true,nonceRefetchInterval:t=300*1e3,onSignIn:i,onSignOut:n,getSiweMessageOptions:p}){let[c,f]=react.useState(void 0),[g,a]=react.useState("loading"),u=wagmi.useConfig(),{isReadyToSign:o,getSiweSignature:d,isRejected:h}=k(),{address:y,chainId:W,isConnected:v}=wagmi.useAccount({config:u}),[P,T]=react.useState(false),w=g==="authenticated",R=g==="loading",N=c,F=react.useCallback(async()=>{a("loading");let{session:s,status:r}=await ne();return f(s),a(r),s},[]);L(()=>{w&&F();},t);let m=react.useCallback(async s=>{await fetch("/api/siwe/logout",{method:"POST"}),f(void 0),a("unauthenticated"),n?.(),s?.();},[n]),I=react.useCallback(async s=>{if(!e)throw new Error("SIWE is currently disabled via provider configuration.");a("loading");try{let r=await d(p);if(!r){a("unauthenticated");return}let l=await fetch("/api/siwe/login",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:r.message,signature:r.signature})}),S=await l.json();if(!l.ok||S.isLoggedIn!==!0)throw new Error(`Verification error: ${S.message||"Login failed."}`);console.log("SIWE Authentication successful.");let A={address:S.address,chainId:S.chainId};f(A),a("authenticated"),i?.(A),s?.(A);}catch(r){throw await core.disconnect(u),a("unauthenticated"),new Error(`SIWE Sign-In failed: ${r instanceof Error?r.message:"Unknown error"}`)}},[e,d,p,i,u]);return react.useEffect(()=>{if(w&&e){let s=c?.address?.toLowerCase(),r=y?.toLowerCase(),l=c?.chainId,S=W;s&&r&&s!==r||l&&S&&l!==S?(console.log("SIWE: Wallet context changed (Address or Chain ID). Initiating re-authentication."),T(true),m()):!v&&(console.log("SIWE: Wallet disconnected. Disconnecting session."),m(),n?.());}},[w,y,W,v,c,m,e,n]),react.useEffect(()=>{P&&g==="unauthenticated"&&o&&e&&(console.log("SIWE: State reset detected. Attempting automatic sign-in to establish new session."),T(false),I().catch(s=>{throw new Error(`SIWE Auto Sign-In failed after context change: ${s instanceof Error?s.message:"Unknown error"}`)}));},[P,g,o,I,e]),react.useMemo(()=>({data:N,isReadyToSign:o,isRejected:h,isLoading:R,isSignedIn:w,signInWithSiwe:I,signOutSiwe:m,enabled:e}),[N,o,h,R,w,I,m,e])}function Pe(e){let t=O(e);return jsxRuntime.jsx(C.Provider,{value:t,children:e.children})}exports.SiweAuthContext=C;exports.SiweNextAuthProvider=Pe;exports.useInterval=L;exports.useSiweAuth=Se;exports.useSiweAuthAdapter=O;exports.useSiweSignature=k;//# sourceMappingURL=index.js.map
1
+ 'use strict';var react=require('react'),core=require('@wagmi/core'),wagmi=require('wagmi'),siwe=require('viem/siwe'),jsxRuntime=require('react/jsx-runtime');function L(t,e){let r=react.useRef(t);react.useEffect(()=>{r.current=t;},[t]),react.useEffect(()=>{if(e!==null&&typeof window<"u"&&window.setInterval){let a=window.setInterval(()=>r.current(),e);return ()=>window.clearInterval(a)}},[e]);}var x=react.createContext(void 0);function de(t){let e=react.useContext(x);if(e===void 0)throw new Error("useSiweAuth must be used within a SiweNextAuthProvider");let r=react.useCallback(async()=>e.signInWithSiwe(t?.onSignIn),[e.signInWithSiwe,t?.onSignIn]),a=react.useCallback(async()=>e.signOutSiwe(t?.onSignOut),[e.signOutSiwe,t?.onSignOut]);return react.useMemo(()=>({...e,signInWithSiwe:r,signOutSiwe:a}),[e,r,a])}async function X(){return crypto.randomUUID().replace(/-/g,"")}function k({wagmiConfig:t}){let{isConnected:e,address:r,chainId:a}=wagmi.useAccount({config:t}),[h,d]=react.useState(false),u=react.useMemo(()=>e&&!!r&&!!a,[e,r,a]);return react.useEffect(()=>{u&&d(false);},[u]),{getSiweSignature:async S=>{d(false);let n=core.getAccount(t);if(!n.isConnected||!n.address||!n.chainId)throw new Error("Wallet not connected or connection details are missing from Wagmi snapshot.");try{let i=await X();if(!i)throw new Error("Failed to retrieve CSRF token/nonce.");let c=siwe.createSiweMessage({domain:window.location.host,statement:"Sign in with Ethereum to the application.",uri:window.location.origin,version:"1",...S?S():{},address:n.address,chainId:n.chainId,nonce:i}),w=await core.signMessage(t,{message:c});if(!w)throw d(!0),await core.disconnect(t),new Error("Message signing cancelled by user or failed.");return {message:c,signature:w}}catch(i){await core.disconnect(t),console.error("Error during signature generation:",i);let c=i;throw (c.name==="UserRejectedRequestError"||c.code===4001||/user rejected/i.test(c.message))&&d(true),i}},isReadyToSign:u,isRejected:h}}async function ee(){try{let t=await fetch("/api/siwe/session");if(t.status===401||t.status===404)return {session:void 0,status:"unauthenticated"};if(!t.ok)throw new Error("Failed to fetch session data.");let e=await t.json();return e.isLoggedIn&&e.address&&e.chainId?{session:{address:e.address,chainId:e.chainId},status:"authenticated"}:{session:void 0,status:"unauthenticated"}}catch(t){return console.error("Error fetching session:",t),{session:void 0,status:"unauthenticated"}}}function O({wagmiConfig:t,enabled:e=true,nonceRefetchInterval:r=300*1e3,onSignIn:a,onSignOut:h,getSiweMessageOptions:d}){let[u,p]=react.useState(void 0),[S,n]=react.useState("loading"),{isReadyToSign:i,getSiweSignature:c,isRejected:w}=k({wagmiConfig:t}),{address:y,chainId:W,isConnected:v}=wagmi.useAccount({config:t}),[P,T]=react.useState(false),g=S==="authenticated",R=S==="loading",N=u,F=react.useCallback(async()=>{n("loading");let{session:s,status:o}=await ee();return p(s),n(o),s},[]);L(()=>{g&&F();},r);let l=react.useCallback(async s=>{await fetch("/api/siwe/logout",{method:"POST"}),p(void 0),n("unauthenticated"),h?.(),s?.();},[h]),I=react.useCallback(async s=>{if(!e)throw new Error("SIWE is currently disabled via provider configuration.");n("loading");try{let o=await c(d);if(!o){n("unauthenticated");return}let m=await fetch("/api/siwe/login",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:o.message,signature:o.signature})}),f=await m.json();if(!m.ok||f.isLoggedIn!==!0)throw new Error(`Verification error: ${f.message||"Login failed."}`);console.log("SIWE Authentication successful.");let A={address:f.address,chainId:f.chainId};p(A),n("authenticated"),a?.(A),s?.(A);}catch(o){throw await core.disconnect(t),n("unauthenticated"),new Error(`SIWE Sign-In failed: ${o instanceof Error?o.message:"Unknown error"}`)}},[e,c,d,a,t]);return react.useEffect(()=>{if(g&&e){let s=u?.address?.toLowerCase(),o=y?.toLowerCase(),m=u?.chainId,f=W;s&&o&&s!==o||m&&f&&m!==f?(console.log("SIWE: Wallet context changed (Address or Chain ID). Initiating re-authentication."),T(true),l()):!v&&(console.log("SIWE: Wallet disconnected. Disconnecting session."),l(),h?.());}},[g,y,W,v,u,l,e,h]),react.useEffect(()=>{P&&S==="unauthenticated"&&i&&e&&(console.log("SIWE: State reset detected. Attempting automatic sign-in to establish new session."),T(false),I().catch(s=>{throw new Error(`SIWE Auto Sign-In failed after context change: ${s instanceof Error?s.message:"Unknown error"}`)}));},[P,S,i,I,e]),react.useMemo(()=>({data:N,isReadyToSign:i,isRejected:w,isLoading:R,isSignedIn:g,signInWithSiwe:I,signOutSiwe:l,enabled:e}),[N,i,w,R,g,I,l,e])}function ve(t){let e=O(t);return jsxRuntime.jsx(x.Provider,{value:e,children:t.children})}exports.SiweAuthContext=x;exports.SiweNextAuthProvider=ve;exports.useInterval=L;exports.useSiweAuth=de;exports.useSiweAuthAdapter=O;exports.useSiweSignature=k;//# sourceMappingURL=index.js.map
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/useInterval.tsx","../src/provider/SiweAuthContext.tsx","../src/hooks/useSiweAuth.tsx","../src/hooks/useSiweSignature.tsx","../src/hooks/useSiweAuthAdapter.tsx","../src/provider/SiweNextAuthProvider.tsx"],"names":["useInterval","callback","delay","savedCallback","useRef","useEffect","id","SiweAuthContext","createContext","useSiweAuth","options","context","useContext","signInWithSiwe","useCallback","signOutSiwe","useMemo","fetchNonce","useSiweSignature","wagmiConfig","useConfig","isConnected","address","chainId","useAccount","isRejected","setIsRejected","useState","isReadyToSign","customOptions","walletSnapshot","getAccount","nonce","messageToSign","createSiweMessage","signature","signMessage","disconnect","error","err","fetchSession","res","data","useSiweAuthAdapter","enabled","nonceRefetchInterval","providerOnSignIn","providerOnSignOut","getSiweMessageOptions","localSession","setLocalSession","sessionStatus","setSessionStatus","config","getSiweSignature","isSigningInAfterContextChange","setIsSigningInAfterContextChange","isAuthenticated","isAuthenticating","updateSession","session","status","userOnSignOut","userOnSignIn","signatureData","response","responseBody","finalSession","sessionAddress","currentAddress","sessionChainId","currentChainId","e","SiweNextAuthProvider","props","siweAuth","jsx"],"mappings":"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","file":"index.js","sourcesContent":["'use client';\n\nimport { useEffect, useRef } from 'react';\n\n/**\n * @function useInterval\n * Creates a stable interval hook safe for client-side execution.\n */\nexport function useInterval(callback: () => void, delay: number | null) {\n const savedCallback = useRef(callback);\n\n useEffect(() => {\n savedCallback.current = callback;\n }, [callback]);\n\n useEffect(() => {\n if (delay !== null && typeof window !== 'undefined' && window.setInterval) {\n // Use window.setInterval and cast the ID to number to satisfy clearInterval's type\n const id = window.setInterval(() => savedCallback.current(), delay);\n return () => window.clearInterval(id);\n }\n }, [delay]);\n}\n","'use client';\n\nimport { createContext } from 'react';\n\nimport { SiweAuthContextType } from '../types';\n\nexport const SiweAuthContext = createContext<SiweAuthContextType | undefined>(undefined);\n","'use client';\n\nimport { useCallback, useContext, useMemo } from 'react';\n\nimport { SiweAuthContext } from '../provider/SiweAuthContext';\nimport { SiweAuthContextType, SIWESession } from '../types';\n\n/**\n * @function useSiweAuth\n * @description Hook to access the SIWE authentication state and methods.\n * @param {object} [options] - Optional callbacks that override provider-level callbacks.\n * @param {(session?: SIWESession) => void} [options.onSignIn] - Callback executed after a successful sign-in.\n * @param {() => void} [options.onSignOut] - Callback executed after a successful sign-out.\n * @returns {SiweAuthContextType}\n * * @example\n * // const { isSignedIn, signInWithSiwe, data, isRejected } = useSiweAuth();\n */\nexport function useSiweAuth(options?: {\n onSignIn?: (session?: SIWESession) => void;\n onSignOut?: () => void;\n}): SiweAuthContextType {\n const context = useContext(SiweAuthContext);\n if (context === undefined) {\n throw new Error('useSiweAuth must be used within a SiweNextAuthProvider');\n }\n\n // Overrides the context's signOutSiwe/signInWithSiwe with local callbacks\n const signInWithSiwe = useCallback(async () => {\n return context.signInWithSiwe(options?.onSignIn);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [context.signInWithSiwe, options?.onSignIn]);\n\n const signOutSiwe = useCallback(async () => {\n return context.signOutSiwe(options?.onSignOut);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [context.signOutSiwe, options?.onSignOut]);\n\n return useMemo(\n () => ({\n ...context,\n signInWithSiwe,\n signOutSiwe,\n }),\n [context, signInWithSiwe, signOutSiwe],\n );\n}\n","'use client';\n\nimport { disconnect, getAccount, signMessage } from '@wagmi/core';\nimport { useEffect, useMemo, useState } from 'react';\nimport { Address } from 'viem';\nimport { createSiweMessage } from 'viem/siwe';\nimport { useAccount, useConfig } from 'wagmi';\n\nimport { GetSiweMessageOptions, UseSiweSignatureResult } from '../types';\n\n/**\n * @function fetchNonce\n * @description Generates a cryptographically secure, alphanumeric random string to use as the SIWE nonce,\n * satisfying the viem/SIWE requirement (at least 8 chars, alphanumeric).\n * @returns {Promise<string>} The valid alphanumeric nonce string.\n */\nasync function fetchNonce(): Promise<string> {\n // Generate UUID and remove hyphens to create a secure, alphanumeric nonce.\n return crypto.randomUUID().replace(/-/g, '');\n}\n\n/**\n * @function useSiweSignature\n * @description A low-level hook that handles the core SIWE cryptographic flow:\n * getting the nonce, creating the message, and getting the signature using Wagmi/Viem.\n * This is the building block for custom backend authentication.\n * @returns {UseSiweSignatureResult}\n * * @example\n * // const { getSiweSignature, isReadyToSign, isRejected } = useSiweSignature();\n */\nexport function useSiweSignature(): UseSiweSignatureResult {\n const wagmiConfig = useConfig();\n const { isConnected, address, chainId } = useAccount({ config: wagmiConfig });\n const [isRejected, setIsRejected] = useState(false);\n\n const isReadyToSign = useMemo(() => isConnected && !!address && !!chainId, [isConnected, address, chainId]);\n\n // Clear rejected state upon context change\n useEffect(() => {\n if (isReadyToSign) {\n setIsRejected(false);\n }\n }, [isReadyToSign]);\n\n const getSiweSignature = async (customOptions?: GetSiweMessageOptions) => {\n setIsRejected(false); // Reset rejection status at the start of a new attempt\n\n const walletSnapshot = getAccount(wagmiConfig);\n\n if (!walletSnapshot.isConnected || !walletSnapshot.address || !walletSnapshot.chainId) {\n throw new Error('Wallet not connected or connection details are missing from Wagmi snapshot.');\n }\n\n try {\n // Use the corrected fetchNonce\n const nonce = await fetchNonce();\n if (!nonce) throw new Error('Failed to retrieve CSRF token/nonce.');\n\n const messageToSign = createSiweMessage({\n domain: window.location.host,\n statement: 'Sign in with Ethereum to the application.',\n uri: window.location.origin,\n version: '1',\n ...(customOptions ? customOptions() : {}), // Apply custom options\n address: walletSnapshot.address,\n chainId: walletSnapshot.chainId,\n nonce,\n });\n\n const signature = await signMessage(wagmiConfig, { message: messageToSign });\n\n if (!signature) {\n setIsRejected(true); // Set rejected status if signature is null/undefined\n await disconnect(wagmiConfig);\n throw new Error('Message signing cancelled by user or failed.');\n }\n\n return { message: messageToSign, signature: signature as Address };\n } catch (error) {\n await disconnect(wagmiConfig);\n console.error('Error during signature generation:', error);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const err = error as any;\n if (err.name === 'UserRejectedRequestError' || err.code === 4001 || /user rejected/i.test(err.message)) {\n setIsRejected(true);\n }\n throw error;\n }\n };\n\n return { getSiweSignature, isReadyToSign, isRejected };\n}\n","'use client';\n\nimport { disconnect } from '@wagmi/core';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useAccount, useConfig } from 'wagmi';\n\nimport { SiweAuthContextType, SiweNextAuthProviderProps, SIWESession } from '../types';\nimport { useInterval } from './useInterval';\nimport { useSiweSignature } from './useSiweSignature';\n\ntype SessionStatus = 'loading' | 'authenticated' | 'unauthenticated';\n\n/**\n * @function fetchSession\n * @description Fetches the current session status and data from the server.\n * @returns {Promise<{session: SIWESession | undefined, status: SessionStatus}>}\n */\nasync function fetchSession(): Promise<{ session: SIWESession | undefined; status: SessionStatus }> {\n try {\n const res = await fetch('/api/siwe/session');\n\n if (res.status === 401 || res.status === 404) {\n return { session: undefined, status: 'unauthenticated' };\n }\n\n if (!res.ok) {\n throw new Error('Failed to fetch session data.');\n }\n\n const data = await res.json();\n\n // NOTE: Data structure must match SiweSessionData {isLoggedIn, address, chainId}\n if (data.isLoggedIn && data.address && data.chainId) {\n return {\n session: { address: data.address, chainId: data.chainId },\n status: 'authenticated',\n };\n }\n return { session: undefined, status: 'unauthenticated' };\n } catch (e) {\n console.error('Error fetching session:', e);\n return { session: undefined, status: 'unauthenticated' };\n }\n}\n\n/**\n * @function useSiweAuthAdapter\n * Internal hook containing the core SIWE/Iron Session logic, acting as the authentication adapter.\n * @returns {SiweAuthContextType}\n */\nexport function useSiweAuthAdapter({\n enabled = true,\n nonceRefetchInterval = 5 * 60 * 1000, // 5 minutes (300,000 ms)\n onSignIn: providerOnSignIn,\n onSignOut: providerOnSignOut,\n getSiweMessageOptions,\n}: SiweNextAuthProviderProps): SiweAuthContextType {\n const [localSession, setLocalSession] = useState<SIWESession | undefined>(undefined);\n const [sessionStatus, setSessionStatus] = useState<SessionStatus>('loading');\n\n const config = useConfig();\n const { isReadyToSign, getSiweSignature, isRejected } = useSiweSignature();\n\n const { address, chainId, isConnected } = useAccount({ config });\n\n const [isSigningInAfterContextChange, setIsSigningInAfterContextChange] = useState(false);\n\n const isAuthenticated = sessionStatus === 'authenticated';\n const isAuthenticating = sessionStatus === 'loading';\n const data: SIWESession | undefined = localSession;\n\n // --- SESSION REFETCH (equivalent to NextAuth's update) ---\n const updateSession = useCallback(async () => {\n setSessionStatus('loading');\n const { session, status } = await fetchSession();\n setLocalSession(session);\n setSessionStatus(status);\n return session;\n }, []);\n\n // --- NONCE REFETCH LOGIC (Managed by custom interval) ---\n useInterval(() => {\n if (isAuthenticated) {\n updateSession();\n }\n }, nonceRefetchInterval);\n\n /**\n * @async\n * @method signOutSiwe\n * Clears the session by calling the server API.\n */\n const signOutSiwe = useCallback(\n async (userOnSignOut?: () => void) => {\n await fetch('/api/siwe/logout', { method: 'POST' }); // Call your custom logout API\n setLocalSession(undefined);\n setSessionStatus('unauthenticated');\n\n providerOnSignOut?.(); // Execute provider callback\n userOnSignOut?.(); // Execute user callback\n },\n [providerOnSignOut],\n );\n\n /**\n * @async\n * @method signInWithSiwe\n * Executes the full SIWE authentication flow: signature -> verification -> session creation.\n */\n const signInWithSiwe = useCallback(\n async (userOnSignIn?: (session?: SIWESession) => void) => {\n if (!enabled) {\n throw new Error('SIWE is currently disabled via provider configuration.');\n }\n\n setSessionStatus('loading');\n\n try {\n // 1. Get Signature using the low-level hook\n const signatureData = await getSiweSignature(getSiweMessageOptions);\n\n if (!signatureData) {\n setSessionStatus('unauthenticated');\n return;\n }\n\n // 2. Send message and signature to your custom login API\n const response = await fetch('/api/siwe/login', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n message: signatureData.message,\n signature: signatureData.signature,\n }),\n });\n\n const responseBody = await response.json();\n\n if (!response.ok || responseBody.isLoggedIn !== true) {\n throw new Error(`Verification error: ${responseBody.message || 'Login failed.'}`);\n }\n\n console.log('SIWE Authentication successful.');\n\n // 3. Update session locally\n const finalSession: SIWESession = {\n address: responseBody.address,\n chainId: responseBody.chainId,\n };\n\n setLocalSession(finalSession);\n setSessionStatus('authenticated');\n\n // 4. Execute callbacks after successful sign-in\n providerOnSignIn?.(finalSession);\n userOnSignIn?.(finalSession);\n } catch (error) {\n await disconnect(config);\n setSessionStatus('unauthenticated');\n throw new Error(`SIWE Sign-In failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n },\n [enabled, getSiweSignature, getSiweMessageOptions, providerOnSignIn, config],\n );\n\n // --- OBLIGATORY SESSION RESET / AUTO-SIGN IN EFFECT ---\n\n useEffect(() => {\n if (isAuthenticated && enabled) {\n const sessionAddress = localSession?.address?.toLowerCase();\n const currentAddress = address?.toLowerCase();\n const sessionChainId = localSession?.chainId;\n const currentChainId = chainId;\n\n const addressChanged = sessionAddress && currentAddress && sessionAddress !== currentAddress;\n const chainChanged = sessionChainId && currentChainId && sessionChainId !== currentChainId;\n const walletDisconnected = !isConnected;\n\n if (addressChanged || chainChanged) {\n console.log('SIWE: Wallet context changed (Address or Chain ID). Initiating re-authentication.');\n\n setIsSigningInAfterContextChange(true);\n\n // 1. OBLIGATORY SIGN OUT for the old session (security)\n signOutSiwe();\n } else if (walletDisconnected) {\n // Handle explicit wallet disconnection: Always sign out.\n console.log('SIWE: Wallet disconnected. Disconnecting session.');\n signOutSiwe();\n providerOnSignOut?.(); // Execute provider callback for disconnect\n }\n }\n }, [isAuthenticated, address, chainId, isConnected, localSession, signOutSiwe, enabled, providerOnSignOut]);\n\n // --- EFFECT TO EXECUTE AUTO SIGN-IN AFTER STATE RESET ---\n useEffect(() => {\n // Triggers when: 1. Flag is set AND 2. Status transitioned to 'unauthenticated'\n if (isSigningInAfterContextChange && sessionStatus === 'unauthenticated' && isReadyToSign && enabled) {\n console.log('SIWE: State reset detected. Attempting automatic sign-in to establish new session.');\n\n setIsSigningInAfterContextChange(false); // Reset flag\n\n // Auto sign-in execution\n signInWithSiwe().catch((e) => {\n throw new Error(\n `SIWE Auto Sign-In failed after context change: ${e instanceof Error ? e.message : 'Unknown error'}`,\n );\n });\n }\n }, [isSigningInAfterContextChange, sessionStatus, isReadyToSign, signInWithSiwe, enabled]);\n\n // --- FINAL EXPORT ---\n\n return useMemo(\n () => ({\n data,\n isReadyToSign,\n isRejected,\n isLoading: isAuthenticating,\n isSignedIn: isAuthenticated,\n signInWithSiwe,\n signOutSiwe,\n enabled,\n }),\n [data, isReadyToSign, isRejected, isAuthenticating, isAuthenticated, signInWithSiwe, signOutSiwe, enabled],\n );\n}\n","'use client';\n\nimport { useSiweAuthAdapter } from '../hooks/useSiweAuthAdapter';\nimport { SiweNextAuthProviderProps } from '../types';\nimport { SiweAuthContext } from './SiweAuthContext';\n\n/**\n * @component\n * @name SiweNextAuthProvider\n * @description Universal Provider for Sign-In with Ethereum (SIWE) using NextAuth.js.\n * This component handles the SIWE authentication logic.\n * It must be nested inside NextAuth's `<SessionProvider>` and your Wagmi Provider.\n * * **Note**: This provider requires the server-side NextAuth configuration to be set up.\n */\nexport function SiweNextAuthProvider(props: SiweNextAuthProviderProps) {\n const siweAuth = useSiweAuthAdapter(props);\n return <SiweAuthContext.Provider value={siweAuth}>{props.children}</SiweAuthContext.Provider>;\n}\n"]}
1
+ {"version":3,"sources":["../src/hooks/useInterval.tsx","../src/provider/SiweAuthContext.tsx","../src/hooks/useSiweAuth.tsx","../src/hooks/useSiweSignature.tsx","../src/hooks/useSiweAuthAdapter.tsx","../src/provider/SiweNextAuthProvider.tsx"],"names":["useInterval","callback","delay","savedCallback","useRef","useEffect","id","SiweAuthContext","createContext","useSiweAuth","options","context","useContext","signInWithSiwe","useCallback","signOutSiwe","useMemo","fetchNonce","useSiweSignature","wagmiConfig","isConnected","address","chainId","useAccount","isRejected","setIsRejected","useState","isReadyToSign","customOptions","walletSnapshot","getAccount","nonce","messageToSign","createSiweMessage","signature","signMessage","disconnect","error","err","fetchSession","res","data","e","useSiweAuthAdapter","enabled","nonceRefetchInterval","providerOnSignIn","providerOnSignOut","getSiweMessageOptions","localSession","setLocalSession","sessionStatus","setSessionStatus","getSiweSignature","isSigningInAfterContextChange","setIsSigningInAfterContextChange","isAuthenticated","isAuthenticating","updateSession","session","status","userOnSignOut","userOnSignIn","signatureData","response","responseBody","finalSession","sessionAddress","currentAddress","sessionChainId","currentChainId","SiweNextAuthProvider","props","siweAuth","jsx"],"mappings":"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","file":"index.js","sourcesContent":["'use client';\n\nimport { useEffect, useRef } from 'react';\n\n/**\n * @function useInterval\n * Creates a stable interval hook safe for client-side execution.\n */\nexport function useInterval(callback: () => void, delay: number | null) {\n const savedCallback = useRef(callback);\n\n useEffect(() => {\n savedCallback.current = callback;\n }, [callback]);\n\n useEffect(() => {\n if (delay !== null && typeof window !== 'undefined' && window.setInterval) {\n // Use window.setInterval and cast the ID to number to satisfy clearInterval's type\n const id = window.setInterval(() => savedCallback.current(), delay);\n return () => window.clearInterval(id);\n }\n }, [delay]);\n}\n","'use client';\n\nimport { createContext } from 'react';\n\nimport { SiweAuthContextType } from '../types';\n\nexport const SiweAuthContext = createContext<SiweAuthContextType | undefined>(undefined);\n","'use client';\n\nimport { useCallback, useContext, useMemo } from 'react';\n\nimport { SiweAuthContext } from '../provider/SiweAuthContext';\nimport { SiweAuthContextType, SIWESession } from '../types';\n\n/**\n * @function useSiweAuth\n * @description Hook to access the SIWE authentication state and methods.\n * @param {object} [options] - Optional callbacks that override provider-level callbacks.\n * @param {(session?: SIWESession) => void} [options.onSignIn] - Callback executed after a successful sign-in.\n * @param {() => void} [options.onSignOut] - Callback executed after a successful sign-out.\n * @returns {SiweAuthContextType}\n * * @example\n * // const { isSignedIn, signInWithSiwe, data, isRejected } = useSiweAuth();\n */\nexport function useSiweAuth(options?: {\n onSignIn?: (session?: SIWESession) => void;\n onSignOut?: () => void;\n}): SiweAuthContextType {\n const context = useContext(SiweAuthContext);\n if (context === undefined) {\n throw new Error('useSiweAuth must be used within a SiweNextAuthProvider');\n }\n\n // Overrides the context's signOutSiwe/signInWithSiwe with local callbacks\n const signInWithSiwe = useCallback(async () => {\n return context.signInWithSiwe(options?.onSignIn);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [context.signInWithSiwe, options?.onSignIn]);\n\n const signOutSiwe = useCallback(async () => {\n return context.signOutSiwe(options?.onSignOut);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [context.signOutSiwe, options?.onSignOut]);\n\n return useMemo(\n () => ({\n ...context,\n signInWithSiwe,\n signOutSiwe,\n }),\n [context, signInWithSiwe, signOutSiwe],\n );\n}\n","'use client';\n\nimport { Config, disconnect, getAccount, signMessage } from '@wagmi/core';\nimport { useEffect, useMemo, useState } from 'react';\nimport { Address } from 'viem';\nimport { createSiweMessage } from 'viem/siwe';\nimport { useAccount } from 'wagmi';\n\nimport { GetSiweMessageOptions, UseSiweSignatureResult } from '../types';\n\n/**\n * @function fetchNonce\n * @description Generates a cryptographically secure, alphanumeric random string to use as the SIWE nonce,\n * satisfying the viem/SIWE requirement (at least 8 chars, alphanumeric).\n * @returns {Promise<string>} The valid alphanumeric nonce string.\n */\nasync function fetchNonce(): Promise<string> {\n // Generate UUID and remove hyphens to create a secure, alphanumeric nonce.\n return crypto.randomUUID().replace(/-/g, '');\n}\n\n/**\n * @function useSiweSignature\n * @description A low-level hook that handles the core SIWE cryptographic flow:\n * getting the nonce, creating the message, and getting the signature using Wagmi/Viem.\n * This is the building block for custom backend authentication.\n * @returns {UseSiweSignatureResult}\n * * @example\n * // const { getSiweSignature, isReadyToSign, isRejected } = useSiweSignature();\n */\nexport function useSiweSignature({ wagmiConfig }: { wagmiConfig: Config }): UseSiweSignatureResult {\n const { isConnected, address, chainId } = useAccount({ config: wagmiConfig });\n const [isRejected, setIsRejected] = useState(false);\n\n const isReadyToSign = useMemo(() => isConnected && !!address && !!chainId, [isConnected, address, chainId]);\n\n // Clear rejected state upon context change\n useEffect(() => {\n if (isReadyToSign) {\n setIsRejected(false);\n }\n }, [isReadyToSign]);\n\n const getSiweSignature = async (customOptions?: GetSiweMessageOptions) => {\n setIsRejected(false); // Reset rejection status at the start of a new attempt\n\n const walletSnapshot = getAccount(wagmiConfig);\n\n if (!walletSnapshot.isConnected || !walletSnapshot.address || !walletSnapshot.chainId) {\n throw new Error('Wallet not connected or connection details are missing from Wagmi snapshot.');\n }\n\n try {\n // Use the corrected fetchNonce\n const nonce = await fetchNonce();\n if (!nonce) throw new Error('Failed to retrieve CSRF token/nonce.');\n\n const messageToSign = createSiweMessage({\n domain: window.location.host,\n statement: 'Sign in with Ethereum to the application.',\n uri: window.location.origin,\n version: '1',\n ...(customOptions ? customOptions() : {}), // Apply custom options\n address: walletSnapshot.address,\n chainId: walletSnapshot.chainId,\n nonce,\n });\n\n const signature = await signMessage(wagmiConfig, { message: messageToSign });\n\n if (!signature) {\n setIsRejected(true); // Set rejected status if signature is null/undefined\n await disconnect(wagmiConfig);\n throw new Error('Message signing cancelled by user or failed.');\n }\n\n return { message: messageToSign, signature: signature as Address };\n } catch (error) {\n await disconnect(wagmiConfig);\n console.error('Error during signature generation:', error);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const err = error as any;\n if (err.name === 'UserRejectedRequestError' || err.code === 4001 || /user rejected/i.test(err.message)) {\n setIsRejected(true);\n }\n throw error;\n }\n };\n\n return { getSiweSignature, isReadyToSign, isRejected };\n}\n","'use client';\n\nimport { disconnect } from '@wagmi/core';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useAccount } from 'wagmi';\n\nimport { SiweAuthContextType, SiweNextAuthProviderProps, SIWESession } from '../types';\nimport { useInterval } from './useInterval';\nimport { useSiweSignature } from './useSiweSignature';\n\ntype SessionStatus = 'loading' | 'authenticated' | 'unauthenticated';\n\n/**\n * @function fetchSession\n * @description Fetches the current session status and data from the server.\n * @returns {Promise<{session: SIWESession | undefined, status: SessionStatus}>}\n */\nasync function fetchSession(): Promise<{ session: SIWESession | undefined; status: SessionStatus }> {\n try {\n const res = await fetch('/api/siwe/session');\n\n if (res.status === 401 || res.status === 404) {\n return { session: undefined, status: 'unauthenticated' };\n }\n\n if (!res.ok) {\n throw new Error('Failed to fetch session data.');\n }\n\n const data = await res.json();\n\n // NOTE: Data structure must match SiweSessionData {isLoggedIn, address, chainId}\n if (data.isLoggedIn && data.address && data.chainId) {\n return {\n session: { address: data.address, chainId: data.chainId },\n status: 'authenticated',\n };\n }\n return { session: undefined, status: 'unauthenticated' };\n } catch (e) {\n console.error('Error fetching session:', e);\n return { session: undefined, status: 'unauthenticated' };\n }\n}\n\n/**\n * @function useSiweAuthAdapter\n * Internal hook containing the core SIWE/Iron Session logic, acting as the authentication adapter.\n * @returns {SiweAuthContextType}\n */\nexport function useSiweAuthAdapter({\n wagmiConfig,\n enabled = true,\n nonceRefetchInterval = 5 * 60 * 1000, // 5 minutes (300,000 ms)\n onSignIn: providerOnSignIn,\n onSignOut: providerOnSignOut,\n getSiweMessageOptions,\n}: SiweNextAuthProviderProps): SiweAuthContextType {\n const [localSession, setLocalSession] = useState<SIWESession | undefined>(undefined);\n const [sessionStatus, setSessionStatus] = useState<SessionStatus>('loading');\n\n const { isReadyToSign, getSiweSignature, isRejected } = useSiweSignature({ wagmiConfig });\n\n const { address, chainId, isConnected } = useAccount({ config: wagmiConfig });\n\n const [isSigningInAfterContextChange, setIsSigningInAfterContextChange] = useState(false);\n\n const isAuthenticated = sessionStatus === 'authenticated';\n const isAuthenticating = sessionStatus === 'loading';\n const data: SIWESession | undefined = localSession;\n\n // --- SESSION REFETCH (equivalent to NextAuth's update) ---\n const updateSession = useCallback(async () => {\n setSessionStatus('loading');\n const { session, status } = await fetchSession();\n setLocalSession(session);\n setSessionStatus(status);\n return session;\n }, []);\n\n // --- NONCE REFETCH LOGIC (Managed by custom interval) ---\n useInterval(() => {\n if (isAuthenticated) {\n updateSession();\n }\n }, nonceRefetchInterval);\n\n /**\n * @async\n * @method signOutSiwe\n * Clears the session by calling the server API.\n */\n const signOutSiwe = useCallback(\n async (userOnSignOut?: () => void) => {\n await fetch('/api/siwe/logout', { method: 'POST' }); // Call your custom logout API\n setLocalSession(undefined);\n setSessionStatus('unauthenticated');\n\n providerOnSignOut?.(); // Execute provider callback\n userOnSignOut?.(); // Execute user callback\n },\n [providerOnSignOut],\n );\n\n /**\n * @async\n * @method signInWithSiwe\n * Executes the full SIWE authentication flow: signature -> verification -> session creation.\n */\n const signInWithSiwe = useCallback(\n async (userOnSignIn?: (session?: SIWESession) => void) => {\n if (!enabled) {\n throw new Error('SIWE is currently disabled via provider configuration.');\n }\n\n setSessionStatus('loading');\n\n try {\n // 1. Get Signature using the low-level hook\n const signatureData = await getSiweSignature(getSiweMessageOptions);\n\n if (!signatureData) {\n setSessionStatus('unauthenticated');\n return;\n }\n\n // 2. Send message and signature to your custom login API\n const response = await fetch('/api/siwe/login', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n message: signatureData.message,\n signature: signatureData.signature,\n }),\n });\n\n const responseBody = await response.json();\n\n if (!response.ok || responseBody.isLoggedIn !== true) {\n throw new Error(`Verification error: ${responseBody.message || 'Login failed.'}`);\n }\n\n console.log('SIWE Authentication successful.');\n\n // 3. Update session locally\n const finalSession: SIWESession = {\n address: responseBody.address,\n chainId: responseBody.chainId,\n };\n\n setLocalSession(finalSession);\n setSessionStatus('authenticated');\n\n // 4. Execute callbacks after successful sign-in\n providerOnSignIn?.(finalSession);\n userOnSignIn?.(finalSession);\n } catch (error) {\n await disconnect(wagmiConfig);\n setSessionStatus('unauthenticated');\n throw new Error(`SIWE Sign-In failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n },\n [enabled, getSiweSignature, getSiweMessageOptions, providerOnSignIn, wagmiConfig],\n );\n\n // --- OBLIGATORY SESSION RESET / AUTO-SIGN IN EFFECT ---\n\n useEffect(() => {\n if (isAuthenticated && enabled) {\n const sessionAddress = localSession?.address?.toLowerCase();\n const currentAddress = address?.toLowerCase();\n const sessionChainId = localSession?.chainId;\n const currentChainId = chainId;\n\n const addressChanged = sessionAddress && currentAddress && sessionAddress !== currentAddress;\n const chainChanged = sessionChainId && currentChainId && sessionChainId !== currentChainId;\n const walletDisconnected = !isConnected;\n\n if (addressChanged || chainChanged) {\n console.log('SIWE: Wallet context changed (Address or Chain ID). Initiating re-authentication.');\n\n setIsSigningInAfterContextChange(true);\n\n // 1. OBLIGATORY SIGN OUT for the old session (security)\n signOutSiwe();\n } else if (walletDisconnected) {\n // Handle explicit wallet disconnection: Always sign out.\n console.log('SIWE: Wallet disconnected. Disconnecting session.');\n signOutSiwe();\n providerOnSignOut?.(); // Execute provider callback for disconnect\n }\n }\n }, [isAuthenticated, address, chainId, isConnected, localSession, signOutSiwe, enabled, providerOnSignOut]);\n\n // --- EFFECT TO EXECUTE AUTO SIGN-IN AFTER STATE RESET ---\n useEffect(() => {\n // Triggers when: 1. Flag is set AND 2. Status transitioned to 'unauthenticated'\n if (isSigningInAfterContextChange && sessionStatus === 'unauthenticated' && isReadyToSign && enabled) {\n console.log('SIWE: State reset detected. Attempting automatic sign-in to establish new session.');\n\n setIsSigningInAfterContextChange(false); // Reset flag\n\n // Auto sign-in execution\n signInWithSiwe().catch((e) => {\n throw new Error(\n `SIWE Auto Sign-In failed after context change: ${e instanceof Error ? e.message : 'Unknown error'}`,\n );\n });\n }\n }, [isSigningInAfterContextChange, sessionStatus, isReadyToSign, signInWithSiwe, enabled]);\n\n // --- FINAL EXPORT ---\n\n return useMemo(\n () => ({\n data,\n isReadyToSign,\n isRejected,\n isLoading: isAuthenticating,\n isSignedIn: isAuthenticated,\n signInWithSiwe,\n signOutSiwe,\n enabled,\n }),\n [data, isReadyToSign, isRejected, isAuthenticating, isAuthenticated, signInWithSiwe, signOutSiwe, enabled],\n );\n}\n","'use client';\n\nimport { useSiweAuthAdapter } from '../hooks/useSiweAuthAdapter';\nimport { SiweNextAuthProviderProps } from '../types';\nimport { SiweAuthContext } from './SiweAuthContext';\n\n/**\n * @component\n * @name SiweNextAuthProvider\n * @description Universal Provider for Sign-In with Ethereum (SIWE) using NextAuth.js.\n * This component handles the SIWE authentication logic.\n * It must be nested inside NextAuth's `<SessionProvider>` and your Wagmi Provider.\n * * **Note**: This provider requires the server-side NextAuth configuration to be set up.\n */\nexport function SiweNextAuthProvider(props: SiweNextAuthProviderProps) {\n const siweAuth = useSiweAuthAdapter(props);\n return <SiweAuthContext.Provider value={siweAuth}>{props.children}</SiweAuthContext.Provider>;\n}\n"]}
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import {createContext,useRef,useEffect,useContext,useCallback,useMemo,useState}from'react';import {getAccount,signMessage,disconnect}from'@wagmi/core';import {useConfig,useAccount}from'wagmi';import {createSiweMessage}from'viem/siwe';import {jsx}from'react/jsx-runtime';function L(e,t){let i=useRef(e);useEffect(()=>{i.current=e;},[e]),useEffect(()=>{if(t!==null&&typeof window<"u"&&window.setInterval){let n=window.setInterval(()=>i.current(),t);return ()=>window.clearInterval(n)}},[t]);}var C=createContext(void 0);function Se(e){let t=useContext(C);if(t===void 0)throw new Error("useSiweAuth must be used within a SiweNextAuthProvider");let i=useCallback(async()=>t.signInWithSiwe(e?.onSignIn),[t.signInWithSiwe,e?.onSignIn]),n=useCallback(async()=>t.signOutSiwe(e?.onSignOut),[t.signOutSiwe,e?.onSignOut]);return useMemo(()=>({...t,signInWithSiwe:i,signOutSiwe:n}),[t,i,n])}async function Y(){return crypto.randomUUID().replace(/-/g,"")}function k(){let e=useConfig(),{isConnected:t,address:i,chainId:n}=useAccount({config:e}),[p,c]=useState(false),f=useMemo(()=>t&&!!i&&!!n,[t,i,n]);return useEffect(()=>{f&&c(false);},[f]),{getSiweSignature:async a=>{c(false);let u=getAccount(e);if(!u.isConnected||!u.address||!u.chainId)throw new Error("Wallet not connected or connection details are missing from Wagmi snapshot.");try{let o=await Y();if(!o)throw new Error("Failed to retrieve CSRF token/nonce.");let d=createSiweMessage({domain:window.location.host,statement:"Sign in with Ethereum to the application.",uri:window.location.origin,version:"1",...a?a():{},address:u.address,chainId:u.chainId,nonce:o}),h=await signMessage(e,{message:d});if(!h)throw c(!0),await disconnect(e),new Error("Message signing cancelled by user or failed.");return {message:d,signature:h}}catch(o){await disconnect(e),console.error("Error during signature generation:",o);let d=o;throw (d.name==="UserRejectedRequestError"||d.code===4001||/user rejected/i.test(d.message))&&c(true),o}},isReadyToSign:f,isRejected:p}}async function ne(){try{let e=await fetch("/api/siwe/session");if(e.status===401||e.status===404)return {session:void 0,status:"unauthenticated"};if(!e.ok)throw new Error("Failed to fetch session data.");let t=await e.json();return t.isLoggedIn&&t.address&&t.chainId?{session:{address:t.address,chainId:t.chainId},status:"authenticated"}:{session:void 0,status:"unauthenticated"}}catch(e){return console.error("Error fetching session:",e),{session:void 0,status:"unauthenticated"}}}function O({enabled:e=true,nonceRefetchInterval:t=300*1e3,onSignIn:i,onSignOut:n,getSiweMessageOptions:p}){let[c,f]=useState(void 0),[g,a]=useState("loading"),u=useConfig(),{isReadyToSign:o,getSiweSignature:d,isRejected:h}=k(),{address:y,chainId:W,isConnected:v}=useAccount({config:u}),[P,T]=useState(false),w=g==="authenticated",R=g==="loading",N=c,F=useCallback(async()=>{a("loading");let{session:s,status:r}=await ne();return f(s),a(r),s},[]);L(()=>{w&&F();},t);let m=useCallback(async s=>{await fetch("/api/siwe/logout",{method:"POST"}),f(void 0),a("unauthenticated"),n?.(),s?.();},[n]),I=useCallback(async s=>{if(!e)throw new Error("SIWE is currently disabled via provider configuration.");a("loading");try{let r=await d(p);if(!r){a("unauthenticated");return}let l=await fetch("/api/siwe/login",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:r.message,signature:r.signature})}),S=await l.json();if(!l.ok||S.isLoggedIn!==!0)throw new Error(`Verification error: ${S.message||"Login failed."}`);console.log("SIWE Authentication successful.");let A={address:S.address,chainId:S.chainId};f(A),a("authenticated"),i?.(A),s?.(A);}catch(r){throw await disconnect(u),a("unauthenticated"),new Error(`SIWE Sign-In failed: ${r instanceof Error?r.message:"Unknown error"}`)}},[e,d,p,i,u]);return useEffect(()=>{if(w&&e){let s=c?.address?.toLowerCase(),r=y?.toLowerCase(),l=c?.chainId,S=W;s&&r&&s!==r||l&&S&&l!==S?(console.log("SIWE: Wallet context changed (Address or Chain ID). Initiating re-authentication."),T(true),m()):!v&&(console.log("SIWE: Wallet disconnected. Disconnecting session."),m(),n?.());}},[w,y,W,v,c,m,e,n]),useEffect(()=>{P&&g==="unauthenticated"&&o&&e&&(console.log("SIWE: State reset detected. Attempting automatic sign-in to establish new session."),T(false),I().catch(s=>{throw new Error(`SIWE Auto Sign-In failed after context change: ${s instanceof Error?s.message:"Unknown error"}`)}));},[P,g,o,I,e]),useMemo(()=>({data:N,isReadyToSign:o,isRejected:h,isLoading:R,isSignedIn:w,signInWithSiwe:I,signOutSiwe:m,enabled:e}),[N,o,h,R,w,I,m,e])}function Pe(e){let t=O(e);return jsx(C.Provider,{value:t,children:e.children})}export{C as SiweAuthContext,Pe as SiweNextAuthProvider,L as useInterval,Se as useSiweAuth,O as useSiweAuthAdapter,k as useSiweSignature};//# sourceMappingURL=index.mjs.map
1
+ import {createContext,useRef,useEffect,useContext,useCallback,useMemo,useState}from'react';import {getAccount,signMessage,disconnect}from'@wagmi/core';import {useAccount}from'wagmi';import {createSiweMessage}from'viem/siwe';import {jsx}from'react/jsx-runtime';function L(t,e){let r=useRef(t);useEffect(()=>{r.current=t;},[t]),useEffect(()=>{if(e!==null&&typeof window<"u"&&window.setInterval){let a=window.setInterval(()=>r.current(),e);return ()=>window.clearInterval(a)}},[e]);}var x=createContext(void 0);function de(t){let e=useContext(x);if(e===void 0)throw new Error("useSiweAuth must be used within a SiweNextAuthProvider");let r=useCallback(async()=>e.signInWithSiwe(t?.onSignIn),[e.signInWithSiwe,t?.onSignIn]),a=useCallback(async()=>e.signOutSiwe(t?.onSignOut),[e.signOutSiwe,t?.onSignOut]);return useMemo(()=>({...e,signInWithSiwe:r,signOutSiwe:a}),[e,r,a])}async function X(){return crypto.randomUUID().replace(/-/g,"")}function k({wagmiConfig:t}){let{isConnected:e,address:r,chainId:a}=useAccount({config:t}),[h,d]=useState(false),u=useMemo(()=>e&&!!r&&!!a,[e,r,a]);return useEffect(()=>{u&&d(false);},[u]),{getSiweSignature:async S=>{d(false);let n=getAccount(t);if(!n.isConnected||!n.address||!n.chainId)throw new Error("Wallet not connected or connection details are missing from Wagmi snapshot.");try{let i=await X();if(!i)throw new Error("Failed to retrieve CSRF token/nonce.");let c=createSiweMessage({domain:window.location.host,statement:"Sign in with Ethereum to the application.",uri:window.location.origin,version:"1",...S?S():{},address:n.address,chainId:n.chainId,nonce:i}),w=await signMessage(t,{message:c});if(!w)throw d(!0),await disconnect(t),new Error("Message signing cancelled by user or failed.");return {message:c,signature:w}}catch(i){await disconnect(t),console.error("Error during signature generation:",i);let c=i;throw (c.name==="UserRejectedRequestError"||c.code===4001||/user rejected/i.test(c.message))&&d(true),i}},isReadyToSign:u,isRejected:h}}async function ee(){try{let t=await fetch("/api/siwe/session");if(t.status===401||t.status===404)return {session:void 0,status:"unauthenticated"};if(!t.ok)throw new Error("Failed to fetch session data.");let e=await t.json();return e.isLoggedIn&&e.address&&e.chainId?{session:{address:e.address,chainId:e.chainId},status:"authenticated"}:{session:void 0,status:"unauthenticated"}}catch(t){return console.error("Error fetching session:",t),{session:void 0,status:"unauthenticated"}}}function O({wagmiConfig:t,enabled:e=true,nonceRefetchInterval:r=300*1e3,onSignIn:a,onSignOut:h,getSiweMessageOptions:d}){let[u,p]=useState(void 0),[S,n]=useState("loading"),{isReadyToSign:i,getSiweSignature:c,isRejected:w}=k({wagmiConfig:t}),{address:y,chainId:W,isConnected:v}=useAccount({config:t}),[P,T]=useState(false),g=S==="authenticated",R=S==="loading",N=u,F=useCallback(async()=>{n("loading");let{session:s,status:o}=await ee();return p(s),n(o),s},[]);L(()=>{g&&F();},r);let l=useCallback(async s=>{await fetch("/api/siwe/logout",{method:"POST"}),p(void 0),n("unauthenticated"),h?.(),s?.();},[h]),I=useCallback(async s=>{if(!e)throw new Error("SIWE is currently disabled via provider configuration.");n("loading");try{let o=await c(d);if(!o){n("unauthenticated");return}let m=await fetch("/api/siwe/login",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:o.message,signature:o.signature})}),f=await m.json();if(!m.ok||f.isLoggedIn!==!0)throw new Error(`Verification error: ${f.message||"Login failed."}`);console.log("SIWE Authentication successful.");let A={address:f.address,chainId:f.chainId};p(A),n("authenticated"),a?.(A),s?.(A);}catch(o){throw await disconnect(t),n("unauthenticated"),new Error(`SIWE Sign-In failed: ${o instanceof Error?o.message:"Unknown error"}`)}},[e,c,d,a,t]);return useEffect(()=>{if(g&&e){let s=u?.address?.toLowerCase(),o=y?.toLowerCase(),m=u?.chainId,f=W;s&&o&&s!==o||m&&f&&m!==f?(console.log("SIWE: Wallet context changed (Address or Chain ID). Initiating re-authentication."),T(true),l()):!v&&(console.log("SIWE: Wallet disconnected. Disconnecting session."),l(),h?.());}},[g,y,W,v,u,l,e,h]),useEffect(()=>{P&&S==="unauthenticated"&&i&&e&&(console.log("SIWE: State reset detected. Attempting automatic sign-in to establish new session."),T(false),I().catch(s=>{throw new Error(`SIWE Auto Sign-In failed after context change: ${s instanceof Error?s.message:"Unknown error"}`)}));},[P,S,i,I,e]),useMemo(()=>({data:N,isReadyToSign:i,isRejected:w,isLoading:R,isSignedIn:g,signInWithSiwe:I,signOutSiwe:l,enabled:e}),[N,i,w,R,g,I,l,e])}function ve(t){let e=O(t);return jsx(x.Provider,{value:e,children:t.children})}export{x as SiweAuthContext,ve as SiweNextAuthProvider,L as useInterval,de as useSiweAuth,O as useSiweAuthAdapter,k as useSiweSignature};//# sourceMappingURL=index.mjs.map
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/useInterval.tsx","../src/provider/SiweAuthContext.tsx","../src/hooks/useSiweAuth.tsx","../src/hooks/useSiweSignature.tsx","../src/hooks/useSiweAuthAdapter.tsx","../src/provider/SiweNextAuthProvider.tsx"],"names":["useInterval","callback","delay","savedCallback","useRef","useEffect","id","SiweAuthContext","createContext","useSiweAuth","options","context","useContext","signInWithSiwe","useCallback","signOutSiwe","useMemo","fetchNonce","useSiweSignature","wagmiConfig","useConfig","isConnected","address","chainId","useAccount","isRejected","setIsRejected","useState","isReadyToSign","customOptions","walletSnapshot","getAccount","nonce","messageToSign","createSiweMessage","signature","signMessage","disconnect","error","err","fetchSession","res","data","useSiweAuthAdapter","enabled","nonceRefetchInterval","providerOnSignIn","providerOnSignOut","getSiweMessageOptions","localSession","setLocalSession","sessionStatus","setSessionStatus","config","getSiweSignature","isSigningInAfterContextChange","setIsSigningInAfterContextChange","isAuthenticated","isAuthenticating","updateSession","session","status","userOnSignOut","userOnSignIn","signatureData","response","responseBody","finalSession","sessionAddress","currentAddress","sessionChainId","currentChainId","e","SiweNextAuthProvider","props","siweAuth","jsx"],"mappings":"8QAQO,SAASA,CAAAA,CAAYC,CAAAA,CAAsBC,CAAAA,CAAsB,CACtE,IAAMC,CAAAA,CAAgBC,OAAOH,CAAQ,CAAA,CAErCI,SAAAA,CAAU,IAAM,CACdF,CAAAA,CAAc,OAAA,CAAUF,EAC1B,CAAA,CAAG,CAACA,CAAQ,CAAC,CAAA,CAEbI,SAAAA,CAAU,IAAM,CACd,GAAIH,CAAAA,GAAU,IAAA,EAAQ,OAAO,MAAA,CAAW,KAAe,MAAA,CAAO,WAAA,CAAa,CAEzE,IAAMI,CAAAA,CAAK,MAAA,CAAO,YAAY,IAAMH,CAAAA,CAAc,OAAA,EAAQ,CAAGD,CAAK,CAAA,CAClE,OAAO,IAAM,MAAA,CAAO,aAAA,CAAcI,CAAE,CACtC,CACF,CAAA,CAAG,CAACJ,CAAK,CAAC,EACZ,CChBO,IAAMK,CAAAA,CAAkBC,aAAAA,CAA+C,MAAS,ECWhF,SAASC,EAAAA,CAAYC,CAAAA,CAGJ,CACtB,IAAMC,CAAAA,CAAUC,UAAAA,CAAWL,CAAe,CAAA,CAC1C,GAAII,CAAAA,GAAY,MAAA,CACd,MAAM,IAAI,MAAM,wDAAwD,CAAA,CAI1E,IAAME,CAAAA,CAAiBC,WAAAA,CAAY,SAC1BH,EAAQ,cAAA,CAAeD,CAAAA,EAAS,QAAQ,CAAA,CAE9C,CAACC,CAAAA,CAAQ,cAAA,CAAgBD,CAAAA,EAAS,QAAQ,CAAC,CAAA,CAExCK,CAAAA,CAAcD,WAAAA,CAAY,SACvBH,EAAQ,WAAA,CAAYD,CAAAA,EAAS,SAAS,CAAA,CAE5C,CAACC,CAAAA,CAAQ,YAAaD,CAAAA,EAAS,SAAS,CAAC,CAAA,CAE5C,OAAOM,OAAAA,CACL,KAAO,CACL,GAAGL,CAAAA,CACH,cAAA,CAAAE,CAAAA,CACA,WAAA,CAAAE,CACF,CAAA,CAAA,CACA,CAACJ,CAAAA,CAASE,CAAAA,CAAgBE,CAAW,CACvC,CACF,CC7BA,eAAeE,CAAAA,EAA8B,CAE3C,OAAO,MAAA,CAAO,UAAA,EAAW,CAAE,OAAA,CAAQ,IAAA,CAAM,EAAE,CAC7C,CAWO,SAASC,CAAAA,EAA2C,CACzD,IAAMC,CAAAA,CAAcC,SAAAA,GACd,CAAE,WAAA,CAAAC,CAAAA,CAAa,OAAA,CAAAC,CAAAA,CAAS,OAAA,CAAAC,CAAQ,CAAA,CAAIC,UAAAA,CAAW,CAAE,MAAA,CAAQL,CAAY,CAAC,CAAA,CACtE,CAACM,CAAAA,CAAYC,CAAa,CAAA,CAAIC,QAAAA,CAAS,KAAK,CAAA,CAE5CC,EAAgBZ,OAAAA,CAAQ,IAAMK,CAAAA,EAAe,CAAC,CAACC,CAAAA,EAAW,CAAC,CAACC,CAAAA,CAAS,CAACF,CAAAA,CAAaC,CAAAA,CAASC,CAAO,CAAC,CAAA,CAG1G,OAAAlB,SAAAA,CAAU,IAAM,CACVuB,CAAAA,EACFF,CAAAA,CAAc,KAAK,EAEvB,CAAA,CAAG,CAACE,CAAa,CAAC,CAAA,CAgDX,CAAE,gBAAA,CA9CgB,MAAOC,CAAAA,EAA0C,CACxEH,CAAAA,CAAc,KAAK,EAEnB,IAAMI,CAAAA,CAAiBC,UAAAA,CAAWZ,CAAW,CAAA,CAE7C,GAAI,CAACW,CAAAA,CAAe,WAAA,EAAe,CAACA,CAAAA,CAAe,OAAA,EAAW,CAACA,CAAAA,CAAe,OAAA,CAC5E,MAAM,IAAI,KAAA,CAAM,6EAA6E,CAAA,CAG/F,GAAI,CAEF,IAAME,CAAAA,CAAQ,MAAMf,CAAAA,EAAW,CAC/B,GAAI,CAACe,CAAAA,CAAO,MAAM,IAAI,KAAA,CAAM,sCAAsC,CAAA,CAElE,IAAMC,CAAAA,CAAgBC,iBAAAA,CAAkB,CACtC,MAAA,CAAQ,MAAA,CAAO,QAAA,CAAS,IAAA,CACxB,SAAA,CAAW,2CAAA,CACX,GAAA,CAAK,MAAA,CAAO,QAAA,CAAS,MAAA,CACrB,OAAA,CAAS,IACT,GAAIL,CAAAA,CAAgBA,CAAAA,EAAc,CAAI,EAAC,CACvC,QAASC,CAAAA,CAAe,OAAA,CACxB,OAAA,CAASA,CAAAA,CAAe,OAAA,CACxB,KAAA,CAAAE,CACF,CAAC,CAAA,CAEKG,CAAAA,CAAY,MAAMC,WAAAA,CAAYjB,CAAAA,CAAa,CAAE,OAAA,CAASc,CAAc,CAAC,CAAA,CAE3E,GAAI,CAACE,CAAAA,CACH,MAAAT,CAAAA,CAAc,CAAA,CAAI,CAAA,CAClB,MAAMW,UAAAA,CAAWlB,CAAW,EACtB,IAAI,KAAA,CAAM,8CAA8C,CAAA,CAGhE,OAAO,CAAE,QAASc,CAAAA,CAAe,SAAA,CAAWE,CAAqB,CACnE,CAAA,MAASG,CAAAA,CAAO,CACd,MAAMD,UAAAA,CAAWlB,CAAW,CAAA,CAC5B,OAAA,CAAQ,KAAA,CAAM,oCAAA,CAAsCmB,CAAK,CAAA,CAEzD,IAAMC,CAAAA,CAAMD,CAAAA,CACZ,MAAA,CAAIC,CAAAA,CAAI,OAAS,0BAAA,EAA8BA,CAAAA,CAAI,IAAA,GAAS,IAAA,EAAQ,gBAAA,CAAiB,IAAA,CAAKA,EAAI,OAAO,CAAA,GACnGb,CAAAA,CAAc,IAAI,CAAA,CAEdY,CACR,CACF,CAAA,CAE2B,aAAA,CAAAV,CAAAA,CAAe,UAAA,CAAAH,CAAW,CACvD,CC1EA,eAAee,EAAAA,EAAqF,CAClG,GAAI,CACF,IAAMC,CAAAA,CAAM,MAAM,KAAA,CAAM,mBAAmB,CAAA,CAE3C,GAAIA,CAAAA,CAAI,MAAA,GAAW,KAAOA,CAAAA,CAAI,MAAA,GAAW,GAAA,CACvC,OAAO,CAAE,OAAA,CAAS,KAAA,CAAA,CAAW,MAAA,CAAQ,iBAAkB,CAAA,CAGzD,GAAI,CAACA,CAAAA,CAAI,EAAA,CACP,MAAM,IAAI,KAAA,CAAM,+BAA+B,CAAA,CAGjD,IAAMC,CAAAA,CAAO,MAAMD,CAAAA,CAAI,IAAA,EAAK,CAG5B,OAAIC,CAAAA,CAAK,UAAA,EAAcA,EAAK,OAAA,EAAWA,CAAAA,CAAK,OAAA,CACnC,CACL,OAAA,CAAS,CAAE,OAAA,CAASA,CAAAA,CAAK,OAAA,CAAS,OAAA,CAASA,CAAAA,CAAK,OAAQ,CAAA,CACxD,MAAA,CAAQ,eACV,CAAA,CAEK,CAAE,OAAA,CAAS,KAAA,CAAA,CAAW,MAAA,CAAQ,iBAAkB,CACzD,CAAA,MAAS,CAAA,CAAG,CACV,OAAA,OAAA,CAAQ,KAAA,CAAM,yBAAA,CAA2B,CAAC,CAAA,CACnC,CAAE,OAAA,CAAS,MAAA,CAAW,MAAA,CAAQ,iBAAkB,CACzD,CACF,CAOO,SAASC,CAAAA,CAAmB,CACjC,OAAA,CAAAC,CAAAA,CAAU,KACV,oBAAA,CAAAC,CAAAA,CAAuB,GAAA,CAAS,GAAA,CAChC,QAAA,CAAUC,CAAAA,CACV,UAAWC,CAAAA,CACX,qBAAA,CAAAC,CACF,CAAA,CAAmD,CACjD,GAAM,CAACC,CAAAA,CAAcC,CAAe,CAAA,CAAIvB,QAAAA,CAAkC,MAAS,CAAA,CAC7E,CAACwB,CAAAA,CAAeC,CAAgB,CAAA,CAAIzB,QAAAA,CAAwB,SAAS,CAAA,CAErE0B,CAAAA,CAASjC,WAAU,CACnB,CAAE,aAAA,CAAAQ,CAAAA,CAAe,gBAAA,CAAA0B,CAAAA,CAAkB,WAAA7B,CAAW,CAAA,CAAIP,CAAAA,EAAiB,CAEnE,CAAE,OAAA,CAAAI,EAAS,OAAA,CAAAC,CAAAA,CAAS,WAAA,CAAAF,CAAY,CAAA,CAAIG,UAAAA,CAAW,CAAE,MAAA,CAAA6B,CAAO,CAAC,CAAA,CAEzD,CAACE,CAAAA,CAA+BC,CAAgC,EAAI7B,QAAAA,CAAS,KAAK,CAAA,CAElF8B,CAAAA,CAAkBN,CAAAA,GAAkB,eAAA,CACpCO,EAAmBP,CAAAA,GAAkB,SAAA,CACrCT,CAAAA,CAAgCO,CAAAA,CAGhCU,CAAAA,CAAgB7C,WAAAA,CAAY,SAAY,CAC5CsC,CAAAA,CAAiB,SAAS,CAAA,CAC1B,GAAM,CAAE,OAAA,CAAAQ,CAAAA,CAAS,MAAA,CAAAC,CAAO,CAAA,CAAI,MAAMrB,EAAAA,EAAa,CAC/C,OAAAU,CAAAA,CAAgBU,CAAO,CAAA,CACvBR,CAAAA,CAAiBS,CAAM,CAAA,CAChBD,CACT,CAAA,CAAG,EAAE,CAAA,CAGL5D,CAAAA,CAAY,IAAM,CACZyD,CAAAA,EACFE,CAAAA,GAEJ,CAAA,CAAGd,CAAoB,CAAA,CAOvB,IAAM9B,CAAAA,CAAcD,WAAAA,CAClB,MAAOgD,CAAAA,EAA+B,CACpC,MAAM,KAAA,CAAM,mBAAoB,CAAE,MAAA,CAAQ,MAAO,CAAC,CAAA,CAClDZ,CAAAA,CAAgB,MAAS,CAAA,CACzBE,CAAAA,CAAiB,iBAAiB,CAAA,CAElCL,CAAAA,IAAoB,CACpBe,MACF,CAAA,CACA,CAACf,CAAiB,CACpB,CAAA,CAOMlC,CAAAA,CAAiBC,WAAAA,CACrB,MAAOiD,CAAAA,EAAmD,CACxD,GAAI,CAACnB,CAAAA,CACH,MAAM,IAAI,KAAA,CAAM,wDAAwD,CAAA,CAG1EQ,CAAAA,CAAiB,SAAS,EAE1B,GAAI,CAEF,IAAMY,CAAAA,CAAgB,MAAMV,CAAAA,CAAiBN,CAAqB,CAAA,CAElE,GAAI,CAACgB,CAAAA,CAAe,CAClBZ,CAAAA,CAAiB,iBAAiB,CAAA,CAClC,MACF,CAGA,IAAMa,CAAAA,CAAW,MAAM,KAAA,CAAM,kBAAmB,CAC9C,MAAA,CAAQ,MAAA,CACR,OAAA,CAAS,CAAE,cAAA,CAAgB,kBAAmB,CAAA,CAC9C,IAAA,CAAM,IAAA,CAAK,SAAA,CAAU,CACnB,OAAA,CAASD,EAAc,OAAA,CACvB,SAAA,CAAWA,CAAAA,CAAc,SAC3B,CAAC,CACH,CAAC,CAAA,CAEKE,CAAAA,CAAe,MAAMD,CAAAA,CAAS,IAAA,EAAK,CAEzC,GAAI,CAACA,CAAAA,CAAS,EAAA,EAAMC,CAAAA,CAAa,UAAA,GAAe,CAAA,CAAA,CAC9C,MAAM,IAAI,KAAA,CAAM,CAAA,oBAAA,EAAuBA,CAAAA,CAAa,OAAA,EAAW,eAAe,CAAA,CAAE,EAGlF,OAAA,CAAQ,GAAA,CAAI,iCAAiC,CAAA,CAG7C,IAAMC,CAAAA,CAA4B,CAChC,OAAA,CAASD,CAAAA,CAAa,OAAA,CACtB,OAAA,CAASA,CAAAA,CAAa,OACxB,CAAA,CAEAhB,EAAgBiB,CAAY,CAAA,CAC5Bf,CAAAA,CAAiB,eAAe,CAAA,CAGhCN,CAAAA,GAAmBqB,CAAY,CAAA,CAC/BJ,CAAAA,GAAeI,CAAY,EAC7B,CAAA,MAAS7B,CAAAA,CAAO,CACd,MAAA,MAAMD,UAAAA,CAAWgB,CAAM,CAAA,CACvBD,CAAAA,CAAiB,iBAAiB,CAAA,CAC5B,IAAI,KAAA,CAAM,CAAA,qBAAA,EAAwBd,CAAAA,YAAiB,KAAA,CAAQA,CAAAA,CAAM,OAAA,CAAU,eAAe,CAAA,CAAE,CACpG,CACF,CAAA,CACA,CAACM,CAAAA,CAASU,EAAkBN,CAAAA,CAAuBF,CAAAA,CAAkBO,CAAM,CAC7E,CAAA,CAIA,OAAAhD,UAAU,IAAM,CACd,GAAIoD,CAAAA,EAAmBb,CAAAA,CAAS,CAC9B,IAAMwB,CAAAA,CAAiBnB,CAAAA,EAAc,OAAA,EAAS,WAAA,EAAY,CACpDoB,CAAAA,CAAiB/C,CAAAA,EAAS,aAAY,CACtCgD,CAAAA,CAAiBrB,CAAAA,EAAc,OAAA,CAC/BsB,CAAAA,CAAiBhD,CAAAA,CAEA6C,GAAkBC,CAAAA,EAAkBD,CAAAA,GAAmBC,CAAAA,EACzDC,CAAAA,EAAkBC,CAAAA,EAAkBD,CAAAA,GAAmBC,GAI1E,OAAA,CAAQ,GAAA,CAAI,mFAAmF,CAAA,CAE/Ff,CAAAA,CAAiC,IAAI,CAAA,CAGrCzC,CAAAA,EAAY,EARa,CAACM,CAAAA,GAW1B,OAAA,CAAQ,GAAA,CAAI,mDAAmD,EAC/DN,CAAAA,EAAY,CACZgC,CAAAA,IAAoB,EAExB,CACF,CAAA,CAAG,CAACU,CAAAA,CAAiBnC,CAAAA,CAASC,CAAAA,CAASF,CAAAA,CAAa4B,CAAAA,CAAclC,CAAAA,CAAa6B,EAASG,CAAiB,CAAC,CAAA,CAG1G1C,SAAAA,CAAU,IAAM,CAEVkD,CAAAA,EAAiCJ,CAAAA,GAAkB,iBAAA,EAAqBvB,CAAAA,EAAiBgB,CAAAA,GAC3F,OAAA,CAAQ,GAAA,CAAI,oFAAoF,EAEhGY,CAAAA,CAAiC,KAAK,CAAA,CAGtC3C,CAAAA,EAAe,CAAE,KAAA,CAAO2D,GAAM,CAC5B,MAAM,IAAI,KAAA,CACR,CAAA,+CAAA,EAAkDA,CAAAA,YAAa,MAAQA,CAAAA,CAAE,OAAA,CAAU,eAAe,CAAA,CACpG,CACF,CAAC,CAAA,EAEL,CAAA,CAAG,CAACjB,CAAAA,CAA+BJ,CAAAA,CAAevB,CAAAA,CAAef,CAAAA,CAAgB+B,CAAO,CAAC,CAAA,CAIlF5B,OAAAA,CACL,KAAO,CACL,IAAA,CAAA0B,CAAAA,CACA,cAAAd,CAAAA,CACA,UAAA,CAAAH,CAAAA,CACA,SAAA,CAAWiC,CAAAA,CACX,UAAA,CAAYD,EACZ,cAAA,CAAA5C,CAAAA,CACA,WAAA,CAAAE,CAAAA,CACA,OAAA,CAAA6B,CACF,CAAA,CAAA,CACA,CAACF,CAAAA,CAAMd,CAAAA,CAAeH,CAAAA,CAAYiC,CAAAA,CAAkBD,CAAAA,CAAiB5C,CAAAA,CAAgBE,EAAa6B,CAAO,CAC3G,CACF,CCpNO,SAAS6B,EAAAA,CAAqBC,CAAAA,CAAkC,CACrE,IAAMC,CAAAA,CAAWhC,EAAmB+B,CAAK,CAAA,CACzC,OAAOE,GAAAA,CAACrE,CAAAA,CAAgB,QAAA,CAAhB,CAAyB,KAAA,CAAOoE,CAAAA,CAAW,QAAA,CAAAD,CAAAA,CAAM,QAAA,CAAS,CACpE","file":"index.mjs","sourcesContent":["'use client';\n\nimport { useEffect, useRef } from 'react';\n\n/**\n * @function useInterval\n * Creates a stable interval hook safe for client-side execution.\n */\nexport function useInterval(callback: () => void, delay: number | null) {\n const savedCallback = useRef(callback);\n\n useEffect(() => {\n savedCallback.current = callback;\n }, [callback]);\n\n useEffect(() => {\n if (delay !== null && typeof window !== 'undefined' && window.setInterval) {\n // Use window.setInterval and cast the ID to number to satisfy clearInterval's type\n const id = window.setInterval(() => savedCallback.current(), delay);\n return () => window.clearInterval(id);\n }\n }, [delay]);\n}\n","'use client';\n\nimport { createContext } from 'react';\n\nimport { SiweAuthContextType } from '../types';\n\nexport const SiweAuthContext = createContext<SiweAuthContextType | undefined>(undefined);\n","'use client';\n\nimport { useCallback, useContext, useMemo } from 'react';\n\nimport { SiweAuthContext } from '../provider/SiweAuthContext';\nimport { SiweAuthContextType, SIWESession } from '../types';\n\n/**\n * @function useSiweAuth\n * @description Hook to access the SIWE authentication state and methods.\n * @param {object} [options] - Optional callbacks that override provider-level callbacks.\n * @param {(session?: SIWESession) => void} [options.onSignIn] - Callback executed after a successful sign-in.\n * @param {() => void} [options.onSignOut] - Callback executed after a successful sign-out.\n * @returns {SiweAuthContextType}\n * * @example\n * // const { isSignedIn, signInWithSiwe, data, isRejected } = useSiweAuth();\n */\nexport function useSiweAuth(options?: {\n onSignIn?: (session?: SIWESession) => void;\n onSignOut?: () => void;\n}): SiweAuthContextType {\n const context = useContext(SiweAuthContext);\n if (context === undefined) {\n throw new Error('useSiweAuth must be used within a SiweNextAuthProvider');\n }\n\n // Overrides the context's signOutSiwe/signInWithSiwe with local callbacks\n const signInWithSiwe = useCallback(async () => {\n return context.signInWithSiwe(options?.onSignIn);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [context.signInWithSiwe, options?.onSignIn]);\n\n const signOutSiwe = useCallback(async () => {\n return context.signOutSiwe(options?.onSignOut);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [context.signOutSiwe, options?.onSignOut]);\n\n return useMemo(\n () => ({\n ...context,\n signInWithSiwe,\n signOutSiwe,\n }),\n [context, signInWithSiwe, signOutSiwe],\n );\n}\n","'use client';\n\nimport { disconnect, getAccount, signMessage } from '@wagmi/core';\nimport { useEffect, useMemo, useState } from 'react';\nimport { Address } from 'viem';\nimport { createSiweMessage } from 'viem/siwe';\nimport { useAccount, useConfig } from 'wagmi';\n\nimport { GetSiweMessageOptions, UseSiweSignatureResult } from '../types';\n\n/**\n * @function fetchNonce\n * @description Generates a cryptographically secure, alphanumeric random string to use as the SIWE nonce,\n * satisfying the viem/SIWE requirement (at least 8 chars, alphanumeric).\n * @returns {Promise<string>} The valid alphanumeric nonce string.\n */\nasync function fetchNonce(): Promise<string> {\n // Generate UUID and remove hyphens to create a secure, alphanumeric nonce.\n return crypto.randomUUID().replace(/-/g, '');\n}\n\n/**\n * @function useSiweSignature\n * @description A low-level hook that handles the core SIWE cryptographic flow:\n * getting the nonce, creating the message, and getting the signature using Wagmi/Viem.\n * This is the building block for custom backend authentication.\n * @returns {UseSiweSignatureResult}\n * * @example\n * // const { getSiweSignature, isReadyToSign, isRejected } = useSiweSignature();\n */\nexport function useSiweSignature(): UseSiweSignatureResult {\n const wagmiConfig = useConfig();\n const { isConnected, address, chainId } = useAccount({ config: wagmiConfig });\n const [isRejected, setIsRejected] = useState(false);\n\n const isReadyToSign = useMemo(() => isConnected && !!address && !!chainId, [isConnected, address, chainId]);\n\n // Clear rejected state upon context change\n useEffect(() => {\n if (isReadyToSign) {\n setIsRejected(false);\n }\n }, [isReadyToSign]);\n\n const getSiweSignature = async (customOptions?: GetSiweMessageOptions) => {\n setIsRejected(false); // Reset rejection status at the start of a new attempt\n\n const walletSnapshot = getAccount(wagmiConfig);\n\n if (!walletSnapshot.isConnected || !walletSnapshot.address || !walletSnapshot.chainId) {\n throw new Error('Wallet not connected or connection details are missing from Wagmi snapshot.');\n }\n\n try {\n // Use the corrected fetchNonce\n const nonce = await fetchNonce();\n if (!nonce) throw new Error('Failed to retrieve CSRF token/nonce.');\n\n const messageToSign = createSiweMessage({\n domain: window.location.host,\n statement: 'Sign in with Ethereum to the application.',\n uri: window.location.origin,\n version: '1',\n ...(customOptions ? customOptions() : {}), // Apply custom options\n address: walletSnapshot.address,\n chainId: walletSnapshot.chainId,\n nonce,\n });\n\n const signature = await signMessage(wagmiConfig, { message: messageToSign });\n\n if (!signature) {\n setIsRejected(true); // Set rejected status if signature is null/undefined\n await disconnect(wagmiConfig);\n throw new Error('Message signing cancelled by user or failed.');\n }\n\n return { message: messageToSign, signature: signature as Address };\n } catch (error) {\n await disconnect(wagmiConfig);\n console.error('Error during signature generation:', error);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const err = error as any;\n if (err.name === 'UserRejectedRequestError' || err.code === 4001 || /user rejected/i.test(err.message)) {\n setIsRejected(true);\n }\n throw error;\n }\n };\n\n return { getSiweSignature, isReadyToSign, isRejected };\n}\n","'use client';\n\nimport { disconnect } from '@wagmi/core';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useAccount, useConfig } from 'wagmi';\n\nimport { SiweAuthContextType, SiweNextAuthProviderProps, SIWESession } from '../types';\nimport { useInterval } from './useInterval';\nimport { useSiweSignature } from './useSiweSignature';\n\ntype SessionStatus = 'loading' | 'authenticated' | 'unauthenticated';\n\n/**\n * @function fetchSession\n * @description Fetches the current session status and data from the server.\n * @returns {Promise<{session: SIWESession | undefined, status: SessionStatus}>}\n */\nasync function fetchSession(): Promise<{ session: SIWESession | undefined; status: SessionStatus }> {\n try {\n const res = await fetch('/api/siwe/session');\n\n if (res.status === 401 || res.status === 404) {\n return { session: undefined, status: 'unauthenticated' };\n }\n\n if (!res.ok) {\n throw new Error('Failed to fetch session data.');\n }\n\n const data = await res.json();\n\n // NOTE: Data structure must match SiweSessionData {isLoggedIn, address, chainId}\n if (data.isLoggedIn && data.address && data.chainId) {\n return {\n session: { address: data.address, chainId: data.chainId },\n status: 'authenticated',\n };\n }\n return { session: undefined, status: 'unauthenticated' };\n } catch (e) {\n console.error('Error fetching session:', e);\n return { session: undefined, status: 'unauthenticated' };\n }\n}\n\n/**\n * @function useSiweAuthAdapter\n * Internal hook containing the core SIWE/Iron Session logic, acting as the authentication adapter.\n * @returns {SiweAuthContextType}\n */\nexport function useSiweAuthAdapter({\n enabled = true,\n nonceRefetchInterval = 5 * 60 * 1000, // 5 minutes (300,000 ms)\n onSignIn: providerOnSignIn,\n onSignOut: providerOnSignOut,\n getSiweMessageOptions,\n}: SiweNextAuthProviderProps): SiweAuthContextType {\n const [localSession, setLocalSession] = useState<SIWESession | undefined>(undefined);\n const [sessionStatus, setSessionStatus] = useState<SessionStatus>('loading');\n\n const config = useConfig();\n const { isReadyToSign, getSiweSignature, isRejected } = useSiweSignature();\n\n const { address, chainId, isConnected } = useAccount({ config });\n\n const [isSigningInAfterContextChange, setIsSigningInAfterContextChange] = useState(false);\n\n const isAuthenticated = sessionStatus === 'authenticated';\n const isAuthenticating = sessionStatus === 'loading';\n const data: SIWESession | undefined = localSession;\n\n // --- SESSION REFETCH (equivalent to NextAuth's update) ---\n const updateSession = useCallback(async () => {\n setSessionStatus('loading');\n const { session, status } = await fetchSession();\n setLocalSession(session);\n setSessionStatus(status);\n return session;\n }, []);\n\n // --- NONCE REFETCH LOGIC (Managed by custom interval) ---\n useInterval(() => {\n if (isAuthenticated) {\n updateSession();\n }\n }, nonceRefetchInterval);\n\n /**\n * @async\n * @method signOutSiwe\n * Clears the session by calling the server API.\n */\n const signOutSiwe = useCallback(\n async (userOnSignOut?: () => void) => {\n await fetch('/api/siwe/logout', { method: 'POST' }); // Call your custom logout API\n setLocalSession(undefined);\n setSessionStatus('unauthenticated');\n\n providerOnSignOut?.(); // Execute provider callback\n userOnSignOut?.(); // Execute user callback\n },\n [providerOnSignOut],\n );\n\n /**\n * @async\n * @method signInWithSiwe\n * Executes the full SIWE authentication flow: signature -> verification -> session creation.\n */\n const signInWithSiwe = useCallback(\n async (userOnSignIn?: (session?: SIWESession) => void) => {\n if (!enabled) {\n throw new Error('SIWE is currently disabled via provider configuration.');\n }\n\n setSessionStatus('loading');\n\n try {\n // 1. Get Signature using the low-level hook\n const signatureData = await getSiweSignature(getSiweMessageOptions);\n\n if (!signatureData) {\n setSessionStatus('unauthenticated');\n return;\n }\n\n // 2. Send message and signature to your custom login API\n const response = await fetch('/api/siwe/login', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n message: signatureData.message,\n signature: signatureData.signature,\n }),\n });\n\n const responseBody = await response.json();\n\n if (!response.ok || responseBody.isLoggedIn !== true) {\n throw new Error(`Verification error: ${responseBody.message || 'Login failed.'}`);\n }\n\n console.log('SIWE Authentication successful.');\n\n // 3. Update session locally\n const finalSession: SIWESession = {\n address: responseBody.address,\n chainId: responseBody.chainId,\n };\n\n setLocalSession(finalSession);\n setSessionStatus('authenticated');\n\n // 4. Execute callbacks after successful sign-in\n providerOnSignIn?.(finalSession);\n userOnSignIn?.(finalSession);\n } catch (error) {\n await disconnect(config);\n setSessionStatus('unauthenticated');\n throw new Error(`SIWE Sign-In failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n },\n [enabled, getSiweSignature, getSiweMessageOptions, providerOnSignIn, config],\n );\n\n // --- OBLIGATORY SESSION RESET / AUTO-SIGN IN EFFECT ---\n\n useEffect(() => {\n if (isAuthenticated && enabled) {\n const sessionAddress = localSession?.address?.toLowerCase();\n const currentAddress = address?.toLowerCase();\n const sessionChainId = localSession?.chainId;\n const currentChainId = chainId;\n\n const addressChanged = sessionAddress && currentAddress && sessionAddress !== currentAddress;\n const chainChanged = sessionChainId && currentChainId && sessionChainId !== currentChainId;\n const walletDisconnected = !isConnected;\n\n if (addressChanged || chainChanged) {\n console.log('SIWE: Wallet context changed (Address or Chain ID). Initiating re-authentication.');\n\n setIsSigningInAfterContextChange(true);\n\n // 1. OBLIGATORY SIGN OUT for the old session (security)\n signOutSiwe();\n } else if (walletDisconnected) {\n // Handle explicit wallet disconnection: Always sign out.\n console.log('SIWE: Wallet disconnected. Disconnecting session.');\n signOutSiwe();\n providerOnSignOut?.(); // Execute provider callback for disconnect\n }\n }\n }, [isAuthenticated, address, chainId, isConnected, localSession, signOutSiwe, enabled, providerOnSignOut]);\n\n // --- EFFECT TO EXECUTE AUTO SIGN-IN AFTER STATE RESET ---\n useEffect(() => {\n // Triggers when: 1. Flag is set AND 2. Status transitioned to 'unauthenticated'\n if (isSigningInAfterContextChange && sessionStatus === 'unauthenticated' && isReadyToSign && enabled) {\n console.log('SIWE: State reset detected. Attempting automatic sign-in to establish new session.');\n\n setIsSigningInAfterContextChange(false); // Reset flag\n\n // Auto sign-in execution\n signInWithSiwe().catch((e) => {\n throw new Error(\n `SIWE Auto Sign-In failed after context change: ${e instanceof Error ? e.message : 'Unknown error'}`,\n );\n });\n }\n }, [isSigningInAfterContextChange, sessionStatus, isReadyToSign, signInWithSiwe, enabled]);\n\n // --- FINAL EXPORT ---\n\n return useMemo(\n () => ({\n data,\n isReadyToSign,\n isRejected,\n isLoading: isAuthenticating,\n isSignedIn: isAuthenticated,\n signInWithSiwe,\n signOutSiwe,\n enabled,\n }),\n [data, isReadyToSign, isRejected, isAuthenticating, isAuthenticated, signInWithSiwe, signOutSiwe, enabled],\n );\n}\n","'use client';\n\nimport { useSiweAuthAdapter } from '../hooks/useSiweAuthAdapter';\nimport { SiweNextAuthProviderProps } from '../types';\nimport { SiweAuthContext } from './SiweAuthContext';\n\n/**\n * @component\n * @name SiweNextAuthProvider\n * @description Universal Provider for Sign-In with Ethereum (SIWE) using NextAuth.js.\n * This component handles the SIWE authentication logic.\n * It must be nested inside NextAuth's `<SessionProvider>` and your Wagmi Provider.\n * * **Note**: This provider requires the server-side NextAuth configuration to be set up.\n */\nexport function SiweNextAuthProvider(props: SiweNextAuthProviderProps) {\n const siweAuth = useSiweAuthAdapter(props);\n return <SiweAuthContext.Provider value={siweAuth}>{props.children}</SiweAuthContext.Provider>;\n}\n"]}
1
+ {"version":3,"sources":["../src/hooks/useInterval.tsx","../src/provider/SiweAuthContext.tsx","../src/hooks/useSiweAuth.tsx","../src/hooks/useSiweSignature.tsx","../src/hooks/useSiweAuthAdapter.tsx","../src/provider/SiweNextAuthProvider.tsx"],"names":["useInterval","callback","delay","savedCallback","useRef","useEffect","id","SiweAuthContext","createContext","useSiweAuth","options","context","useContext","signInWithSiwe","useCallback","signOutSiwe","useMemo","fetchNonce","useSiweSignature","wagmiConfig","isConnected","address","chainId","useAccount","isRejected","setIsRejected","useState","isReadyToSign","customOptions","walletSnapshot","getAccount","nonce","messageToSign","createSiweMessage","signature","signMessage","disconnect","error","err","fetchSession","res","data","e","useSiweAuthAdapter","enabled","nonceRefetchInterval","providerOnSignIn","providerOnSignOut","getSiweMessageOptions","localSession","setLocalSession","sessionStatus","setSessionStatus","getSiweSignature","isSigningInAfterContextChange","setIsSigningInAfterContextChange","isAuthenticated","isAuthenticating","updateSession","session","status","userOnSignOut","userOnSignIn","signatureData","response","responseBody","finalSession","sessionAddress","currentAddress","sessionChainId","currentChainId","SiweNextAuthProvider","props","siweAuth","jsx"],"mappings":"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","file":"index.mjs","sourcesContent":["'use client';\n\nimport { useEffect, useRef } from 'react';\n\n/**\n * @function useInterval\n * Creates a stable interval hook safe for client-side execution.\n */\nexport function useInterval(callback: () => void, delay: number | null) {\n const savedCallback = useRef(callback);\n\n useEffect(() => {\n savedCallback.current = callback;\n }, [callback]);\n\n useEffect(() => {\n if (delay !== null && typeof window !== 'undefined' && window.setInterval) {\n // Use window.setInterval and cast the ID to number to satisfy clearInterval's type\n const id = window.setInterval(() => savedCallback.current(), delay);\n return () => window.clearInterval(id);\n }\n }, [delay]);\n}\n","'use client';\n\nimport { createContext } from 'react';\n\nimport { SiweAuthContextType } from '../types';\n\nexport const SiweAuthContext = createContext<SiweAuthContextType | undefined>(undefined);\n","'use client';\n\nimport { useCallback, useContext, useMemo } from 'react';\n\nimport { SiweAuthContext } from '../provider/SiweAuthContext';\nimport { SiweAuthContextType, SIWESession } from '../types';\n\n/**\n * @function useSiweAuth\n * @description Hook to access the SIWE authentication state and methods.\n * @param {object} [options] - Optional callbacks that override provider-level callbacks.\n * @param {(session?: SIWESession) => void} [options.onSignIn] - Callback executed after a successful sign-in.\n * @param {() => void} [options.onSignOut] - Callback executed after a successful sign-out.\n * @returns {SiweAuthContextType}\n * * @example\n * // const { isSignedIn, signInWithSiwe, data, isRejected } = useSiweAuth();\n */\nexport function useSiweAuth(options?: {\n onSignIn?: (session?: SIWESession) => void;\n onSignOut?: () => void;\n}): SiweAuthContextType {\n const context = useContext(SiweAuthContext);\n if (context === undefined) {\n throw new Error('useSiweAuth must be used within a SiweNextAuthProvider');\n }\n\n // Overrides the context's signOutSiwe/signInWithSiwe with local callbacks\n const signInWithSiwe = useCallback(async () => {\n return context.signInWithSiwe(options?.onSignIn);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [context.signInWithSiwe, options?.onSignIn]);\n\n const signOutSiwe = useCallback(async () => {\n return context.signOutSiwe(options?.onSignOut);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [context.signOutSiwe, options?.onSignOut]);\n\n return useMemo(\n () => ({\n ...context,\n signInWithSiwe,\n signOutSiwe,\n }),\n [context, signInWithSiwe, signOutSiwe],\n );\n}\n","'use client';\n\nimport { Config, disconnect, getAccount, signMessage } from '@wagmi/core';\nimport { useEffect, useMemo, useState } from 'react';\nimport { Address } from 'viem';\nimport { createSiweMessage } from 'viem/siwe';\nimport { useAccount } from 'wagmi';\n\nimport { GetSiweMessageOptions, UseSiweSignatureResult } from '../types';\n\n/**\n * @function fetchNonce\n * @description Generates a cryptographically secure, alphanumeric random string to use as the SIWE nonce,\n * satisfying the viem/SIWE requirement (at least 8 chars, alphanumeric).\n * @returns {Promise<string>} The valid alphanumeric nonce string.\n */\nasync function fetchNonce(): Promise<string> {\n // Generate UUID and remove hyphens to create a secure, alphanumeric nonce.\n return crypto.randomUUID().replace(/-/g, '');\n}\n\n/**\n * @function useSiweSignature\n * @description A low-level hook that handles the core SIWE cryptographic flow:\n * getting the nonce, creating the message, and getting the signature using Wagmi/Viem.\n * This is the building block for custom backend authentication.\n * @returns {UseSiweSignatureResult}\n * * @example\n * // const { getSiweSignature, isReadyToSign, isRejected } = useSiweSignature();\n */\nexport function useSiweSignature({ wagmiConfig }: { wagmiConfig: Config }): UseSiweSignatureResult {\n const { isConnected, address, chainId } = useAccount({ config: wagmiConfig });\n const [isRejected, setIsRejected] = useState(false);\n\n const isReadyToSign = useMemo(() => isConnected && !!address && !!chainId, [isConnected, address, chainId]);\n\n // Clear rejected state upon context change\n useEffect(() => {\n if (isReadyToSign) {\n setIsRejected(false);\n }\n }, [isReadyToSign]);\n\n const getSiweSignature = async (customOptions?: GetSiweMessageOptions) => {\n setIsRejected(false); // Reset rejection status at the start of a new attempt\n\n const walletSnapshot = getAccount(wagmiConfig);\n\n if (!walletSnapshot.isConnected || !walletSnapshot.address || !walletSnapshot.chainId) {\n throw new Error('Wallet not connected or connection details are missing from Wagmi snapshot.');\n }\n\n try {\n // Use the corrected fetchNonce\n const nonce = await fetchNonce();\n if (!nonce) throw new Error('Failed to retrieve CSRF token/nonce.');\n\n const messageToSign = createSiweMessage({\n domain: window.location.host,\n statement: 'Sign in with Ethereum to the application.',\n uri: window.location.origin,\n version: '1',\n ...(customOptions ? customOptions() : {}), // Apply custom options\n address: walletSnapshot.address,\n chainId: walletSnapshot.chainId,\n nonce,\n });\n\n const signature = await signMessage(wagmiConfig, { message: messageToSign });\n\n if (!signature) {\n setIsRejected(true); // Set rejected status if signature is null/undefined\n await disconnect(wagmiConfig);\n throw new Error('Message signing cancelled by user or failed.');\n }\n\n return { message: messageToSign, signature: signature as Address };\n } catch (error) {\n await disconnect(wagmiConfig);\n console.error('Error during signature generation:', error);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const err = error as any;\n if (err.name === 'UserRejectedRequestError' || err.code === 4001 || /user rejected/i.test(err.message)) {\n setIsRejected(true);\n }\n throw error;\n }\n };\n\n return { getSiweSignature, isReadyToSign, isRejected };\n}\n","'use client';\n\nimport { disconnect } from '@wagmi/core';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useAccount } from 'wagmi';\n\nimport { SiweAuthContextType, SiweNextAuthProviderProps, SIWESession } from '../types';\nimport { useInterval } from './useInterval';\nimport { useSiweSignature } from './useSiweSignature';\n\ntype SessionStatus = 'loading' | 'authenticated' | 'unauthenticated';\n\n/**\n * @function fetchSession\n * @description Fetches the current session status and data from the server.\n * @returns {Promise<{session: SIWESession | undefined, status: SessionStatus}>}\n */\nasync function fetchSession(): Promise<{ session: SIWESession | undefined; status: SessionStatus }> {\n try {\n const res = await fetch('/api/siwe/session');\n\n if (res.status === 401 || res.status === 404) {\n return { session: undefined, status: 'unauthenticated' };\n }\n\n if (!res.ok) {\n throw new Error('Failed to fetch session data.');\n }\n\n const data = await res.json();\n\n // NOTE: Data structure must match SiweSessionData {isLoggedIn, address, chainId}\n if (data.isLoggedIn && data.address && data.chainId) {\n return {\n session: { address: data.address, chainId: data.chainId },\n status: 'authenticated',\n };\n }\n return { session: undefined, status: 'unauthenticated' };\n } catch (e) {\n console.error('Error fetching session:', e);\n return { session: undefined, status: 'unauthenticated' };\n }\n}\n\n/**\n * @function useSiweAuthAdapter\n * Internal hook containing the core SIWE/Iron Session logic, acting as the authentication adapter.\n * @returns {SiweAuthContextType}\n */\nexport function useSiweAuthAdapter({\n wagmiConfig,\n enabled = true,\n nonceRefetchInterval = 5 * 60 * 1000, // 5 minutes (300,000 ms)\n onSignIn: providerOnSignIn,\n onSignOut: providerOnSignOut,\n getSiweMessageOptions,\n}: SiweNextAuthProviderProps): SiweAuthContextType {\n const [localSession, setLocalSession] = useState<SIWESession | undefined>(undefined);\n const [sessionStatus, setSessionStatus] = useState<SessionStatus>('loading');\n\n const { isReadyToSign, getSiweSignature, isRejected } = useSiweSignature({ wagmiConfig });\n\n const { address, chainId, isConnected } = useAccount({ config: wagmiConfig });\n\n const [isSigningInAfterContextChange, setIsSigningInAfterContextChange] = useState(false);\n\n const isAuthenticated = sessionStatus === 'authenticated';\n const isAuthenticating = sessionStatus === 'loading';\n const data: SIWESession | undefined = localSession;\n\n // --- SESSION REFETCH (equivalent to NextAuth's update) ---\n const updateSession = useCallback(async () => {\n setSessionStatus('loading');\n const { session, status } = await fetchSession();\n setLocalSession(session);\n setSessionStatus(status);\n return session;\n }, []);\n\n // --- NONCE REFETCH LOGIC (Managed by custom interval) ---\n useInterval(() => {\n if (isAuthenticated) {\n updateSession();\n }\n }, nonceRefetchInterval);\n\n /**\n * @async\n * @method signOutSiwe\n * Clears the session by calling the server API.\n */\n const signOutSiwe = useCallback(\n async (userOnSignOut?: () => void) => {\n await fetch('/api/siwe/logout', { method: 'POST' }); // Call your custom logout API\n setLocalSession(undefined);\n setSessionStatus('unauthenticated');\n\n providerOnSignOut?.(); // Execute provider callback\n userOnSignOut?.(); // Execute user callback\n },\n [providerOnSignOut],\n );\n\n /**\n * @async\n * @method signInWithSiwe\n * Executes the full SIWE authentication flow: signature -> verification -> session creation.\n */\n const signInWithSiwe = useCallback(\n async (userOnSignIn?: (session?: SIWESession) => void) => {\n if (!enabled) {\n throw new Error('SIWE is currently disabled via provider configuration.');\n }\n\n setSessionStatus('loading');\n\n try {\n // 1. Get Signature using the low-level hook\n const signatureData = await getSiweSignature(getSiweMessageOptions);\n\n if (!signatureData) {\n setSessionStatus('unauthenticated');\n return;\n }\n\n // 2. Send message and signature to your custom login API\n const response = await fetch('/api/siwe/login', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n message: signatureData.message,\n signature: signatureData.signature,\n }),\n });\n\n const responseBody = await response.json();\n\n if (!response.ok || responseBody.isLoggedIn !== true) {\n throw new Error(`Verification error: ${responseBody.message || 'Login failed.'}`);\n }\n\n console.log('SIWE Authentication successful.');\n\n // 3. Update session locally\n const finalSession: SIWESession = {\n address: responseBody.address,\n chainId: responseBody.chainId,\n };\n\n setLocalSession(finalSession);\n setSessionStatus('authenticated');\n\n // 4. Execute callbacks after successful sign-in\n providerOnSignIn?.(finalSession);\n userOnSignIn?.(finalSession);\n } catch (error) {\n await disconnect(wagmiConfig);\n setSessionStatus('unauthenticated');\n throw new Error(`SIWE Sign-In failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n },\n [enabled, getSiweSignature, getSiweMessageOptions, providerOnSignIn, wagmiConfig],\n );\n\n // --- OBLIGATORY SESSION RESET / AUTO-SIGN IN EFFECT ---\n\n useEffect(() => {\n if (isAuthenticated && enabled) {\n const sessionAddress = localSession?.address?.toLowerCase();\n const currentAddress = address?.toLowerCase();\n const sessionChainId = localSession?.chainId;\n const currentChainId = chainId;\n\n const addressChanged = sessionAddress && currentAddress && sessionAddress !== currentAddress;\n const chainChanged = sessionChainId && currentChainId && sessionChainId !== currentChainId;\n const walletDisconnected = !isConnected;\n\n if (addressChanged || chainChanged) {\n console.log('SIWE: Wallet context changed (Address or Chain ID). Initiating re-authentication.');\n\n setIsSigningInAfterContextChange(true);\n\n // 1. OBLIGATORY SIGN OUT for the old session (security)\n signOutSiwe();\n } else if (walletDisconnected) {\n // Handle explicit wallet disconnection: Always sign out.\n console.log('SIWE: Wallet disconnected. Disconnecting session.');\n signOutSiwe();\n providerOnSignOut?.(); // Execute provider callback for disconnect\n }\n }\n }, [isAuthenticated, address, chainId, isConnected, localSession, signOutSiwe, enabled, providerOnSignOut]);\n\n // --- EFFECT TO EXECUTE AUTO SIGN-IN AFTER STATE RESET ---\n useEffect(() => {\n // Triggers when: 1. Flag is set AND 2. Status transitioned to 'unauthenticated'\n if (isSigningInAfterContextChange && sessionStatus === 'unauthenticated' && isReadyToSign && enabled) {\n console.log('SIWE: State reset detected. Attempting automatic sign-in to establish new session.');\n\n setIsSigningInAfterContextChange(false); // Reset flag\n\n // Auto sign-in execution\n signInWithSiwe().catch((e) => {\n throw new Error(\n `SIWE Auto Sign-In failed after context change: ${e instanceof Error ? e.message : 'Unknown error'}`,\n );\n });\n }\n }, [isSigningInAfterContextChange, sessionStatus, isReadyToSign, signInWithSiwe, enabled]);\n\n // --- FINAL EXPORT ---\n\n return useMemo(\n () => ({\n data,\n isReadyToSign,\n isRejected,\n isLoading: isAuthenticating,\n isSignedIn: isAuthenticated,\n signInWithSiwe,\n signOutSiwe,\n enabled,\n }),\n [data, isReadyToSign, isRejected, isAuthenticating, isAuthenticated, signInWithSiwe, signOutSiwe, enabled],\n );\n}\n","'use client';\n\nimport { useSiweAuthAdapter } from '../hooks/useSiweAuthAdapter';\nimport { SiweNextAuthProviderProps } from '../types';\nimport { SiweAuthContext } from './SiweAuthContext';\n\n/**\n * @component\n * @name SiweNextAuthProvider\n * @description Universal Provider for Sign-In with Ethereum (SIWE) using NextAuth.js.\n * This component handles the SIWE authentication logic.\n * It must be nested inside NextAuth's `<SessionProvider>` and your Wagmi Provider.\n * * **Note**: This provider requires the server-side NextAuth configuration to be set up.\n */\nexport function SiweNextAuthProvider(props: SiweNextAuthProviderProps) {\n const siweAuth = useSiweAuthAdapter(props);\n return <SiweAuthContext.Provider value={siweAuth}>{props.children}</SiweAuthContext.Provider>;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuwaio/satellite-siwe-next-auth",
3
- "version": "1.0.0-fix-test-alpha.42.b314afd",
3
+ "version": "1.0.0-fix-test-alpha.43.2b6e6fe",
4
4
  "private": false,
5
5
  "author": "Oleksandr Tkach",
6
6
  "license": "Apache-2.0",