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

feat: add the sign feature #24

Merged
merged 8 commits into from
Aug 29, 2022
Merged

feat: add the sign feature #24

merged 8 commits into from
Aug 29, 2022

Conversation

kayagokalp
Copy link
Member

@kayagokalp kayagokalp commented Aug 25, 2022

About this PR

closes #7.

This PR introduces a new command sign to the forc-wallet. Currently sign accepts 2 parameters:

  1. Transaction id
  2. Account index of the account that we want to sign this transaction with

In this first iteration of development (where we are trying to enable our users to sign deployment transactions) The usual signing process while deploying a contract currently looks like the following:

  1. Running forc-deploy will ask the user to input the address of the wallet they are going to be signing with. To get that the user can either run the forc-wallet list and look under the address section of the desired account or run forc-wallet account <account_index> to get the address. This reports a transaction id and waits for the signature.
  2. User runs forc-wallet sign <transaction_id> <account_index> and forc-wallet asks for the password for the wallet as we do need to decrypt it before signing. If the password is correct, the signature is generated and reported back to the user.
  3. In the meantime forc-deploy is waiting for the signature to be inserted, once the user inserts the generated signature from the forc-wallet it adds it to the witnesses and submits the transaction.

All the required functionality from the wallet's end is ready with this PR and once FuelLabs/sway#2629 is merged forc-deploy will also behave as described.

@kayagokalp kayagokalp added the enhancement New feature or request label Aug 25, 2022
@kayagokalp kayagokalp self-assigned this Aug 25, 2022
@kayagokalp kayagokalp requested review from adlerjohn, mitchmindtree and a team August 25, 2022 14:26
@kayagokalp kayagokalp marked this pull request as ready for review August 25, 2022 14:26
@kayagokalp kayagokalp enabled auto-merge (squash) August 25, 2022 14:27
Copy link
Member

@JoshuaBatty JoshuaBatty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one. Looks reasonable, will defer to @mitchmindtree

@JoshuaBatty JoshuaBatty requested a review from a team August 26, 2022 00:14
@kayagokalp
Copy link
Member Author

I am converting this to draft, because just now I managed to sign a transaction and while doing so I had to make some changes. I will update the description while pushing them.

@kayagokalp kayagokalp marked this pull request as draft August 26, 2022 15:59
auto-merge was automatically disabled August 26, 2022 15:59

Pull request was converted to draft

@kayagokalp kayagokalp marked this pull request as ready for review August 26, 2022 20:16
@kayagokalp kayagokalp enabled auto-merge (squash) August 26, 2022 22:26
@kayagokalp
Copy link
Member Author

This is ready to go! I added the plain address section to the list command but I believe the naming there could be improved. Since in the current implementation forc-deploy does not communicate with forc-wallet as a lib, we do need a way of providing the wallet that we are going to be signing the transaction as forc-deploy will prepare the deployment transaction and provide the id to the user (1st step in the description). So the address that we are seeing under the address section of the forc-wallet list (or forc-wallet account <account_index>) is for that.

The newly added plain address section is very helpful while testing as to sign a contract we need to add coins to that account through chain config. In the "chain config" we need to provide the plain address, so I added that section to the list command.

I can also improve the CLI experience (with some suggestions 😅) in this PR too, but if you prefer reaching a point where we can complete the whole signing process first and iterate over it for better UX I am also down for that too.

src/account.rs Outdated
Comment on lines 45 to 46
println!("Wallet address: {}", wallet.address());
println!("Wallet plain address: {}", wallet.address().hash());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the plain address the hash of the pubkey? I don't think that should be printed out by default. Regular end-users should be using bech32 addresses exclusively. Pubkey hash should be something users need to purposefully seek out as advanced users.

Copy link
Member Author

@kayagokalp kayagokalp Aug 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the hash of the pubkey, since it is useful/needed while testing in local as (if I am not mistaken) chain config requires that for funding the wallet with initial coins. But this is indeed something an advanced user would use. Maybe we can introduce a flag to account command in a future PR such that executing something like forc-wallet account <account_index> --hashed would return this. If this sounds good I can create an issue

src/list.rs Outdated
"[{}] {} 0x{}",
index,
address,
Bech32Address::from_str(&address)?.hash()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

src/sign.rs Outdated
};
let tx_id = Bytes32::from_str(id).map_err(|e| anyhow!("{}", e))?;
let secret_key = derive_account_with_index(&wallet_path, account_index)?;
let message = unsafe { Message::from_bytes_unchecked(*tx_id) };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For clarity, this should be called message hash?

Copy link
Contributor

@mitchmindtree mitchmindtree left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just tested this locally with your forc deploy branch and it appears to be working nicely!

)?;
let phrase_recovered = eth_keystore::decrypt_key(path.join(".wallet"), password)?;
let phrase = String::from_utf8(phrase_recovered)?;
let derive_path = format!("m/44'/1179993420'/{}'/0/0", account_index);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we should be using an upstream const and/or function for constructing this path? E.g. at least a wallet_account_derive_path function or similar. It's probably fine for now, but I've opened an issue to follow-up: #28.

@kayagokalp kayagokalp merged commit d78bba3 into master Aug 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feat: add the sign feature
4 participants