janezpodhostnik / flow-py-sdk

Unofficial flow blockchain python sdk
MIT License
35 stars 26 forks source link

verify_user_signature returning false when true is expected #65

Open alexisprunier opened 4 weeks ago

alexisprunier commented 4 weeks ago

Hi,

At first, thanks for the SDK you put at disposal! Very useful!

I have an issue with the recent v2 of the library. I have adapted my backend python code to keep having the signature verification of Dapper wallets.

My code with v1: https://github.com/alexisprunier/mfl-assistant/blob/main/api/utils/flow.py My code with v2: https://github.com/alexisprunier/mfl-assistant/blob/home/api/utils/flow.py

Since the usage of the v2, I only get the false value from the flow_py_sdk.utils.verify_user_signature function.

The parameters seems to be very similar. The PY objects also seems to do the same work. I see that the major modification for this feature is the script, probably due to the flow network upgrade.

I can ensure that I reach the following piece of code.

return script_result.as_type(cadence.Bool).value

Is there any hint you could give to me about this?

Regards, Alexis

janezpodhostnik commented 3 weeks ago

Thank you for reporting!

I'll take a look soon (likely tomorrow). There is probably a bug (or a change) in the result parsing.

janezpodhostnik commented 2 weeks ago

It looks like your previous iteration of the code was using the FCLCrypto smart contract to verify the user signatures. The python sdk does not use FCLCrypto, but instead runs similar logic in the script body. The major difference I can see and that probably applies here, is this part from the FCLCrypto contract:

        // Non-custodial users can only generate a weight of 999
        return totalWeight >= 999.0

