What can go wrong?
There are three common failure modes when an end user enters a recipient account:- Invalid format — the input is not a valid NEAR account ID (wrong characters, length, etc.).
- Unfunded implicit /
0xaccount — the address corresponds to a key pair, but no one has activated the account by funding it. Funds sent here are reachable only by whoever holds the private key. - Typo of an existing account — the entered value is a valid, existing account, but not the one the user intended. This is the hardest case to catch and benefits the most from confirmation UX.
.near, .tg, .sweat, implicit, 0x, deterministic), see the Address (Account ID) reference.
If you delete an account and the beneficiary account does not exist, all the NEAR funds will be lost
Validation strategy
Apply these checks in order. Each step is cheap and rules out a specific failure mode. The strategy is language-agnostic — the examples below show JavaScript (for frontends) and Rust (for backends, CLIs, and indexers).1
Validate the format
Reject inputs that cannot be valid NEAR account IDs before doing any network call. A NEAR account ID must:
- Be 2 to 64 characters long
- Contain only lowercase letters (
a-z), digits (0-9), and the separators.,-,_ - Not start or end with a separator, and not have two separators in a row
0x...) and deterministic (0s...) addresses are 42 characters (the 0x/0s prefix plus 40 lowercase hex characters). Implicit accounts are 64 lowercase hex characters.- 🌐 JavaScript
- 🦀 Rust
2
Classify the address type
Once the format is valid, classify the account so you can apply the right rules:This lets your UI explain to the user what kind of account they are about to send to (e.g. “This looks like an Ethereum-style address. Make sure the recipient controls the private key.”).
- 🌐 JavaScript
- 🦀 Rust
3
Check whether the account exists on chain
Call the RPC
view_account method. If the account exists you will receive its amount, code_hash, and storage_usage; if it does not, the RPC returns an error code such as AccountDoesNotExist or UNKNOWN_ACCOUNT.- 🌐 near-api-js
- 🦀 near-jsonrpc-client
- 🦀 near-api-rs
- cURL
4
Apply recipient-class rules
Combine the classification and the existence check into a decision:
5
Allowlist supported assets and add confidence signals
For higher-value transfers (or as a default for new recipients), layer an asset allowlist and other confidence signals on top of the existence check:
- Verified asset allowlist: map every asset your app supports to its exact token-contract account ID. Never infer that a token is legitimate from a symbol, name, or an account ID that looks similar. For example, the USD₮ contract on NEAR is
usdt.tether-token.near, notusdt.near. You can use Rhea Finance’s on-chainget_whitelisted_tokensresult fromv2.ref-finance.nearas an input to your list. It is Rhea’s DEX trading allowlist, not a universal security guarantee, so review and own the list you present to users. - First-time recipient confirmation: if the user has never sent to this account before, require a second confirmation step or suggest a small test transaction before the real transfer.
- Token-specific registration: for fungible token transfers, verify the recipient is registered with the FT contract (
storage_balance_of). If not, batch astorage_depositaction — otherwise the transfer will fail.
UI recommendations
Validation is only useful if the user can act on it. A few UX patterns that work well:- Show the resolved account inline as the user types — name, balance preview, and “exists” indicator. This catches typos before the user clicks Send.
- Distinguish blocking errors from warnings. Invalid format and non-existent named accounts should disable the Send button. Unfunded implicit /
0xaccounts and low-activity accounts should require an extra confirmation, not a block. - Always show the full account ID in the confirmation step — not just a truncated
abc...xyz. Many losses come from look-alike characters in the middle of a long hex string. - Suggest a test transaction when the recipient looks suspicious. Sending
0.01 NEARfirst costs almost nothing and surfaces problems before larger amounts are at risk.
See also
- Address (Account ID) — the canonical reference for the account types you will be validating.
- Avoiding Token Loss — protocol-level scenarios where funds become irrecoverable.
- RPC:
view_account— the underlying RPC call used for the existence check. - Handling NEAR Types — converting balances and timestamps when displaying recipient data.