6 min read
Overview
Whether you are querying a token account balance or constructing a token transfer instruction, knowing how to derive a user's token account address is a fundamental skill for any Solana developer. In this guide, we will walk through five easy ways to fetch the address of a Solana SPL-associated token account:
- Using Solana's SPL-Token Command Line Interface (SPL-Token CLI) (Jump to SPL-Token CLI)
- Using Solana's JavaScript API (Jump to Solana-Web3.js)
- Using Solana's SPL Token Program API (Jump to SPL Token Program)
- Using a cURL script (Jump to cURL)
- Using Rust (Jump to Rust)
What You Will Need
- Basic understanding of Solana Fundamentals
- Solana CLI latest version installed
- SPL Token Program CLI latest version installed
- Nodejs (version 16.15 or higher) installed
- Basic JavaScript experience
- cURL stable version installed
- A wallet address and mint address to query (we will use the wallet:
E645TckHQnDcavVv92Etc6xSWQaq8zzPtPRGBheviRAk
and USDC token mint,EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
) - Rust installed (optional for Rust method)
Dependency | Version |
---|---|
solana-cli | 1.16.14 |
spl-token-cli | 3.1.1 |
node.js | 16.15 |
curl | 8.1.12 |
@solana/web3.js | 1.78.5 |
@solana/spl-token | 0.3.7 |
solana-sdk | 1.16.14 |
spl-associated-token-account | 2.2.0 |
cargo | 1.69.0 |
SPL Token Accounts
Before diving into the code, let's take a moment to recap what a token account is and how it differs from a Solana wallet address. Just like most elements of the Solana ecosystem, token accounts are built on Solana's account model. This means that token accounts are actually Solana accounts that are associated with a specific token mint. These accounts are owned by the SPL Token Program (TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
) and controlled by a user's wallet address. Though having multiple token accounts associated with a single wallet address is possible, each token account is unique to a specific mint. To reduce friction in token management, Solana introduced the Associated Token Program, a way to deterministically map a user's wallet to a token account for an associated mint. This guide will focus on how to fetch the address of an associated token account for a given wallet and mint.
Method 1 - SPL-Token CLI
Our first method is to check the balance of a wallet using Solana SPL-Token CLI. If you do not already have it installed, follow the instructions for your operating environment at spl.solana.com/token. To make sure your installation was successful, open a new terminal and type:
spl-token --version
You should see something like this:
You're ready to go! All you need to do is get your wallet address handy--you can copy it directly from Phantom or any other wallet:
You will also need the mint address of the token you want to query. You can find this by searching for the name of the token on any Solana-based explorer, e.g., Solana Explorer:
In your terminal, fetch your token account by entering:
spl-token address --owner OWNER_WALLET_ADDRESS --token TOKEN_MINT_ADDRESS --verbose -um
We simply pass the --owner
flag with the wallet address we want to query, the --token
flag with the mint address of the token we want to query, and the --verbose
flag to get a more detailed response (required for this query). The -um
flag tells the CLI to use the Solana mainnet cluster (though our search is deterministic and should not require a specified cluster, the CLI tool verifies that our mint address is actually a valid mint address on that cluster).
You should see something like this:
Great job!
Method 2 - Solana-Web3.js
Create a new project directory and file, balance.js, in your terminal with the following:
mkdir token-address && cd token-address && echo > address.js
Install Solana Web3 dependencies:
yarn init -y
yarn add @solana/web3.js@1
or
npm init -y
npm install --save @solana/web3.js@1
Open address.js in a code editor of choice, and on line 1, require @solana/web3.js. We will deconstruct the PublicKey class from this package.
const { PublicKey } = require('@solana/web3.js');
On lines 3-6, define your wallet, mint, and the relevant programs (Token Program and Associated Token Program):
const OWNER = new PublicKey('YOUR_WALLET_ADDRESS'); // e.g., E645TckHQnDcavVv92Etc6xSWQaq8zzPtPRGBheviRAk
const MINT = new PublicKey('YOUR_MINT_ADDRESS'); // e.g., EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
const TOKEN_PROGRAM_ID = new PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA');
const ASSOCIATED_TOKEN_PROGRAM_ID = new PublicKey('ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL');
Finally, fetch your address by calling the findProgramAddressSync()
method on PublicKey:
const [address] = PublicKey.findProgramAddressSync(
[OWNER.toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), MINT.toBuffer()],
ASSOCIATED_TOKEN_PROGRAM_ID
);
console.log('Using Solana-Web3.js: ', address.toBase58());
The findProgramAddressSync
method deterministically finds a program address given seeds and a program ID. In this case, we pass the wallet address, token program ID, and mint address as seeds and the associated token program ID as the program ID (these seeds and their order are defined by the associated token program).
Run your code. In your terminal type,
node address
You should see something like this:
Nice job!
Note: you can alternatively use the Connection class to send a getAssociatedTokenAddressSync
request to the Solana cluster. This method requires a network request, so it is not as performant as the findProgramAddressSync
method; however, it will also find any token accounts created outside of the associated token program. Situationally, this could be useful.