Skip to content

feat: validate receiver account before sending tokens#582

Merged
vsavchyn-dev merged 7 commits into
near:mainfrom
Gmin2:feat/validate-receiver-before-send
May 8, 2026
Merged

feat: validate receiver account before sending tokens#582
vsavchyn-dev merged 7 commits into
near:mainfrom
Gmin2:feat/validate-receiver-before-send

Conversation

@Gmin2

@Gmin2 Gmin2 commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

Adds recipient validation to the tokens subcommand (send-near, send-ft,send-ft-call, send-nft), after network selection, two checks run: a network mismatch check that warns if the receiver looks like it belongs to a different network and an rpc existence check that warns if the receiver account doesn't exist on the selected network. Both checks prompt the user for confirmation and never block, the user can always choose to proceed. If the rpc is unreachable,the existence check is skipped silently.

image

Fixes #581

@Gmin2 Gmin2 requested a review from a team as a code owner April 2, 2026 10:36
Copilot AI review requested due to automatic review settings April 2, 2026 10:36
@github-project-automation github-project-automation Bot moved this to NEW❗ in DevTools Apr 2, 2026
@Gmin2 Gmin2 force-pushed the feat/validate-receiver-before-send branch from ea800ee to a22d122 Compare April 2, 2026 10:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds receiver account validation for token transfer commands to reduce accidental sends to the wrong network or to non-existent accounts, while still allowing users to proceed after explicit confirmation.

Changes:

  • Added common helper(s) to (1) warn on likely network mismatch and (2) check receiver existence via RPC with a confirmation prompt.
  • Wired the receiver validation into tokens send flows (NEAR, FT, FT-call, NFT) after network selection.
  • Implemented “cancel” behavior by returning an empty-actions transaction (which the existing pipeline treats as a cancellation).

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/common.rs Adds network-mismatch heuristic, RPC existence check, and shared confirmation prompt helper.
src/commands/tokens/send_near/mod.rs Calls receiver validation before creating the transfer transaction.
src/commands/tokens/send_nft/mod.rs Calls receiver validation before constructing the NFT transfer call.
src/commands/tokens/send_ft/amount_ft.rs Calls receiver validation before building FT transfer transaction.
src/commands/tokens/send_ft_call/amount_ft.rs Calls receiver validation before building FT transfer-call transaction.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/common.rs
Comment on lines +472 to +476
receiver_account_id, network_config.network_name
);
return ask_if_should_proceed();
}

Copilot AI Apr 2, 2026

Copy link

Choose a reason for hiding this comment

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

The early return ask_if_should_proceed() means that when the receiver looks like it’s on the wrong network and the user chooses to proceed, the RPC existence check is never run. If the intention is to run both validations (as described in the PR description), consider prompting on the network-mismatch warning and then continuing to the existence check when the user confirms.

Copilot uses AI. Check for mistakes.
Comment thread src/common.rs Outdated
Comment on lines +479 to +483
.block_on(get_account_state(
network_config,
receiver_account_id,
near_primitives::types::BlockReference::latest(),
));

Copilot AI Apr 2, 2026

Copy link

Choose a reason for hiding this comment

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

This function performs an RPC call via get_account_state unconditionally. In offline mode (GlobalContext.offline), this will still retry (with sleeps) and slow down “offline” flows. Consider adding an offline flag parameter (or passing GlobalContext) so the existence check can be skipped when offline, while still keeping the lightweight network-suffix heuristic.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

done (3490ab9)

Comment thread src/common.rs Outdated
ask_if_should_proceed()
}
// Dont block the transaction if we can't reach the RPC
Err(_) => Ok(true),

Copilot AI Apr 2, 2026

Copy link

Choose a reason for hiding this comment

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

Err(_) => Ok(true) will silently proceed not only when the RPC is unreachable, but also for other server-side errors (e.g., misconfigured RPC URL, unexpected server response). This can hide real problems. Consider matching specifically on JsonRpcError::TransportError(_) (skip silently as intended) and returning Err(err.into()) for other error variants, similar to how account existence is handled in create_account/fund_myself_create_account/sign_as.

Suggested change
Err(_) => Ok(true),
Err(near_jsonrpc_client::errors::JsonRpcError::TransportError(_)) => Ok(true),
Err(err) => Err(err.into()),

Copilot uses AI. Check for mistakes.
Comment thread src/common.rs Outdated
);
ask_if_should_proceed()
}
// Dont block the transaction if we can't reach the RPC

Copilot AI Apr 2, 2026

Copy link

Choose a reason for hiding this comment

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

Typo in comment: "Dont" → "Don't".

Suggested change
// Dont block the transaction if we can't reach the RPC
// Don't block the transaction if we can't reach the RPC

Copilot uses AI. Check for mistakes.
actions: vec![],
});
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You cannot use the user dialog in fn from previous context(). Some users use a script command that should end with "quiet".

@Gmin2 Gmin2 Apr 2, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added a verbosity param in validate_receiver_account_id to skip validation if in quiet mode to skip validation in fcb7f73

});
}

let amount_ft = if let crate::types::ft_properties::FungibleTokenTransferAmount::ExactAmount(ft) = &ft_transfer_amount {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Same reason as above

receiver_id: receiver_account_id.clone(),
actions: vec![],
});
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Same reason as above

receiver_id: nft_contract_account_id.clone(),
actions: vec![],
});
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Same reason as above

@Gmin2 Gmin2 requested a review from FroVolod April 2, 2026 12:59

@frolvanya frolvanya left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the contribution!

Found few minor issues, but overall looks good to me. Still probably have to be discussed with a team which option rpc vs string check is better

Comment thread src/common.rs Outdated
Comment thread src/common.rs Outdated
Comment thread src/common.rs Outdated
Comment thread src/common.rs Outdated
Comment thread src/common.rs
@FroVolod FroVolod marked this pull request as draft April 30, 2026 14:08
@FroVolod FroVolod marked this pull request as ready for review May 1, 2026 09:35

@vsavchyn-dev vsavchyn-dev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM, thanks for the PR!

@vsavchyn-dev vsavchyn-dev merged commit 6f35092 into near:main May 8, 2026
13 checks passed
@github-project-automation github-project-automation Bot moved this from NEW❗ to Shipped 🚀 in DevTools May 8, 2026
vsavchyn-dev pushed a commit that referenced this pull request May 8, 2026
## 🤖 New release

* `near-cli-rs`: 0.26.1 -> 0.26.2 (✓ API compatible changes)

<details><summary><i><b>Changelog</b></i></summary><p>

<blockquote>

##
[0.26.2](v0.26.1...v0.26.2)
- 2026-05-08

### Added

- validate receiver account before sending tokens
([#582](#582))
</blockquote>


</p></details>

---
This PR was generated with
[release-plz](https://github.com/release-plz/release-plz/).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Shipped 🚀

Development

Successfully merging this pull request may close these issues.

[Task] Check that recipient is valid before sending transaction

6 participants