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(wallet): add update seed storage password rpc #2317

Open
wants to merge 11 commits into
base: dev
Choose a base branch
from

Conversation

borngraced
Copy link
Member

@borngraced borngraced commented Jan 10, 2025

implement functionality to update the password for seed storage in the wallet in kdf with it's rpc method

Example JSON Request

{
       "method": "update_seed_storage_password",
	"userpass": "rpc_password",
	"mmrpc": "2.0",
	"params": {
		"current_password": "old_password123",
		"new_password": "new_password456"
	}
 }

Example JSON Response

{
    "result": "success"
}

Comment on lines 590 to 593
let encrypted_data = encrypt_mnemonic(&mnemonic, &req.new_password)?;
// save new encrypted mnemonic data with new password
save_encrypted_passphrase(&ctx, &wallet_name, &encrypted_data).await?;

Copy link
Collaborator

Choose a reason for hiding this comment

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

could u actually verify whether this would play well in wasm?
this call eventually does table.add_item, which if the item already exists will error ConstraintError (as per this).

We should use table.replace_item to be able to supported updates.

Copy link
Member Author

@borngraced borngraced Jan 10, 2025

Choose a reason for hiding this comment

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

done thank you 9e50c9f

@laruh
Copy link
Member

laruh commented Jan 10, 2025

Why the result is bool and not Ok if password updated successfully or Err if failed?
image

Comment on lines 558 to 570
/// # Arguments
/// - `ctx`: The shared context (`MmArc`) for the application.
/// - `req`: The `SeedPasswordUpdateRequest` containing the current and new passwords.
///
/// # Example
/// ```ignore
/// let request = SeedPasswordUpdateRequest {
/// current_password: "old_password".to_string(),
/// new_password: "new_password".to_string(),
/// };
/// let response = update_seed_storage_password_rpc(ctx, request).await?;
/// assert!(response.successful);
/// ```
Copy link
Member

Choose a reason for hiding this comment

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

We agreed not to describe function parameters in the function documentation.
Instead, provide documentation for the parameter types themselves (e.g. above SeedPasswordUpdateRequest).
It actually makes docs more readable. If I want to know nuances about each param or result I will go to its type doc comment.

Copy link
Member Author

Choose a reason for hiding this comment

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

removed

Comment on lines 547 to 554
/// `SeedPasswordUpdateResponse` represents the result of a
/// password update request.
/// It contains a boolean indicating whether the operation was successful.
#[derive(Serialize)]
pub struct SeedPasswordUpdateResponse {
/// `true` if the password update was successful, `false` otherwise.
successful: bool,
}
Copy link
Member

@laruh laruh Jan 10, 2025

Choose a reason for hiding this comment

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

reference to this comment #2317 (comment)
Such result representation confuses, I suggest to return just Ok(()) from update_seed_storage_password_rpc if success.
Or please explain why SeedPasswordUpdateResponse with successful: bool is preferable, if I missed the point.

Copy link
Member Author

@borngraced borngraced Jan 10, 2025

Choose a reason for hiding this comment

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

I don't want to return a null value for 200 status rpc response hence why I'm returning successful which is better than null

I will update the type field to be of type result: String instead(looks like a convention already) 9e50c9f

Copy link
Member

@laruh laruh Jan 12, 2025

Choose a reason for hiding this comment

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

well at least string is better then bool
upd: probably worth, string has "infinite" display variants

Copy link
Collaborator

Choose a reason for hiding this comment

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

I can see we normally return result: "Success"

Copy link
Member

@laruh laruh Jan 12, 2025

Choose a reason for hiding this comment

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

I can see we normally return result: "Success"

string type can have any msg, its not strict type
Not the best choice for successful result

Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess some existing new rpcs are not used by the GUI yet, so we could change them

Copy link
Member

@laruh laruh Jan 13, 2025

Choose a reason for hiding this comment

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

what's your conclusion on this?

@borngraced We should provide new type which is supposed to show successful operation and if there is no need to return other info.

Provided by dimxy here #2317 (comment)

const KDF_SUCCESS_RES: &str = "Success";
pub struct KdfSuccessRes;
impl Serialize for KdfSuccessRes {
    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(KDF_SUCCESS_RES)
    }
}
pub async fn update_seed_storage_password_rpc(
    ctx: MmArc,
    req: SeedPasswordUpdateRequest,
) -> MmResult<KdfSuccessRes, WalletsStorageRpcError> {
    ...
    Ok(KdfSuccessRes)
}

Ok(KdfSuccessRes) is supposed to be used instead of Ok(()), so response will be

{
  "mmrpc": "2.0",
  "result": "success",
  "id": null
}

at least for update storage password RPCs such approach should be used

I guess some existing new rpcs are not used by the GUI yet, so we could change them

@dimxy maybe, but if such RPCs are already in master, then it would be a breaking change, right? Even if some of these RPCs are quite new. I suggest checking if there are any other new RPCs still in dev branch and not in master. If everything is already in master, I don't think we should touch it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

  1. BTW we already have this in code:
    pub struct SuccessResponse(&'static str);
    which for empty results produces this json:
    {"mmrpc":"2.0","result":"success","id":null}

  2. Actually we have yet another empty 'success' result:
    pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNftError>
    which gives json:
    {"mmrpc":"2.0","result": null, "id":null}
    I think I like this one most of all because it provides simplest deserialisation (no need to switch between object or string for "result" value)

Copy link
Member Author

Choose a reason for hiding this comment

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

done

Copy link
Member

@laruh laruh Jan 17, 2025

Choose a reason for hiding this comment

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

done

Could you return just Ok(()) pls, as in the end @dimxy came to conclusion that he prefers MmResult<(), Err> more (what I suggested to have at the beginning)

string is still not a strict type in the response. In such rpcs like update, the 200 status is actually what is expected.

@borngraced borngraced changed the title feat(wallet): add support for updating seed storage password feat(wallet): add update seed storage password rpc Jan 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants