rocklabs-io / ic-py

Python Agent Library for the DFINITY Internet Computer
MIT License
125 stars 25 forks source link

Struggling encoding params #68

Closed yugocabrio closed 2 years ago

yugocabrio commented 2 years ago

Hello. Let me ask you a question.I am building a program to automate social networking posts. However, I'm struggling to understand how to encode the params correctly for a types record.

The picture shows the correct parameters returned in Invalid record error.

Screen Shot 2022-06-23 at 18 53 40

These are the parameters I set. Can you please tell me if there are any mistakes?

types = Types.Record({
        'quoted_resource':Types.Nat64,
        'user_tags': Types.Vec(Types.Text),
        'nft_image_url':Types.Opt(Types.Text),
        'hashtags':Types.Vec(Types.Text),
        '"text"':Types.Text,
        'image':Types.Opt(Types.Record({'canister_id':Types.Principal,'image_id':Types.Text,'timestamp':Types.Nat64,'format':Types.Text})),
    }
)

values = {
        'quoted_resource':0,
        'user_tags':[], 
        'nft_image_url':"",
        'hashtags':[],
        '"text"':"Hello.How are you doing?",
        'image':[],
}

Thanks for the great library. Sincerely,

Myse1f commented 2 years ago

Can you provide the code that can reproduce the error?

For Opt type, it must be an empty array or an array with only 1 element. So nft_image_urlshould be [] or ["some text"].

With the code below, I can encode the parameter:

types = Types.Record({
        'quoted_resource':Types.Nat64,
        'user_tags': Types.Vec(Types.Text),
        'nft_image_url':Types.Opt(Types.Text),
        'hashtags':Types.Vec(Types.Text),
        '"text"':Types.Text,
        'image':Types.Opt(Types.Record({'canister_id':Types.Principal,'image_id':Types.Text,'timestamp':Types.Nat64,'format':Types.Text})),
    }
)

values = {
        'quoted_resource':0,
        'user_tags':[], 
        'nft_image_url': [],
        'hashtags':[],
        '"text"':"Hello.How are you doing?",
        'image':[],
}

encode([{
  'type': types,
  'value': values
}])

#b'DIDL\x05mqnql\x04\xb3\xc4\xb1\xf2\x04h\xff\xba\x8c\xa2\x08q\xd6\xa9\xbb\xae\nx\xb7\x9e\xba\xec\x0fqn\x02l\x06\x85\xdb\xa8\xa4\x01x\x8d\x9d\xb4\xb5\x01\x00\xc8\x92\x9a\x8f\x02\x01\xa7\xc7\xb7\xbe\x02\x00\xf3\x9e\xee\xad\nq\xdb\xbe\xa4\xeb\x0b\x03\x01\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18Hello.How are you doing?\x00'
yugocabrio commented 2 years ago

I am learning about Internet Identity's delegation mechanism and I found out that Python agent can also do update calls. So I would like to try the update call of distrikt. Here is the entire code. I modified it to your advice, however, It could not update call. Displaying my principal ID of distrikt is got well. https://github.com/0xYGicp/post_updatecall/blob/main/main.py

And also this is the payload of the posting function of distrikt.

Screen Shot 2022-06-24 at 20 47 18
Myse1f commented 2 years ago

I think the key '"text"' should be 'text'.
In candid text conflict with keyword text. So it adds a quotation.

What I mean is

types = Types.Record({
        'quoted_resource':Types.Nat64,
        'user_tags': Types.Vec(Types.Text),
        'nft_image_url':Types.Opt(Types.Text),
        'hashtags':Types.Vec(Types.Text),
        'text':Types.Text,
        'image':Types.Opt(Types.Record({'canister_id':Types.Principal,'image_id':Types.Text,'timestamp':Types.Nat64,'format':Types.Text})),
    }
)

values = {
        'quoted_resource':0,
        'user_tags':[], 
        'nft_image_url': [],
        'hashtags':[],
        'text':"Hello.How are you doing?",
        'image':[],
}
yugocabrio commented 2 years ago

Thanks for your advice, it was a great help. It worked out well.

yugocabrio commented 2 years ago

@Myse1f I am having difficulty understanding how II works, so could you please answer my question?

Is it possible to automate prepare_delegation and get_delegation by using ic-py when logging into an existing dapps with II? It means a method that does not take identity or delegation from local storage. I don't think I can do it that way because it is the front end of that dapp that generates the session key. Am I right in my thinking?

When you are logged into dapps with II, you are signing the payload with a private session key, right? So how can I sign the payload with just ic-identity or ic_delegation in local storage?

I wonder why it can be signed without a private session key there.

bodily11 commented 2 years ago

Hey 0xYGicp, you should just DM me on Twitter and I'll show you how to do it. It is a bit tricky, but actually isn't that crazy.

@BobBodily on Twitter.

bodily11 commented 2 years ago

I spent at least 40 hours reading the Internet Identity Spec to figure out how to automate II, so happy to share my learnings.