Solana enables instant, global token transfers with fees under $0.001. Whether you're building cross-border remittances, payroll disbursements, or treasury operations, a basic stablecoin payment settles in under a second and costs a fraction of a cent.
How It Works
A payment moves stablecoins from the sender's token account to the recipient's token account. If the recipient is receiving this token for the first time, their token account can be created as part of the same transaction.
See How Payments Work on Solana for core payment concepts.
The splToken helper from
@solana/client handles ATA
derivation, decimal conversion, and transaction building automatically. This is
ideal for single payment transfers.
The steps below show the core flow. See the Demo for complete runnable code.
Create the Token Helper
Configure the splToken() helper by calling client.splToken() with the mint
address. The helper provides methods for common token operations.
Setting tokenProgram: "auto" automatically detects whether the mint account is
owned by Token or Token-2022 program.
const client = createClient({endpoint: "http://localhost:8899",websocketEndpoint: "ws://localhost:8900",commitment: "confirmed"});const splToken = client.splToken({mint: mint.address,tokenProgram: "auto"});
Send the Payment
Use sendTransfer() to transfer tokens between wallets. The method handles:
- ATA Resolution: Automatically derives Associated Token Accounts (ATAs) for the sender and recipient. If the recipient's ATA doesn't exist, the instruction to create the account is automatically added to the same transaction.
- Decimal Conversion: Accepts token amounts and automatically converts to base units based on the mint's decimals (e.g. 0.25 tokens -> 250000 base units, if the mint has 6 decimals)
- Transaction Building: Creates, signs, and sends the transaction with the transfer instruction
const client = createClient({endpoint: "http://localhost:8899",websocketEndpoint: "ws://localhost:8900",commitment: "confirmed"});const splToken = client.splToken({mint: mint.address,tokenProgram: "auto"});const signature = await splToken.sendTransfer({amount: 0.25,authority: sender,destinationOwner: recipient.address});
Verify Balances
After the transfer completes, use fetchBalance() to verify the token balances.
This method takes a wallet address and automatically derives the corresponding
ATA to fetch the balance.
const client = createClient({endpoint: "http://localhost:8899",websocketEndpoint: "ws://localhost:8900",commitment: "confirmed"});const splToken = client.splToken({mint: mint.address,tokenProgram: "auto"});const signature = await splToken.sendTransfer({amount: 0.25,authority: sender,destinationOwner: recipient.address});const senderBalance = await splToken.fetchBalance(sender.address);const recipientBalance = await splToken.fetchBalance(recipient.address);
Demo
// Generate keypairs for sender and recipientconst sender = (await generateKeypair()).signer;const recipient = (await generateKeypair()).signer;console.log("Sender Address:", sender.address);console.log("Recipient Address:", recipient.address);// Demo Setup: Create client, mint account, token accounts, and fund with initial tokensconst { client, mint } = await demoSetup(sender, recipient);console.log("\nMint Address:", mint.address);// =============================================================================// Basic Token Payment Demo// =============================================================================// Create splToken helper for this mint using @solana/clientconst splToken = client.splToken({mint: mint.address,tokenProgram: "auto"});// Transfer tokens from sender to recipient (ATA and decimals handled automatically)const signature = await splToken.sendTransfer({amount: 0.25,authority: sender,destinationOwner: recipient.address});console.log("\n=== Token Payment Complete ===");console.log("Transaction Signature:", signature.toString());// Fetch final token account balances using splToken helperconst senderBalance = await splToken.fetchBalance(sender.address);const recipientBalance = await splToken.fetchBalance(recipient.address);console.log("\nSender Token Account Balance:", senderBalance);console.log("Recipient Token Account Balance:", recipientBalance);// =============================================================================// Demo Setup Helper Function// =============================================================================
Is this page helpful?