Reading from Network
Read data from the Solana network by fetching different accounts. This section will help you understand the structure of Solana accounts. Each Solana account has a unique address that is used to locate its corresponding on-chain data. Accounts contain either state data or an executable program.
Fetch a wallet account
A wallet is an account owned by the System Program. Wallets are primarily used to hold SOL and sign transactions. When SOL is sent to a new address for the first time, a system account is automatically created.
The example below generates a new keypair, requests SOL to fund the new public key address, and retrieves the account data for the newly funded wallet.
import { Keypair, Connection, LAMPORTS_PER_SOL } from "@solana/web3.js";const keypair = Keypair.generate();console.log(`Public Key: ${keypair.publicKey}`);const connection = new Connection("http://localhost:8899", "confirmed");// Funding an address with SOL automatically creates an accountconst signature = await connection.requestAirdrop(keypair.publicKey,LAMPORTS_PER_SOL);await connection.confirmTransaction(signature, "confirmed");const accountInfo = await connection.getAccountInfo(keypair.publicKey);console.log(JSON.stringify(accountInfo, null, 2));
When you fetch a wallet account, the response includes the fields shown in the example output on the right.
{"data": {"type": "Buffer","data": []},"executable": false,"lamports": 1000000000,"owner": "11111111111111111111111111111111","rentEpoch": 0,"space": 0}
The data field contains the account's data stored as bytes.
For wallet accounts, this field is empty (0 bytes).
{"data": {"type": "Buffer","data": []},"executable": false,"lamports": 1000000000,"owner": "11111111111111111111111111111111","rentEpoch": 0,"space": 0}
The executable field indicates whether the account's data field contains
executable program code.
For wallet accounts this field is false.
{"data": {"type": "Buffer","data": []},"executable": false,"lamports": 1000000000,"owner": "11111111111111111111111111111111","rentEpoch": 0,"space": 0}
The lamports field contains the account's SOL balance, in lamports.
{"data": {"type": "Buffer","data": []},"executable": false,"lamports": 1000000000,"owner": "11111111111111111111111111111111","rentEpoch": 0,"space": 0}
The owner field shows the program that owns the account.
For wallets, the owner is always the System Program, with the address
11111111111111111111111111111111.
{"data": {"type": "Buffer","data": []},"executable": false,"lamports": 1000000000,"owner": "11111111111111111111111111111111","rentEpoch": 0,"space": 0}
The rentEpoch field is a legacy field from a deprecated rent mechanism.
(This field is included for backward compatibility.)
{"data": {"type": "Buffer","data": []},"executable": false,"lamports": 1000000000,"owner": "11111111111111111111111111111111","rentEpoch": 0,"space": 0}
The space field shows the number of bytes contained in the data field.
This is not a field in the Account type itself,
but is included in the response.
In this example, the space field is 0 because the data field contains 0
bytes of data.
{"data": {"type": "Buffer","data": []},"executable": false,"lamports": 1000000000,"owner": "11111111111111111111111111111111","rentEpoch": 0,"space": 0}
Fetch the Token Program
The example below fetches the Token Program to demonstrate the difference between wallet and program accounts. The program account stores the compiled bytecode for the Token Program's source code. You can view this program account on the Solana Explorer.
import { Connection, PublicKey } from "@solana/web3.js";const connection = new Connection("https://api.mainnet-beta.solana.com","confirmed");const address = new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");const accountInfo = await connection.getAccountInfo(address);
The Token Program is an executable program account. Programs have the same underlying fields as all accounts, but with key differences.
{"data": {"type": "Buffer","data": [127, "...truncated, total bytes: 134080...", 0]},"executable": true,"lamports": 4522329612,"owner": "BPFLoader2111111111111111111111111111111111","rentEpoch": 18446744073709552000,"space": 134080}
The executable field is set to true, which indicates that the account's data
field contains executable code.
{"data": {"type": "Buffer","data": [127, "...truncated, total bytes: 134080...", 0]},"executable": true,"lamports": 4522329612,"owner": "BPFLoader2111111111111111111111111111111111","rentEpoch": 18446744073709552000,"space": 134080}
The data field stores the program's executable code.
{"data": {"type": "Buffer","data": [127, "...truncated, total bytes: 134080...", 0]},"executable": true,"lamports": 4522329612,"owner": "BPFLoader2111111111111111111111111111111111","rentEpoch": 18446744073709552000,"space": 134080}
Every program account is owned by its loader program.
In this example, the owner is the BPFLoader2 program.
{"data": {"type": "Buffer","data": [127, "...truncated, total bytes: 134080...", 0]},"executable": true,"lamports": 4522329612,"owner": "BPFLoader2111111111111111111111111111111111","rentEpoch": 18446744073709552000,"space": 134080}
Fetch a mint account
A mint account is an account owned by the Token Program that stores global metadata for a specific token. This includes the total supply, number of decimals, and the accounts that are authorized to mint or freeze tokens. The mint account's address uniquely identifies a token on the Solana network.
The example below fetches the USD Coin Mint account to demonstrate how a program's state is stored in a separate account.
import { Connection, PublicKey } from "@solana/web3.js";const connection = new Connection("https://api.mainnet-beta.solana.com","confirmed");const address = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");const accountInfo = await connection.getAccountInfo(address);
Mint accounts store state, not executable code. They are owned by the Token Program, which includes instructions defining how to create and update mint accounts.
{"data": {"type": "Buffer","data": [1, "...truncated, total bytes: 82...", 103]},"executable": false,"lamports": 407438077149,"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","rentEpoch": 18446744073709552000,"space": 82}
The mint account's data field stores state, not executable code,
so the executable field is false.
The Token Program defines the Mint data type, which is stored in the data field.
{"data": {"type": "Buffer","data": [1, "...truncated, total bytes: 82...", 103]},"executable": false,"lamports": 407438077149,"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","rentEpoch": 18446744073709552000,"space": 82}
The data field contains the serialized Mint account state, such as the mint
authority, total supply, number of decimals.
To read from a Mint account, you must deserialize the data field into the
Mint data type, which is shown in the next example.
{"data": {"type": "Buffer","data": [1, "...truncated, total bytes: 82...", 103]},"executable": false,"lamports": 407438077149,"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","rentEpoch": 18446744073709552000,"space": 82}
The mint account is owned by the Token Program.
This means that its data field can only be modified by the Token Program' instructions.
{"data": {"type": "Buffer","data": [1, "...truncated, total bytes: 82...", 103]},"executable": false,"lamports": 407438077149,"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","rentEpoch": 18446744073709552000,"space": 82}
Deserialize mint account
Before the raw bytes in an account's data field can be interpreted meaningfully
they must be deserialized.
The appropriate data type is defined by the program that owns the account.
Most Solana programs provide client libraries with helper functions that
abstract away the deserialization process. These functions convert the raw
account bytes into structured data types, making it easier to work with the
account data.
For example, the @solana/spl-token library includes the
getMint() function to help deserialize a mint account's
data field into the
Mint
data type defined by the Token Program.
import { PublicKey, Connection } from "@solana/web3.js";import { getMint } from "@solana/spl-token";const connection = new Connection("https://api.mainnet-beta.solana.com","confirmed");const address = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");const mintData = await getMint(connection, address, "confirmed");
pub struct Mint {/// Optional authority used to mint new tokens. The mint authority may only/// be provided during mint creation. If no mint authority is present/// then the mint has a fixed supply and no further tokens may be/// minted.pub mint_authority: COption<Pubkey>,/// Total supply of tokens.pub supply: u64,/// Number of base 10 digits to the right of the decimal place.pub decimals: u8,/// Is `true` if this structure has been initializedpub is_initialized: bool,/// Optional authority to freeze token accounts.pub freeze_authority: COption<Pubkey>,}
The getMint() function deserializes a mint account's data field into the
Mint account type.
{"data": {"type": "Buffer","data": [1, "...truncated, total bytes: 82...", 103]},"executable": false,"lamports": 407438077149,"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","rentEpoch": 18446744073709552000,"space": 82}
You can view the fully deserialized mint account data on the Solana Explorer.
{"address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","mintAuthority": "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG","supply": "8985397351591790","decimals": 6,"isInitialized": true,"freezeAuthority": "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar","tlvData": {"type": "Buffer","data": []}}
The address field contains the mint account's address.
{"address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","mintAuthority": "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG","supply": "8985397351591790","decimals": 6,"isInitialized": true,"freezeAuthority": "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar","tlvData": {"type": "Buffer","data": []}}
The mintAuthority field shows the only account that can create new units of the token.
{"address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","mintAuthority": "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG","supply": "8985397351591790","decimals": 6,"isInitialized": true,"freezeAuthority": "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar","tlvData": {"type": "Buffer","data": []}}
The supply field shows the total number of tokens that have been minted.
This value is measured in the smallest unit of the token. To get the total supply in
standard units, adjust the value of the supply field by the decimals.
{"address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","mintAuthority": "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG","supply": "8985397351591790","decimals": 6,"isInitialized": true,"freezeAuthority": "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar","tlvData": {"type": "Buffer","data": []}}
The decimals field shows the number of decimal places for the token.
{"address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","mintAuthority": "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG","supply": "8985397351591790","decimals": 6,"isInitialized": true,"freezeAuthority": "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar","tlvData": {"type": "Buffer","data": []}}
The isInitialized field indicates whether the mint account has been initialized.
This field is a security check used in the Token Program.
{"address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","mintAuthority": "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG","supply": "8985397351591790","decimals": 6,"isInitialized": true,"freezeAuthority": "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar","tlvData": {"type": "Buffer","data": []}}
The freezeAuthority field shows the account with authority to freeze token accounts.
A frozen token account cannot transfer or burn the token it contains.
{"address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","mintAuthority": "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG","supply": "8985397351591790","decimals": 6,"isInitialized": true,"freezeAuthority": "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar","tlvData": {"type": "Buffer","data": []}}
The tlvData field contains extra data for Token Extensions
and requires further deserialization.
This field is only relevant to accounts created by the Token Extension Program
(Token2022).
{"address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","mintAuthority": "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG","supply": "8985397351591790","decimals": 6,"isInitialized": true,"freezeAuthority": "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar","tlvData": {"type": "Buffer","data": []}}
Is this page helpful?