feat: Validate beneficiary account before deleting account#596
Conversation
|
@FroVolod Thank you for your contribution! Your pull request is now a part of the Race of Sloths! Current status: executed
Your contribution is much appreciated with a final score of 3! @vsavchyn-dev received 25 Sloth Points for reviewing and scoring this pull request. We would appreciate your feedback or contribution idea that you can submit here What is the Race of SlothsRace of Sloths is a friendly competition where you can participate in challenges and compete with other open-source contributors within your normal workflow For contributors:
For maintainers:
Feel free to check our website for additional details! Bot commands
|
There was a problem hiding this comment.
Pull request overview
This PR adds beneficiary account validation before constructing account deletion transactions, helping prevent delete actions from sending remaining funds to an invalid beneficiary.
Changes:
- Validates the beneficiary account in the dedicated
account delete-accountflow. - Validates
DeleteAccountbeneficiaries when finalizing manually constructed transactions.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/commands/account/delete_account/mod.rs |
Adds beneficiary validation before producing the delete-account transaction. |
src/commands/transaction/construct_transaction/skip_action/mod.rs |
Adds validation for delete-account actions in constructed transactions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if !crate::common::validate_receiver_account_id( | ||
| network_config, | ||
| &beneficiary_account_id, | ||
| item.global_context.verbosity, | ||
| item.global_context.offline, | ||
| )? { |
There was a problem hiding this comment.
That mentioned, do we really want to double-ask user?
| if let near_primitives::action::Action::DeleteAccount(near_primitives::transaction::DeleteAccountAction { beneficiary_id }) = action | ||
| && !crate::common::validate_receiver_account_id( | ||
| network_config, | ||
| beneficiary_id, | ||
| item.0.global_context.verbosity, | ||
| item.0.global_context.offline, | ||
| )? { |
vsavchyn-dev
left a comment
There was a problem hiding this comment.
Despite changing how the things are with deleting account - I think this is better in terms of UX, so that nobody can screw up by deleting and loosing their funds (esp on mainnet). LGTM
| scope: &<DeleteAccountAction as interactive_clap::ToInteractiveClapContextScope>::InteractiveClapContextScope, | ||
| ) -> color_eyre::eyre::Result<Self> { | ||
| let beneficiary_id: near_primitives::types::AccountId = scope.beneficiary_id.clone().into(); | ||
| if previous_context.signer_account_id == beneficiary_id { |
There was a problem hiding this comment.
Actually, we can continue using signer, but we just need to ensure that signer == receiver for DeleteAccount action specifically to prevent:

https://testnet.nearblocks.io/txns/5sr9DvD1QofwT8kssoHjuzw9rpktUcsG2f9W4nhtMgXP
Also, this would ensure that only one account will be deleted at max, so #596 (comment) could be irrelevant after this fix
There was a problem hiding this comment.
This is unnecessary check for the low-level construct transaction flow. I suggest we don't overcomplicate things here. There is nothing bad that could happen here.
There was a problem hiding this comment.
It's a single sender == receiver check for all actions except CreateAccount that prevents a submission of incorrect tx (the whole purpose of this pr btw), so I think it's better to add this check
There was a problem hiding this comment.
Then we should validate it for AddKey, DeleteKey, DeployCode - also require signer == receiver
There was a problem hiding this comment.
AddKey, DeleteKey, DeployCode
Yes?
sender == receivercheck for all actions exceptCreateAccount
I don't see how is this a problem. We don't need to do it in every single module and copy paste code everywhere. We just need to add a single check in skip_action flow
There was a problem hiding this comment.
I suggest moving this task to another PR.
|
🥁 Score it! @vsavchyn-dev, please score the PR with |
|
@race-of-sloths score 3 |
## 🤖 New release
* `near-cli-rs`: 0.27.0 -> 0.28.0 (⚠ API breaking changes)
### ⚠ `near-cli-rs` breaking changes
```text
--- failure constructible_struct_adds_field: externally-constructible struct adds field ---
Description:
A pub struct constructible with a struct literal has a new pub field. Existing struct literals must be updated to include the new field.
ref: https://doc.rust-lang.org/reference/expressions/struct-expr.html
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.48.0/src/lints/constructible_struct_adds_field.ron
Failed in:
field CliSignPrivateKey.nonce_index in /tmp/.tmpat9wFR/near-cli-rs/src/transaction_signature_options/sign_with_private_key/mod.rs:5
field InteractiveClapContextScopeForGenerateKeypair.signature_scheme in /tmp/.tmpat9wFR/near-cli-rs/src/commands/account/create_account/sponsor_by_faucet_service/add_key/autogenerate_new_keypair/mod.rs:3
field CliSignLedger.nonce_index in /tmp/.tmpat9wFR/near-cli-rs/src/transaction_signature_options/sign_with_ledger/mod.rs:18
field CliSignLegacyKeychain.nonce_index in /tmp/.tmpat9wFR/near-cli-rs/src/transaction_signature_options/sign_with_legacy_keychain/mod.rs:12
field CliSignKeychain.nonce_index in /tmp/.tmpat9wFR/near-cli-rs/src/transaction_signature_options/sign_with_keychain/mod.rs:9
field SignLedgerContext.nonce_index in /tmp/.tmpat9wFR/near-cli-rs/src/transaction_signature_options/sign_with_ledger/mod.rs:51
field InteractiveClapContextScopeForSignSeedPhrase.nonce_index in /tmp/.tmpat9wFR/near-cli-rs/src/transaction_signature_options/sign_with_seed_phrase/mod.rs:7
field CliSignAccessKeyFile.nonce_index in /tmp/.tmpat9wFR/near-cli-rs/src/transaction_signature_options/sign_with_access_key_file/mod.rs:5
field CliGenerateKeypair.signature_scheme in /tmp/.tmpat9wFR/near-cli-rs/src/commands/account/create_account/sponsor_by_faucet_service/add_key/autogenerate_new_keypair/mod.rs:3
field InteractiveClapContextScopeForSignPrivateKey.nonce_index in /tmp/.tmpat9wFR/near-cli-rs/src/transaction_signature_options/sign_with_private_key/mod.rs:5
field InteractiveClapContextScopeForSignLedger.nonce_index in /tmp/.tmpat9wFR/near-cli-rs/src/transaction_signature_options/sign_with_ledger/mod.rs:18
field InteractiveClapContextScopeForSignLegacyKeychain.nonce_index in /tmp/.tmpat9wFR/near-cli-rs/src/transaction_signature_options/sign_with_legacy_keychain/mod.rs:12
field InteractiveClapContextScopeForSignKeychain.nonce_index in /tmp/.tmpat9wFR/near-cli-rs/src/transaction_signature_options/sign_with_keychain/mod.rs:9
field InteractiveClapContextScopeForSignAccessKeyFile.nonce_index in /tmp/.tmpat9wFR/near-cli-rs/src/transaction_signature_options/sign_with_access_key_file/mod.rs:5
field CliSignSeedPhrase.nonce_index in /tmp/.tmpat9wFR/near-cli-rs/src/transaction_signature_options/sign_with_seed_phrase/mod.rs:7
--- failure enum_no_repr_variant_discriminant_changed: enum variant had its discriminant change value ---
Description:
The enum's variant had its discriminant value change. This breaks downstream code that used its value via a numeric cast like `as isize`.
ref: https://doc.rust-lang.org/reference/items/enumerations.html#assigning-discriminant-values
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.48.0/src/lints/enum_no_repr_variant_discriminant_changed.ron
Failed in:
variant TopLevelCommandDiscriminants::Extensions 7 -> 8 in /tmp/.tmpat9wFR/near-cli-rs/src/commands/mod.rs:60
variant TopLevelCommandDiscriminants::Extensions 7 -> 8 in /tmp/.tmpat9wFR/near-cli-rs/src/commands/mod.rs:60
variant AccountActionsDiscriminants::GetPublicKey 7 -> 8 in /tmp/.tmpat9wFR/near-cli-rs/src/commands/account/mod.rs:69
variant AccountActionsDiscriminants::AddKey 8 -> 9 in /tmp/.tmpat9wFR/near-cli-rs/src/commands/account/mod.rs:74
variant AccountActionsDiscriminants::DeleteKeys 9 -> 12 in /tmp/.tmpat9wFR/near-cli-rs/src/commands/account/mod.rs:89
variant AccountActionsDiscriminants::ManageStorageDeposit 10 -> 13 in /tmp/.tmpat9wFR/near-cli-rs/src/commands/account/mod.rs:94
variant AccountActionsDiscriminants::GetPublicKey 7 -> 8 in /tmp/.tmpat9wFR/near-cli-rs/src/commands/account/mod.rs:69
variant AccountActionsDiscriminants::AddKey 8 -> 9 in /tmp/.tmpat9wFR/near-cli-rs/src/commands/account/mod.rs:74
variant AccountActionsDiscriminants::DeleteKeys 9 -> 12 in /tmp/.tmpat9wFR/near-cli-rs/src/commands/account/mod.rs:89
variant AccountActionsDiscriminants::ManageStorageDeposit 10 -> 13 in /tmp/.tmpat9wFR/near-cli-rs/src/commands/account/mod.rs:94
--- failure enum_variant_added: enum variant added on exhaustive enum ---
Description:
A publicly-visible enum without #[non_exhaustive] has a new variant.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#enum-variant-new
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.48.0/src/lints/enum_variant_added.ron
Failed in:
variant AccountActionsDiscriminants:ViewGasKeyNonces in /tmp/.tmpat9wFR/near-cli-rs/src/commands/account/mod.rs:64
variant AccountActionsDiscriminants:FundGasKey in /tmp/.tmpat9wFR/near-cli-rs/src/commands/account/mod.rs:79
variant AccountActionsDiscriminants:WithdrawFromGasKey in /tmp/.tmpat9wFR/near-cli-rs/src/commands/account/mod.rs:84
variant AccountActionsDiscriminants:ViewGasKeyNonces in /tmp/.tmpat9wFR/near-cli-rs/src/commands/account/mod.rs:64
variant AccountActionsDiscriminants:FundGasKey in /tmp/.tmpat9wFR/near-cli-rs/src/commands/account/mod.rs:79
variant AccountActionsDiscriminants:WithdrawFromGasKey in /tmp/.tmpat9wFR/near-cli-rs/src/commands/account/mod.rs:84
variant CliTopLevelCommand:GenerateKeypair in /tmp/.tmpat9wFR/near-cli-rs/src/commands/mod.rs:16
variant CliAccountActions:ViewGasKeyNonces in /tmp/.tmpat9wFR/near-cli-rs/src/commands/account/mod.rs:27
variant CliAccountActions:FundGasKey in /tmp/.tmpat9wFR/near-cli-rs/src/commands/account/mod.rs:27
variant CliAccountActions:WithdrawFromGasKey in /tmp/.tmpat9wFR/near-cli-rs/src/commands/account/mod.rs:27
variant TopLevelCommandDiscriminants:GenerateKeypair in /tmp/.tmpat9wFR/near-cli-rs/src/commands/mod.rs:56
variant TopLevelCommandDiscriminants:GenerateKeypair in /tmp/.tmpat9wFR/near-cli-rs/src/commands/mod.rs:56
--- failure function_missing: pub fn removed or renamed ---
Description:
A publicly-visible function cannot be imported by its prior path. A `pub use` may have been removed, or the function itself may have been renamed or removed entirely.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#item-remove
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.48.0/src/lints/function_missing.ron
Failed in:
function near_cli_rs::transaction_signature_options::send::sleep_after_error, previously in file /tmp/.tmppWZUdR/near-cli-rs/src/transaction_signature_options/send/mod.rs:193
--- failure trait_method_added: pub trait method added ---
Description:
A non-sealed public trait added a new method without a default implementation, which breaks downstream implementations of the trait
ref: https://doc.rust-lang.org/cargo/reference/semver.html#trait-new-item-no-default
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.48.0/src/lints/trait_method_added.ron
Failed in:
trait method near_cli_rs::common::RpcQueryResponseExt::gas_key_nonces_view in file /tmp/.tmpat9wFR/near-cli-rs/src/common.rs:3499
```
<details><summary><i><b>Changelog</b></i></summary><p>
<blockquote>
##
[0.28.0](v0.27.0...v0.28.0)
- 2026-07-02
### Added
- sign transactions with a gas key (nonce_index)
([#608](#608))
- gas-key support (nearcore 2.13)
([#607](#607))
- post-quantum (ML-DSA-65) key generation (draft)
([#605](#605))
- Validate beneficiary account before deleting account
([#596](#596))
### Fixed
- Fixed output information for transaction status "Started"
([#594](#594))
### Other
- Fixed NPM Trusted Publishing
([#603](#603))
</blockquote>
</p></details>
---
This PR was generated with
[release-plz](https://github.com/release-plz/release-plz/).
---------
Co-authored-by: r-near <[email protected]>




No description provided.