(shouldn't the comment say "Custodial users ..."?)

So since you are doing verification on dapper wallets this might apply. Can you give me an address you tested this on so I can confirm this theory?

If it is correct I think I might add a optional parameter for the case of custodial users.

alexisprunier commented 2 weeks ago

Hi,

Here is the address I use: 0xdf26376de6cba19e

I know that several users have the same issue with other addresses. My case is not isolated.

Thanks for all this.

Regards, Alexis

janezpodhostnik commented 2 weeks ago

Thanks!

It looks like the 999 weight is not a problem for that particular scenario. I'll try to replicate the scenario.

janezpodhostnik commented 2 weeks ago

@alexisprunier In your code can you try

 signature_is_valid = await utils.verify_user_signature(
-           message=bytes(fields.hex(), "utf-8"),
+           message=fields,
            client=client,
            composite_signatures=[signer],
        )

FCLCrypto expects a hex encoded message, but the python-sdk currently expects utf-8 bytes.

See these lines in the example: https://github.com/janezpodhostnik/flow-py-sdk/blob/ac0bbb931e7748d854c70f3e85aef3da0aacf6f9/examples/user_message_examples.py#L38 https://github.com/janezpodhostnik/flow-py-sdk/blob/ac0bbb931e7748d854c70f3e85aef3da0aacf6f9/examples/user_message_examples.py#L55

alexisprunier commented 2 weeks ago

Hi,

I have this error with the suggested change:

2024-09-30 18:35:19 Traceback (most recent call last):
2024-09-30 18:35:19   File "/usr/local/lib/python3.9/site-packages/uvicorn/protocols/http/httptools_impl.py", line 375, in run_asgi
2024-09-30 18:35:19     result = await app(self.scope, self.receive, self.send)
2024-09-30 18:35:19   File "/usr/local/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__
2024-09-30 18:35:19     return await self.app(scope, receive, send)
2024-09-30 18:35:19   File "/usr/local/lib/python3.9/site-packages/fastapi/applications.py", line 1054, in __call__
2024-09-30 18:35:19     await super().__call__(scope, receive, send)
2024-09-30 18:35:19   File "/usr/local/lib/python3.9/site-packages/starlette/applications.py", line 116, in __call__
2024-09-30 18:35:19     await self.middleware_stack(scope, receive, send)
2024-09-30 18:35:19   File "/usr/local/lib/python3.9/site-packages/starlette/middleware/errors.py", line 186, in __call__
2024-09-30 18:35:19     raise exc
2024-09-30 18:35:19   File "/usr/local/lib/python3.9/site-packages/starlette/middleware/errors.py", line 164, in __call__
2024-09-30 18:35:19     await self.app(scope, receive, _send)
2024-09-30 18:35:19   File "/usr/local/lib/python3.9/site-packages/starlette/middleware/cors.py", line 91, in __call__
2024-09-30 18:35:19     await self.simple_response(scope, receive, send, request_headers=headers)
2024-09-30 18:35:19   File "/usr/local/lib/python3.9/site-packages/starlette/middleware/cors.py", line 146, in simple_response
2024-09-30 18:35:19     await self.app(scope, receive, send)
2024-09-30 18:35:19   File "/usr/local/lib/python3.9/site-packages/starlette/middleware/exceptions.py", line 62, in __call__
2024-09-30 18:35:19     await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
2024-09-30 18:35:19   File "/usr/local/lib/python3.9/site-packages/starlette/_exception_handler.py", line 55, in wrapped_app
2024-09-30 18:35:19     raise exc
2024-09-30 18:35:19   File "/usr/local/lib/python3.9/site-packages/starlette/_exception_handler.py", line 44, in wrapped_app
2024-09-30 18:35:19     await app(scope, receive, sender)
2024-09-30 18:35:19   File "/usr/local/lib/python3.9/site-packages/starlette/routing.py", line 746, in __call__
2024-09-30 18:35:19     await route.handle(scope, receive, send)
2024-09-30 18:35:19   File "/usr/local/lib/python3.9/site-packages/starlette/routing.py", line 288, in handle
2024-09-30 18:35:19     await self.app(scope, receive, send)
2024-09-30 18:35:19   File "/usr/local/lib/python3.9/site-packages/starlette/routing.py", line 75, in app
2024-09-30 18:35:19     await wrap_app_handling_exceptions(app, request)(scope, receive, send)
2024-09-30 18:35:19   File "/usr/local/lib/python3.9/site-packages/starlette/_exception_handler.py", line 55, in wrapped_app
2024-09-30 18:35:19     raise exc
2024-09-30 18:35:19   File "/usr/local/lib/python3.9/site-packages/starlette/_exception_handler.py", line 44, in wrapped_app
2024-09-30 18:35:19     await app(scope, receive, sender)
2024-09-30 18:35:19   File "/usr/local/lib/python3.9/site-packages/starlette/routing.py", line 70, in app
2024-09-30 18:35:19     response = await func(request)
2024-09-30 18:35:19   File "/usr/local/lib/python3.9/site-packages/fastapi/routing.py", line 299, in app
2024-09-30 18:35:19     raise e
2024-09-30 18:35:19   File "/usr/local/lib/python3.9/site-packages/fastapi/routing.py", line 294, in app
2024-09-30 18:35:19     raw_response = await run_endpoint_function(
2024-09-30 18:35:19   File "/usr/local/lib/python3.9/site-packages/fastapi/routing.py", line 191, in run_endpoint_function
2024-09-30 18:35:19     return await dependant.call(**values)
2024-09-30 18:35:19   File "/app/./main.py", line 98, in login
2024-09-30 18:35:19     if await verify_signature(service):
2024-09-30 18:35:19   File "/app/./utils/flow.py", line 37, in verify_signature
2024-09-30 18:35:19     signature_is_valid = await utils.verify_user_signature(
2024-09-30 18:35:19   File "/usr/local/lib/python3.9/site-packages/flow_py_sdk/utils/verify_user_signature.py", line 33, in verify_user_signature
2024-09-30 18:35:19     cadence_message = cadence.String(str(message, "utf-8"))
2024-09-30 18:35:19 UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf8 in position 0: invalid start byt
alexisprunier commented 2 weeks ago

To bring more context:

I am using this javacript library to handle the login:

"@onflow/fcl": "^1.11.0",

All the users of the app gets identified via the Dapper wallet.

It looks like, when you get logged, you get a signature based on a message composed of the wallet address, the app name (in this case, "mfl-assistant" and the nonce, generated by the backend of the app.

In our case, the message seems to be wrong. The content of it, in this flow.py file, hasn't changed. It has been working properly. The element that has change is the version of Flow and the version of the flow-py-sdk that has been upgraded.

Is that possible that:

Would you have any suggestions?

Thanks in advance for your reply.

Regards, Alexis

alexisprunier commented 5 days ago

Hey, just a little up on that topic.

Btw, you can reproduce quite easily with docker by executing "docker compose up" from the ".docker" directory of the project on this branch:

https://github.com/alexisprunier/mfl-assistant/tree/home

Then you can go on the webapp and click the "login" button on the bottom left to trigger the piece of code.

Regards