@@ -2,6 +2,9 @@ import type { NonceResponse, Session, UserInfo } from "../types.js";
22import { getAddress , type WalletClient } from "viem" ;
33import { ModuleBase } from "../base.js" ;
44
5+ const DEFAULT_SIWE_VERIFY_RETRY = 10 ;
6+ const DEFAULT_SIWE_VERIFY_BACKOFF_MS = 100 ;
7+
58export class AuthModule extends ModuleBase {
69 /**
710 * Request nonce for SIWE.
@@ -34,7 +37,11 @@ export class AuthModule extends ModuleBase {
3437 * Full SIWE flow using a `WalletClient`.
3538 * - Derives address, fetches nonce, signs message, verifies and stores session.
3639 */
37- async SIWE ( wallet : WalletClient , signal ?: AbortSignal ) : Promise < Session > {
40+ async SIWE (
41+ wallet : WalletClient ,
42+ retry = DEFAULT_SIWE_VERIFY_RETRY ,
43+ signal ?: AbortSignal
44+ ) : Promise < Session > {
3845 // Resolve the current active account from the WalletClient.
3946 // - Browser wallets (e.g., MetaMask) surface the user-selected address here.
4047 // - Viem/local wallets must set `wallet.account` explicitly before calling.
@@ -53,7 +60,21 @@ export class AuthModule extends ModuleBase {
5360 // Sign using the active account resolved above (string or Account object)
5461 const signature = await wallet . signMessage ( { account, message } ) ;
5562
56- return this . verify ( message , signature , signal ) ;
63+ // Retry verify up to `retry` times
64+ let lastError : unknown ;
65+ for ( let attemptIndex = 0 ; attemptIndex < retry ; attemptIndex ++ ) {
66+ try {
67+ return await this . verify ( message , signature , signal ) ;
68+ } catch ( err ) {
69+ lastError = err ;
70+ await this . delay ( DEFAULT_SIWE_VERIFY_BACKOFF_MS ) ;
71+ }
72+ }
73+ throw lastError instanceof Error ? lastError : new Error ( "SIWE verification failed" ) ;
74+ }
75+
76+ private async delay ( ms : number ) : Promise < void > {
77+ await new Promise ( ( resolve ) => setTimeout ( resolve , ms ) ) ;
5778 }
5879
5980 /**
0 commit comments