Transfer SPL Tokens
Transfer SPL tokens and estimate transfer fees on Solana.
This guide explains how to transfer SPL tokens, estimate fees, add a memo, and validate a transfer. These methods support the original SPL Token program; Token-2022 mints remain unsupported.
Transfer Tokens
Use account.transfer() to send SPL tokens to a recipient address. If the recipient does not have a token account, one is created automatically.
const transferResult = await account.transfer({
token: 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB', // USDt mint address
recipient: 'publicKey', // Recipient's base58-encoded public key
amount: 1000000n // Amount in token's base units (6 decimals for USDt)
})
console.log('Transfer hash:', transferResult.hash)
console.log('Transfer fee:', transferResult.fee, 'lamports')Estimate Transfer Fees
Use account.quoteTransfer() to get a fee estimate before executing the transfer.
const transferQuote = await account.quoteTransfer({
token: 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB',
recipient: 'publicKey',
amount: 1000000n
})
console.log('Transfer fee estimate:', transferQuote.fee, 'lamports')Add a Memo (optional)
Pass { memo } as the second argument to quoteTransfer() and transfer(). The memo is a public, on-chain payment reference; keep secrets and personal data out of it.
- Prepare the same transfer fields and memo for both calls.
- Inspect the quote before sending; configure
transferMaxFeeto enforce a fee cap during execution. - Submit the transfer with the same memo.
You can quote and send a transfer using your reviewed mint, recipient, and amount:
const transferOptions = { token: splTokenMint, recipient, amount }
const solanaOptions = { memo: 'Invoice 1042' }
const quote = await account.quoteTransfer(transferOptions, solanaOptions)
console.log('Estimated fee:', quote.fee, 'lamports')
const result = await account.transfer(transferOptions, solanaOptions)
console.log('Transfer hash:', result.hash)The memo must be a string; an empty string adds no memo instruction. Both calls throw ValueError for a non-string memo or a memo that makes the transaction exceed Solana's transaction-size limit. The limit applies to the complete transaction, so there is no fixed character allowance. The second argument applies to SPL transfers, not native SOL sends. This feature does not enable Token-2022 memo-transfer extensions.
Transfer with Validation
You can validate addresses and check balances before transferring to catch errors early.
1. Validate Addresses
if (typeof splTokenMint !== 'string' || splTokenMint.length < 32) {
throw new Error('Invalid SPL token mint address')
}
if (typeof recipient !== 'string' || recipient.length < 32) {
throw new Error('Invalid recipient address')
}2. Check Balance
Use account.getTokenBalance() to verify sufficient funds:
const balance = await account.getTokenBalance(splTokenMint)
if (balance < amount) {
throw new Error('Insufficient SPL token balance')
}3. Quote and Execute Transfer
Use account.quoteTransfer() to estimate fees, then account.transfer() to execute:
const quote = await account.quoteTransfer({
token: splTokenMint,
recipient,
amount
})
console.log('Transfer fee estimate:', quote.fee, 'lamports')
const result = await account.transfer({
token: splTokenMint,
recipient,
amount
})
console.log('Transfer hash:', result.hash)
console.log('Actual fee:', result.fee, 'lamports')Next Steps
Learn how to sign and verify messages with your Solana account.