Skip to content
This repository was archived by the owner on May 3, 2024. It is now read-only.
This repository was archived by the owner on May 3, 2024. It is now read-only.

wallet_authenticator is outdated and not in line with the message created by the react/web SDK #145

@ManZzup

Description

@ManZzup

Hi there,

I'll try to improve the issue ticket as i go but for now I realized (after a few hours) that the message body of the created by the react SDK and the verify method used in the python SDK are waay different. Judging by the content, I think python one is the outdated option. For now I've overriden the generate_message and verify methods to get this working. Below is my code if anyone facing the same issue,

def format_time_for_message(timestamp):
    time = timestamp.strftime("%Y-%m-%dT%H:%M:%S")
    microseconds = timestamp.strftime("%f")[0:3]
    formatted_time = f"{time}.{microseconds}Z"
    
    return formatted_time
    
def generate_message(payload: ExtendedPayloadData) -> str:
        """
        Generates an EIP-4361 compliant message to sign based on the login payload
        """

        message = ""

        # Add the domain and login address for transparency
        message += f"{payload.domain} wants you to sign in with your Ethereum account:\n{payload.address}\n\n"

        # Prompt user to make sure domain is correct to prevent phishing attacks
        message += "Please ensure that the domain above matches the URL of the current website.\n\n"

        message += f"Version: {payload.version}\n"

        # Add data fields in compliance with the EIP-4361 standard
        if payload.chain_id is not None:
            message += f"Chain ID: {payload.chain_id}\n"

        message += f"Nonce: {payload.nonce}\n"
        message += f"Issued At: {format_time_for_message(payload.issued_at)}\n"

        message += f"Expiration Time: {format_time_for_message(payload.expiration_time)}\n"

        message += f"Not Before: {format_time_for_message(payload.invalid_before)}"

        return message

def verify(
        domain: str,
        payload,
        options: VerifyOptions = VerifyOptions()
    ) -> str:
        """
        Server-side function to securely verify the address of the logged in client-side wallet
        by validating the provided client-side login request.

        ```python
        domain = "example.com"
        payload = sdk.auth.login(domain)

        # Verify the login request
        address = sdk.auth.verify(domain, payload)
        ```

        :param domain: The domain of the application to verify the login request for
        :param payload: The login payload to verify
        :return: The address of the logged in wallet that signed the payload
        """

        # Check that the intended domain matches the domain of the payload
        if payload.payload.domain != domain:
            raise Exception(
                f"Expected domain '{domain}' does not match domain on payload '{payload.payload.domain}'"
            )

        # Check that the payload hasn't expired
        current_time = datetime.utcnow()
        if current_time.replace(
            tzinfo=pytz.utc
        ) > payload.payload.expiration_time.replace(tzinfo=pytz.utc):
            raise Exception(f"Login request has expired")

        # If chain ID is specified, check that it matches the chain ID of the signature
        if (
            options.chain_id is not None
            and options.chain_id != payload.payload.chain_id
        ):
            raise Exception(
                f"Chain ID '{options.chain_id}' does not match payload chain ID '{payload.payload.chain_id}'"
            )

        # Check that the signing address is the claimed wallet address
        message = generate_message(payload.payload)
        user_address = sdk.auth._recover_address(message, payload.signature)
        
        if user_address.lower() != payload.payload.address.lower():
            raise Exception(
                f"The intended payload address '{payload.payload.address.lower()}' is not the payload signer"
            )

        return user_address

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions