NEAR Intents: Withdrawals
How to withdraw tokens from the Verifier contract
After a successful deposit, tokens are assigned to your account in the Verifier contract. You retain full ownership and control, and can withdraw at any time.
Withdrawal methods
There are two ways to withdraw tokens:
- Direct function call on the Verifier contract
- Signed intent submitted via
execute_intents
[!NOTE]
When using direct function calls, the token ID is used without a prefix (e.g.,
wrap.near).When using signed intents, the token ID is prefixed (e.g.,
nep141:wrap.near).
Withdrawing fungible tokens (NEP-141)
The Verifier contract exposes ft_withdraw for direct withdrawals and FtWithdraw for intent-based withdrawals.
Via direct function call
Replace <token-contract> with the token's contract address and adjust the amount for the token's decimal precision.
NEAR CLI
near call intents.near ft_withdraw \
'{"token": "<token-contract>", "receiver_id": "your-account.near", "amount": "<amount>"}' \
--deposit 0.000000000000000000000001 \
--gas 100000000000000 \
--useAccount your-account.near \
--networkId mainnet
NEAR API JS
import { Account, JsonRpcProvider, teraToGas, KeyPairString } from "near-api-js";
const accountId = "your-account.near";
const privateKey = "ed25519:3D4YudU..." as KeyPairString;
const provider = new JsonRpcProvider({ url: "https://rpc.fastnear.com" });
const account = new Account(accountId, provider, privateKey);
await account.callFunction({
contractId: "intents.near",
methodName: "ft_withdraw",
args: {
token: "<token-contract>",
receiver_id: "your-account.near",
amount: "<amount>",
},
gas: teraToGas("100"),
deposit: 1n, // 1 yoctoNEAR
});
See contract interaction example in near-api-examples repository.
| Parameter | Description |
|---|---|
token |
The token contract to withdraw (e.g., wrap.near for wNEAR). No prefix for direct calls. |
receiver_id |
The NEAR account that will receive the withdrawn tokens. |
amount |
The amount in the token's smallest unit. Each token has different decimals (e.g., wNEAR has 24, USDC has 6). |
--deposit |
1 yoctoNEAR, required for the withdrawal call. |
--gas |
100 TGas to cover the cross-contract call. |
Via signed intent
Submit a signed FtWithdraw intent through execute_intents. Withdraw intents (ft_withdraw, nft_withdraw, mt_withdraw) use unprefixed token IDs (e.g., usdc.near). Token prefixes like nep141: are only used in transfer and token_diff intents.
[!WARNING]
Your public key must be registered with the Verifier contract before you can submit signed intents. For named accounts, call
add_public_keyonintents.near. Implicit accounts skip this step. See Account Abstraction for details.
{
"standard": "nep413",
"payload": {
"recipient": "intents.near",
"nonce": "Vij2xgAlKBKzgNPJFViEQRhPvveC+P9xRwOXFW/IK5w=",
"message": "{\"deadline\":\"2025-05-20T13:29:34.360380Z\",\"intents\":[{\"intent\":\"ft_withdraw\",\"token\":\"wrap.near\",\"receiver_id\":\"alice.near\",\"amount\":\"1000\"}],\"signer_id\":\"user1.test.near\"}"
},
"public_key": "ed25519:C3jXhkGhEx88Gj7XKtUziJKXEBMRaJ67bWFkxJikVxZ2",
"signature": "ed25519:5op5APf9YaRznvMVwZBw6GGk9ychU3QtNRKJSxuVajHFMQths4ZZMRoAENU1zWhjinqz8KuLNyM9589c86opopyT"
}
See Intent Types and Execution for the full signed intent format and how to submit intents.
Real transaction examples
View these withdrawal and intent transactions on NEAR mainnet:
| Operation | Transaction |
|---|---|
| Withdraw by transaction | 3E8TDSLq... |
| Deposit + swap + withdraw | BMFcWFRe... |
| Execute intents | FxpbspXj... |
Withdrawal functions by token type
| Token Type | Direct Function | Intent |
|---|---|---|
| NEP-141 (Fungible) | ft_withdraw | FtWithdraw |
| NEP-171 (NFT) | nft_withdraw | NftWithdraw |
| NEP-245 (Multi Token) | mt_withdraw | MtWithdraw |
| Native NEAR | N/A | NativeWithdraw |
Withdrawing non-fungible tokens (NEP-171)
To withdraw NFTs from the Verifier contract, use nft_withdraw for direct calls or NftWithdraw for intent-based withdrawals, following the same patterns as fungible token withdrawals above.
Refunds on failed withdrawals
[!WARNING]
Important: This section applies to all withdrawal types except
NativeWithdraw, since native NEAR transfers cannot fail.
A refund restores your balance when a withdrawal fails on the target smart contract. The behavior depends on the msg parameter in your withdrawal request.
How msg affects refunds
The withdraw function has a msg parameter from the NEP-141 standard:
msg Value |
Transfer Method | Refund on Failure? |
|---|---|---|
Not specified or null |
ft_transfer |
✅ |
Any string value (including "") |
ft_transfer_call |
❌ |
[!WARNING]
An empty string (
"") still counts as a specifiedmsgvalue and will useft_transfer_callwith no refund. Only omittingmsgentirely or setting it tonullenables refund protection.
[!NOTE]
This same logic applies to Multi Token and NFT transfers with their corresponding functions:
nft_transfer,nft_transfer_call,mt_transfer, andmt_transfer_call.
Why refunds don't always work
Due to the asynchronous and sharded nature of the NEAR blockchain, refunds can only be processed when ft_transfer is used (i.e., when msg is not specified or is null).
The refund issue occurs when an asynchronous call to another smart contract (e.g., a USDC contract) fails. If an error happens within the Verifier contract itself, your balance won't change.
Summary
| Withdrawal Request | msg Parameter |
Refund Possible? |
|---|---|---|
FtWithdraw intent or ft_withdraw call |
No (or null) |
✅ |
FtWithdraw intent or ft_withdraw call |
Yes, as string | ❌ |
MtWithdraw intent or mt_withdraw call |
No (or null) |
✅ |
MtWithdraw intent or mt_withdraw call |
Yes, as string | ❌ |
NftWithdraw intent or nft_withdraw call |
No (or null) |
✅ |
NftWithdraw intent or nft_withdraw call |
Yes, as string | ❌ |
[!TIP]
Recommendation: To ensure a successful withdrawal with refund protection, avoid specifying
msgor set it explicitly tonull. For programmable actions on the receiving contract, perform them from your own account usingft_transfer_call.