Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I implement Proof of account with sdk? #47

Open
davit555 opened this issue Sep 30, 2022 · 3 comments
Open

How can I implement Proof of account with sdk? #47

davit555 opened this issue Sep 30, 2022 · 3 comments

Comments

@davit555
Copy link

davit555 commented Sep 30, 2022

It seems every other sdk has such functionality (C#, Go, Node...) and I don't know how to verify proof of account with the python SDK ...

In particular
when js client sends the authentication with
.put("fcl.accountProof.resolver", resolver) adding to the config

where the resolver is something like this

const resolver = async () => { return { appIdentifier: "MyAppIdentifier", nonce: "75f8587e5bd5f9dcc9909d0dae1f0ac5814458b2ae129620502cb936fde7120a" }

then it gets some signature

{ "f_type": "Service", "f_vsn": "1.0.0", "type": "account-proof", "method": "DATA", "uid": "blocto#account-proof", "data": { "f_type": "account-proof", "f_vsn": "2.0.0", "signatures": [ { "f_type": "CompositeSignature", "f_vsn": "1.0.0", "addr": "0x46dfa5325a7bb983", "keyId": 1, "signature": "ce972efe49abc05a3bc8d71ff1e48e42d8d869a3ca30efb5e39ebbdb3f8a37fffb6f3bddd8eeacf803755c2726b64a9049be8360e9d2889ec914a301ab73da3d" } ], "address": "0x46dfa5325a7bb983", "timestamp": null, "nonce": "75f8587e5bd5f9dcc9909d0dae1f0ac5814458b2ae129620502cb936fde7120a" } }

then I need to somehow verify this signature from maybe
verify_user_signature

method but I don't know what to pass as message parameter...

do I need to encode the message like rlp or perform some other serialization....

Please help to figure out this

@davit555 davit555 changed the title How can I implement Proof of account withs sdk? How can I implement Proof of account with sdk? Oct 3, 2022
@gurd33pS1ngh
Copy link

I need same functionality . Do you able to solve it? @davit555

@davit555
Copy link
Author

davit555 commented Feb 15, 2023

yes
I have manually implemented it... but it is too strange that it didn't exist in sdk....
@gurd33pS1ngh

@davit555
Copy link
Author

davit555 commented Feb 15, 2023

from flow_py_sdk.exceptions import PySDKError
from flow_py_sdk.client import AccessAPI
from flow_py_sdk.script import Script
from flow_py_sdk.utils import CompositeSignature
from rlp import encode


async def verify(app_identifier, account_address, nonce, blockchain_network, signature, key_id, env, port=9000):
    async with flow_client(
            host=blockchain_network, port=port
    ) as client:
        account = await client.get_account(
            address=account_address.to_bytes((account_address.bit_length() + 7) // 8, "big")
        )

        fields = encode(
            [
                app_identifier,  # String
                account.address,  # Byte
                bytes.fromhex(nonce)  # Byte from hex number
            ]
        )

        signer = CompositeSignature(
            addr=account.address.hex(),
            keyId=key_id,
            signature=signature
        )
        is_verified = await verify_account_proof_signatures(
            client=client, message=bytes(fields.hex(), "utf-8"), composite_signatures=[signer], env=env
        )
        return is_verified


async def verify_account_proof_signatures(*, client: AccessAPI, message: bytes,
                                          composite_signatures: list[CompositeSignature], env: str
                                          ) -> bool:
    # if there is no signature return False
    if len(composite_signatures) == 0:
        return False

    # it does not make sense for the signatures to be from different addresses
    if any(x.addr != composite_signatures[0].addr for x in composite_signatures):
        raise PySDKError("All signatures must be from the same address")

    address = cadence.Address.from_hex(composite_signatures[0].addr)
    signatures = cadence.Array(
        [cadence.String(x.signature) for x in composite_signatures]
    )
    key_indexes = cadence.Array([cadence.Int(x.keyId) for x in composite_signatures])
    cadence_message = cadence.String(str(message, "utf-8"))

    if env == "Prod":
        address_of_network = "0xdb6b70764af4ff68"
    else:
        address_of_network = "0x5b250a8a85b44a67"

    script = Script(
        code=
        f'''        
        import FCLCrypto from {address_of_network}
        pub fun main(address: Address,
                     message: String,
                     keyIndices: [Int],
                     signatures: [String]): Bool''' + '''{
            return FCLCrypto.verifyAccountProofSignatures(address: address, message: message, keyIndices: keyIndices, 
            signatures: signatures)
         }   
        ''',
        arguments=[
            address,
            cadence_message,
            key_indexes,
            signatures,
        ],
    )
    script_result = await client.execute_script(script)

    if script_result is None:
        return False

    return script_result.as_type(cadence.Bool).value

for anyone that needs that missing code part...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants