5
5
from src .auth .utils .bcrypt_helper import hash_password , verify_password
6
6
from src .db .models import UserModel
7
7
from src .db .sql_alchemy import Database
8
+ from siwe import SiweMessage
8
9
9
10
database = Database ()
10
11
@@ -31,6 +32,15 @@ class LoginInput(BaseModel):
31
32
)
32
33
33
34
35
+ class VerifyInput (BaseModel ):
36
+ message : str = Field (
37
+ ..., example = "0x0..." , description = "The SIWE message"
38
+ )
39
+ signature : str = Field (
40
+ ..., example = "0x0..." , description = "User's signature for a message"
41
+ )
42
+
43
+
34
44
class AuthService :
35
45
"""
36
46
Service class for handling user authentication and registration logic.
@@ -91,3 +101,34 @@ def authenticate_user(self, email: str, password: str, db: Session):
91
101
raise HTTPException (status_code = 401 , detail = "Incorrect email or password" )
92
102
93
103
return user
104
+
105
+ def verify_signature (self , message : str , signature : str ):
106
+ """
107
+ Verify a signature according to SIWE spec
108
+
109
+ Args:
110
+ message (str): A SIWE message
111
+ signature (str): User's signature for the message
112
+
113
+ Returns:
114
+ VerificationResult: The result of the verification, containing the address and chain id of the signing wallet
115
+
116
+ Raises:
117
+ HTTPException: If message cannot be parsed or verified
118
+ """
119
+
120
+ try :
121
+ siwe_message = SiweMessage .from_message (message )
122
+ siwe_message .verify (signature )
123
+ except ValueError :
124
+ # ValueError is raised if message is invalid according to SIWE
125
+ raise HTTPException (
126
+ status_code = 400 , detail = "The provided message is not a valid SIWE message" )
127
+ except :
128
+ raise HTTPException (
129
+ status_code = 401 , detail = "Signature is not valid" )
130
+
131
+ return {
132
+ "chain_id" : siwe_message .chain_id ,
133
+ "address" : siwe_message .address ,
134
+ }
0 commit comments