Solana, verify a signature with python

907 views Asked by At

I'm trying to authenticate users via the phantom wallet but I cannot verify the signature on the backend. Here's my frontend code:

const response = await solana.connect();
console.log("wallet account ", response.publicKey.toString());
setWalletKey(response.publicKey.toString());
const message = new TextEncoder().encode("hello");
const signature = await solana.signMessage(message);
const resp_backend = await Axios.post("http://localhost:8000/api/auth/",{message:"hello", pub_key:response.publicKey.toString(), signature:bs58.encode(signature.signature)})

And the backend on Django:

from nacl.signing import VerifyKey
import base58
from solders.pubkey import Pubkey

def verify_signature_for_user(public_key, signature, message):
    pub_key = Pubkey(public_key)
    print(len(public_key))
    msg = bytes(message, encoding='utf-8')
    signed = bytes(signature, 'utf-8')


    result = VerifyKey(pub_key).verify(smessage=msg, signature=base58.b58decode(signed))
    return result

I'm getting the below error:

ValueError: expected a sequence of length 32 (got 44)

Any ideas on how to fix this?

2

There are 2 answers

0
Hans On

In "pubkey class" (from solders.pubkey import Pubkey), we can see the bytes based init value below (pubkey.pyi).

from typing import ClassVar, Sequence, Tuple, Union

class Pubkey:
    LENGTH: ClassVar[int]
    def __init__(self, pubkey_bytes: Union[bytes, Sequence[int]]) -> None: ...
    @staticmethod
    def new_unique() -> "Pubkey": ...

In the solana, pubkey can be Uint8Array(32) and that this array can make with base58 library. So, If you fix this point, the code will be work well.

import base58
_pub_key = base58.b58decode(public_key)
pub_key = Pubkey(_pub_key)
1
Tamgros On

If you're passing in a string, you have to convert it

pub_key = Pubkey.from_string(public_key)