I want my server to be able to authenticate a user based on whether or not they have the private key to their wallet. I am using web3.js in my front end, and web3.py in my backend.

The scenario will be something like this:

enter image description here

For now I only care about step 3 (without the nonce) and step 4.

This is the code I have in my front end:

        //Instantiate Web3
        const Web3 = require("web3");

        //Get Metamask web3 provider
        var web3 = new Web3(Web3.givenProvider);

        //Connect to Metamask (not sure how to do like web3.eth.connect)
        await window.ethereum.enable();

        //Get wallet address (public key)
        var accounts = await web3.eth.getAccounts();
        const walletAddress = accounts[0];

        //TO-DO: Message should be generated on server side with a nonce
        const message = "helloworld";

        //Sign message with Metamask (private key)
        const signedMessage = await web3.eth.personal.sign(

In my Django backend, I am creating an API like this: http://localhost:8000/verify/claimedWallet/message/signedMessage

(This params convention looks off to me, but that was what was recommended in a Python Dev discord.)

How do I use web3.py to recover the address from the message and signed message?



1 Answer 1


Here is what worked for me:

You will need a Web3 provider, for example:

w3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/api_key')

You can recover the address using the message and signature like so:

encoded_message = encode_defunct(bytes(message, encoding='utf8'))
recoveredAddress = w3.eth.account.recover_message(encoded_message , signature)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.