I'm not sure if that's possible but it would be very useful to have the wallet address be a part of the id token and JWT.
Our use case is a complex onboarding process and it'll be helpful to use the verified JWT for authentication, and base it on wallet address rather than an email.
This would be great to document in the server side verification, took a while to find. I guess changing the curve will let obtain other chains' public addresses (such as Solana) in this case.
Please note that the public key is compressed. It took me few hours to study the keccak and eliptical curvers and how it is even possible to do the compression. Afterwards I noticed that the resulting address had different case than the one I generated, so I have had to learn about the “checksum” address.
So it was a great learning episode about the Ethereum essentials in the end… but for those who just need a solution, here is the code I ended up with:
import eth_utils
from coincurve import PublicKey
def derive_wallet(public_key: str) -> str:
"""Derives Ethereum wallet address from either compressed or uncompressed public key."""
# Ethereum wallet address is represented by the last 20 bytes from the
# keccak256 hex digest of the uncompressed public key.
# Public keys are prepended with a single byte to indicate if they are
# compressed or uncompressed. This means we first need to get the
# uncompressed 65 byte key (compressed=False) and then strip the first byte
# ([1:]) to get our 64 byte Ethereum public key.
# https://www.arthurkoziel.com/generating-ethereum-addresses-in-python/
uncompressed_key = PublicKey(bytes.fromhex(public_key)).format(compressed=False)[1:]
keccak_digest = eth_utils.keccak(uncompressed_key)
return eth_utils.to_checksum_address(f"0x{keccak_digest[-20:].hex()}")