Sign-In with Ethereum
raw JSON → 4.4.0 verified Fri May 01 auth: no python
A Python implementation of Sign-In with Ethereum (EIP-4361). Supports parsing, verifying, and generating EIP-4361 messages for Ethereum authentication. Current version 4.4.0, requires Python >=3.8, <4.0. Actively maintained.
pip install siwe Common errors
error AttributeError: module 'siwe' has no attribute 'SiweMessage' ↓
cause Old import path or incomplete install; in v4.0.0+ the class is at the top level.
fix
Use
from siwe import SiweMessage (not from siwe.siwe import SiweMessage). error TypeError: verify() got an unexpected keyword argument 'message' ↓
cause Using v4+ API but passing arguments from earlier versions.
fix
Call
verify(signature=signature) instead of verify(message=..., signature=...). error ValueError: Invalid nonce length ↓
cause The nonce must be at least 8 characters long according to EIP-4361. Some generated nonces may be shorter if using a custom one.
fix
Use
generate_nonce() from siwe which ensures proper length, or provide a nonce of at least 8 characters. Warnings
breaking In v4.0.0, the signature verification API changed: `verify` now requires the `signature` parameter and no longer accepts `message` param. Also, `SiweMessage` no longer has a `check_valid` method. ↓
fix Use `message.verify(signature=signature)` instead of passing separate arguments or calling deprecated methods.
deprecated Using `from siwe import SiweMessage` is correct, but importing from submodules like `siwe.siwe` is deprecated and may break in future versions. ↓
fix Import directly from the top-level `siwe` package: `from siwe import SiweMessage`.
gotcha The `verify` method returns the recovered address (a string) on success, not a boolean. Many users expect a boolean and incorrectly check `if message.verify(signature)`. This will always be truthy if a valid address is returned. ↓
fix Compare the recovered address to the expected signer: `recovered = message.verify(signature=signature); assert recovered == expected_address`.
Imports
- SiweMessage
from siwe import SiweMessage - generate_nonce
from siwe import generate_nonce
Quickstart
from siwe import SiweMessage, generate_nonce
from eth_account.messages import encode_defunct
from eth_account.account import Account
# Generate a nonce
nonce = generate_nonce()
# Create a SIWE message
message = SiweMessage(
domain='example.com',
address='0x1234...',
uri='https://example.com',
version='1',
chain_id=1,
nonce=nonce,
issued_at='2022-01-01T00:00:00Z'
)
# Prepare message for signing
prepared = message.prepare_message()
# (Typically you'd send `prepared` to the client to sign with their wallet)
# To verify, you need the signature from the wallet
# signature = '0x...' # signature from the client
# recovered_address = message.verify(signature=signature)
# print(recovered_address)