# Table of Contents - [Learn how the Solana blockchain works | Solana](#learn-how-the-solana-blockchain-works-solana) - [Core Concepts | Solana](#core-concepts-solana) - [Transaction Fees | Solana](#transaction-fees-solana) - [Program-Derived Address | Solana](#program-derived-address-solana) - [Tokens on Solana | Solana](#tokens-on-solana-solana) - [Cross Program Invocation | Solana](#cross-program-invocation-solana) - [Rust SDK for Solana | Solana](#rust-sdk-for-solana-solana) - [Transactions | Solana](#transactions-solana) - [Accounts | Solana](#accounts-solana) - [Frontend | Solana](#frontend-solana) - [Install the Solana CLI and Anchor with one command | Solana](#install-the-solana-cli-and-anchor-with-one-command-solana) - [Programs | Solana](#programs-solana) - [Quick Start | Solana](#quick-start-solana) - [Payments | Solana](#payments-solana) - [Solana RPC Methods: HTTP & Websockets | Solana](#solana-rpc-methods-http-websockets-solana) - [Clusters and Public RPC Endpoints | Solana](#clusters-and-public-rpc-endpoints-solana) - [Tokens on Solana | Solana](#tokens-on-solana-solana) - [Instructions | Solana](#instructions-solana) - [Cross Program Invocation | Solana](#cross-program-invocation-solana) - [Staking on Solana | Solana](#staking-on-solana-solana) - [Solana Gaming SDKs | Solana](#solana-gaming-sdks-solana) - [How Payments Work on Solana | Solana](#how-payments-work-on-solana-solana) - [Common JSON Data Structures for Solana RPC Methods | Solana](#common-json-data-structures-for-solana-rpc-methods-solana) - [Install the dependencies necessary to develop with Solana | Solana](#install-the-dependencies-necessary-to-develop-with-solana-solana) - [SPL Token Basics | Solana](#spl-token-basics-solana) - [@solana/client | Solana](#-solana-client-solana) - [JavaScript/TypeScript SDK for Solana | Solana](#javascript-typescript-sdk-for-solana-solana) - [Reading from Network | Solana](#reading-from-network-solana) - [Solana RPC HTTP Methods | Solana](#solana-rpc-http-methods-solana) - [Interacting with Solana | Solana](#interacting-with-solana-solana) - [Introductory commands for getting started on the Solana CLI | Solana](#introductory-commands-for-getting-started-on-the-solana-cli-solana) - [Extensions | Solana](#extensions-solana) - [Writing to the Network | Solana](#writing-to-the-network-solana) - [@solana/react-hooks | Solana](#-solana-react-hooks-solana) - [Introductory commands for getting started on the Anchor CLI | Solana](#introductory-commands-for-getting-started-on-the-anchor-cli-solana) - [Send Payments | Solana](#send-payments-solana) - [getLatestBlockhash RPC Method | Solana](#getlatestblockhash-rpc-method-solana) - [getAccountInfo RPC Method | Solana](#getaccountinfo-rpc-method-solana) - [Solana wallet integration with Next.js and @solana/react-hooks | Solana](#solana-wallet-integration-with-next-js-and-solana-react-hooks-solana) - [Developing Programs in Rust | Solana](#developing-programs-in-rust-solana) - [@solana/web3-compat | Solana](#-solana-web3-compat-solana) - [Deploy Your First Solana Program | Solana](#deploy-your-first-solana-program-solana) - [Deploying Programs | Solana](#deploying-programs-solana) - [Introductory commands for getting started on the Surfpool CLI | Solana](#introductory-commands-for-getting-started-on-the-surfpool-cli-solana) - [Basic Payment | Solana](#basic-payment-solana) - [Limitations | Solana](#limitations-solana) - [Payment Processing | Solana](#payment-processing-solana) - [Verifying Programs | Solana](#verifying-programs-solana) - [Payment with Memo | Solana](#payment-with-memo-solana) - [getTransaction RPC Method | Solana](#gettransaction-rpc-method-solana) - [getBalance RPC Method | Solana](#getbalance-rpc-method-solana) - [Verify Address | Solana](#verify-address-solana) - [Agentic Payments | Solana](#agentic-payments-solana) - [Accept Payments | Solana](#accept-payments-solana) - [Program Derived Address | Solana](#program-derived-address-solana) - [Stake Accounts | Solana](#stake-accounts-solana) - [Stake Programming | Solana](#stake-programming-solana) - [Go SDK for Solana | Solana](#go-sdk-for-solana-solana) - [Python SDK for Solana | Solana](#python-sdk-for-solana-solana) - [Java SDK for Solana | Solana](#java-sdk-for-solana-solana) - [Fee Abstraction | Solana](#fee-abstraction-solana) - [Create a Token Mint | Solana](#create-a-token-mint-solana) - [Sync Native | Solana](#sync-native-solana) - [Mint Tokens | Solana](#mint-tokens-solana) - [Freeze Account | Solana](#freeze-account-solana) - [Close Token Account | Solana](#close-token-account-solana) - [Transfer Tokens | Solana](#transfer-tokens-solana) - [Create a Token Account | Solana](#create-a-token-account-solana) - [Revoke Delegate | Solana](#revoke-delegate-solana) - [Thaw Account | Solana](#thaw-account-solana) - [Burn Tokens | Solana](#burn-tokens-solana) - [Approve Delegate | Solana](#approve-delegate-solana) --- # Learn how the Solana blockchain works | Solana This website uses cookies to offer you a better browsing experience. Find out more on how we use cookies. Opt-out[Details](https://solana.com/privacy-policy#collection-of-information) Accept Solana Documentation ==================== Solana is the high-performance blockchain designed for mass adoption. Learn why Solana is the top choice for developers looking to build scalable blockchain applications. Search or ask AI⌘K Copy MarkdownOpen [Getting Started](https://solana.com/docs#getting-started) ----------------------------------------------------------- [### Quickstart\ \ Build your first Solana program directly in the browser](https://solana.com/docs/intro/quick-start) [### Setup Local Environment\ \ Install dependencies for Solana development](https://solana.com/docs/intro/installation) ### [Build Faster with Solana Developer Templates](https://solana.com/docs#build-faster-with-solana-developer-templates) [### Explore Developer Templates\ \ Build faster with production-ready templates for dApps, DeFi protocols, NFT marketplaces, and more. Get started with battle-tested code patterns optimized for the Solana ecosystem.](https://solana.com/developers/templates) [Try Solana: Play 2048](https://solana.com/docs#try-solana-play-2048) ---------------------------------------------------------------------- Play 2048 on Solana where every move sends a transaction. Click "Play" to start with a funded devnet wallet and use the arrow keys to play. If on mobile, swipe to control the tiles. ### Play Solana 2048 Built by [Jonas](https://x.com/SolPlay_jonas) , from the Solana Foundation DevRel team. [Start Learning](https://solana.com/docs#start-learning) --------------------------------------------------------- Learn the key concepts specific to Solana development. [### Accounts\ \ How Solana stores data](https://solana.com/docs/core/accounts) [### Fees on Solana\ \ Costs to send transactions on Solana](https://solana.com/docs/core/fees) [### Transactions\ \ How to interact with the Solana network](https://solana.com/docs/core/transactions) [### Programs\ \ Smart contracts on Solana](https://solana.com/docs/core/programs) [### Programs Derived Address\ \ How to generate deterministic addresses](https://solana.com/docs/core/pda) [### Cross Program Invocation\ \ How to call one program from another](https://solana.com/docs/core/cpi) ### [Client Side Development](https://solana.com/docs#client-side-development) The following SDKs are the official SDKs for Solana built by [Anza](https://anza.xyz/) . #### [Official SDKs](https://solana.com/docs#official-sdks) | Language | SDK | | --- | --- | | Rust | [solana\_sdk](https://solana.com/docs/clients/official/rust) | | Typescript (Client) | [@solana/client](https://solana.com/docs/clients/official/javascript#solana-client) | | Typescript (React) | [@solana/react-hooks](https://solana.com/docs/clients/official/javascript#solana-react-hooks) | | Typescript (Recommended) | [@solana/kit](https://solana.com/docs/clients/official/javascript#solana-kit) | | Typescript (Legacy) | [@solana/web3.js](https://solana.com/docs/clients/official/javascript#solana-web3js) | #### [Community SDKs](https://solana.com/docs#community-sdks) The following are community-contributed SDKs for various languages: | Language | SDK | | --- | --- | | Python | [solders](https://github.com/kevinheavey/solders) | | Java | [sava](https://sava.software/)
or [solanaj](https://github.com/skynetcap/solanaj)
or [solana4j](https://github.com/LMAX-Exchange/solana4j) | | C++ | [solcpp](https://github.com/mschneider/solcpp)
or [solana-c](https://github.com/VAR-META-Tech/solana-c-sdk) | | Go | [solana-go](https://github.com/gagliardetto/solana-go) | | Kotlin | [sol4k](https://github.com/sol4k/sol4k)
or [solanaKT](https://github.com/metaplex-foundation/SolanaKT) | | Dart | [solana](https://github.com/espresso-cash/espresso-cash-public/tree/master/packages/solana) | | C# | [solnet](https://github.com/bmresearch/Solnet) | | GdScript | [godot](https://github.com/Virus-Axel/godot-solana-sdk/) | Community SDKs are not guaranteed to be up to date or include all features of the official SDKs. [Running a validator](https://solana.com/docs#running-a-validator) ------------------------------------------------------------------- Explore what it takes to operate a Solana validator and help secure the network. [### Validators\ \ Individual nodes securing the Solana network](https://docs.anza.xyz/validator/anatomy) [### System Requirements\ \ Recommended hardware requirements and SOL required to operate a validator](https://docs.anza.xyz/operations/requirements) [### Validator Setup\ \ Setup a validator and get connected to a cluster for the first time](https://docs.anza.xyz/operations/setup-a-validator) [Getting Support](https://solana.com/docs#getting-support) ----------------------------------------------------------- Get help from the Solana community on [Solana StackExchange](https://solana.stackexchange.com/) . Is this page helpful? [Next\ \ Quick Installation](https://solana.com/docs/intro/installation) ### Table of Contents [Getting Started](https://solana.com/docs#getting-started) [Build Faster with Solana Developer Templates](https://solana.com/docs#build-faster-with-solana-developer-templates) [Try Solana: Play 2048](https://solana.com/docs#try-solana-play-2048) [Start Learning](https://solana.com/docs#start-learning) [Client Side Development](https://solana.com/docs#client-side-development) [Official SDKs](https://solana.com/docs#official-sdks) [Community SDKs](https://solana.com/docs#community-sdks) [Running a validator](https://solana.com/docs#running-a-validator) [Getting Support](https://solana.com/docs#getting-support) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/index.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter Learn how the Solana blockchain works | Solana --- # Core Concepts | Solana [Solana Documentation](https://solana.com/docs) [Core Concepts](https://solana.com/docs/core) ============================================== Copy MarkdownOpen To build on Solana, it's essential to understand key concepts unique to Solana development. This section covers the core concepts you need to understand as you start building on Solana, including accounts, transactions, programs, and more. [Accounts](https://solana.com/docs/core#accounts) -------------------------------------------------- All data on the Solana blockchain is stored as an Account. The structure of the Solana blockchain resembles a key-value store, in which the key is the on-chain address and the value is an Account. Learn more about [Accounts](https://solana.com/docs/core/accounts) . [Transactions and Instructions](https://solana.com/docs/core#transactions-and-instructions) -------------------------------------------------------------------------------------------- To interact with the Solana network, a user must send a transaction. A transaction is a set of one or more instructions—an instruction is a specific operation to be processed. The execution logic for an instruction is stored on a program deployed to the Solana network. Learn more about [Transactions](https://solana.com/docs/core/transactions) and [Instructions](https://solana.com/docs/core/transactions#instruction) . [Fees](https://solana.com/docs/core#fees) ------------------------------------------ There are three different types of fees that can be incurred when using the Solana blockchain: * **Transaction Fees**: A fee to have validators process transactions & instructions * **Prioritization Fees**: An optional fee to boost a transaction's processing order * **Rent**: A withheld balance to keep data stored on-chain Learn more about [Fees on Solana](https://solana.com/docs/core/fees) . [Programs on Solana](https://solana.com/docs/core#programs-on-solana) ---------------------------------------------------------------------- On Solana, smart contracts are called Programs. Each program is stored in an on-chain account and contains executable code with specific instructions. These instructions represent the program's functionality and are invoked by sending a transaction to the network. Learn more about [Programs on Solana](https://solana.com/docs/core/programs) . [Program Derived Address](https://solana.com/docs/core#program-derived-address) -------------------------------------------------------------------------------- Program-derived addresses (PDAs) allow developers to create hashmap-like structures on-chain using a predefined set of inputs (e.g. strings, numbers, and other account addresses). PDAs allow for two important use cases: * **Deterministic Account Addresses**: Predefined inputs (seeds) and a program ID are combined to deterministically derive an address. * **Program Signing**: A Solana programs can sign for PDAs, which are derived from its program ID. Learn more about [Program Derived Address](https://solana.com/docs/core/pda) . [Cross-program Invocation](https://solana.com/docs/core#cross-program-invocation) ---------------------------------------------------------------------------------- Cross-program invocation (CPI) occurs when one program invokes an instruction from another. This allows for the composability of Solana programs. To conceptualize the concept, imagine a program's set of instructions as a set of API endpoints. A CPI occurs when one endpoint invokes another. Learn more about [Cross Program Invocation](https://solana.com/docs/core/cpi) . [Tokens](https://solana.com/docs/core#tokens) ---------------------------------------------- Tokens are digital assets that represent ownership over diverse categories of assets. Tokenization enables the digitalization of property rights—a fundamental component for managing fungible and non-fungible assets. * **Fungible Tokens**: Interchangeable and divisible assets of the same type and value (ex. USDC). * **Non-fungible Tokens (NFT):** Ownership of indivisible assets (e.g. artwork). Learn more about [Tokens on Solana](https://solana.com/docs/core/tokens) . [Clusters and Endpoints](https://solana.com/docs/core#clusters-and-endpoints) ------------------------------------------------------------------------------ The Solana blockchain has several different groups of validators, known as [Clusters](https://solana.com/docs/references/clusters) . Each cluster serves a different purpose and contains dedicated nodes to fulfill [JSON-RPC](https://solana.com/docs/rpc/) requests. There are three primary clusters on the Solana network, shown in the table below. | Name | Endpoint | Use | | --- | --- | --- | | Mainnet | `https://api.mainnet.solana.com` | Production | | Devnet | `https://api.devnet.solana.com` | Developer experimentation | | Testnet | `https://api.testnet.solana.com` | Validator testing | Learn more about [Clusters and Endpoints](https://solana.com/docs/references/clusters) . Is this page helpful? [Previous\ \ Composing Multiple Programs](https://solana.com/docs/intro/quick-start/cross-program-invocation) [Next\ \ Accounts](https://solana.com/docs/core/accounts) ### Table of Contents [Accounts](https://solana.com/docs/core#accounts) [Transactions and Instructions](https://solana.com/docs/core#transactions-and-instructions) [Fees](https://solana.com/docs/core#fees) [Programs on Solana](https://solana.com/docs/core#programs-on-solana) [Program Derived Address](https://solana.com/docs/core#program-derived-address) [Cross-program Invocation](https://solana.com/docs/core#cross-program-invocation) [Tokens](https://solana.com/docs/core#tokens) [Clusters and Endpoints](https://solana.com/docs/core#clusters-and-endpoints) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/core/index.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter Core Concepts | Solana --- # Transaction Fees | Solana This website uses cookies to offer you a better browsing experience. Find out more on how we use cookies. Opt-out[Details](https://solana.com/privacy-policy#collection-of-information) Accept [Solana Documentation](https://solana.com/docs) [Core Concepts](https://solana.com/docs/core) [Transaction Fees](https://solana.com/docs/core/fees) ====================================================== Copy MarkdownOpen Every Solana transaction requires a transaction fee, paid in SOL. Transaction fees are split into two parts: the base fee and the prioritization fee. The base fee compensates validators for processing the transaction. The prioritization fee is an optional fee, to increase the chance that the current leader will process your transaction. [Base fee](https://solana.com/docs/core/fees#base-fee) ------------------------------------------------------- Every transaction costs 5000 [lamports](https://solana.com/docs/references/terminology#lamport) per included signature. This fee is paid by the first signer on the transaction. Only accounts owned by the System Program can pay transaction fees. The base fee is split as follows: * **50% burned:** Half is [burned](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/fee-calculator/src/lib.rs#L70) (taken out of the circulating SOL supply). * **50% distributed:** Half is [paid to the validator](https://github.com/anza-xyz/agave/blob/e621336acad4f5d6e5b860eaa1b074b01c99253c/runtime/src/bank/fee_distribution.rs#L58-L62) that processed the transaction. [Prioritization fee](https://solana.com/docs/core/fees#prioritization-fee) --------------------------------------------------------------------------- A [prioritization fee](https://github.com/anza-xyz/agave/blob/v2.2.14/compute-budget/src/compute_budget_limits.rs#L47-L48) is an optional fee used to increase the chance that the current leader (validator) will process your transaction. The validator receives [100% of the priority fee](https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0096-reward-collected-priority-fee-in-entirety.md) . Prioritization fees can be set by adjusting the transaction's [computation unit](https://solana.com/docs/references/terminology#compute-units) (CU) price and CU limit. (See the [How to Use Priority Fees guide](https://solana.com/developers/guides/advanced/how-to-use-priority-fees) for more details on prioritization fees.) The prioritization fee is calculated as follows: Prioritization fee formula Prioritization fee = CU limit \* CU price The prioritization fee is used to determine your [transaction's priority](https://github.com/anza-xyz/agave/blob/v2.2.14/core/src/banking_stage/transaction_scheduler/receive_and_buffer.rs#L646) , relative to other transactions. It is calculated using the following formula: Transaction priority formula Priority = (Prioritization fee + Base fee) / (1 + CU limit + Signature CUs + Write lock CUs) #### [Compute unit limit](https://solana.com/docs/core/fees#compute-unit-limit) By [default](https://github.com/anza-xyz/agave/blob/v2.1.13/compute-budget/src/compute_budget.rs#L149-L197) , each instruction is allocated [200,000 CUs](https://github.com/anza-xyz/agave/blob/v2.1.13/compute-budget/src/compute_budget_limits.rs#L10) and each transaction is allocated [1.4 million CUs](https://github.com/anza-xyz/agave/blob/v2.1.13/compute-budget/src/compute_budget_limits.rs#L14) . You can change these defaults by including a [`SetComputeUnitLimit`](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/src/compute_budget.rs#L42-L44) instruction in your transaction. To calculate the appropriate CU limit for your transaction, we recommend the following steps: 1. Estimate the required CU units by [simulating](https://solana.com/developers/guides/advanced/how-to-request-optimal-compute) the transaction 2. Add a 10% safety margin to this estimate The priority fee is determined by the requested compute unit limit transaction, _not_ the actual number of compute units used. If you set a compute unit limit that's too high or use the default amount, you may pay for unused compute units. #### [Compute unit price](https://solana.com/docs/core/fees#compute-unit-price) The compute unit price is an optional amount of [micro-lamports](https://solana.com/docs/references/terminology#micro-lamports) paid for each requested CU. You can think of the CU price as a tip to encourage the validator to prioritize your transaction. To set the CU price, include a [`SetComputeUnitPrice`](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/src/compute_budget.rs#L48-L50) instruction in your transaction. The default CU price is 0, meaning the default prioritization fee is also 0. For help determining the best CU price for your transaction, see the real-time CU price recommendation provided listed in the table below. | Provider | Priority Fee API | | --- | --- | | [Helius](https://www.helius.dev/) | [Documentation](https://docs.helius.dev/solana-apis/priority-fee-api) | | [QuickNode](https://www.quicknode.com/) | [Documentation](https://marketplace.quicknode.com/add-on/solana-priority-fee) | | [Triton](https://triton.one/) | [Documentation](https://docs.triton.one/chains/solana/improved-priority-fees-api) | #### [Example](https://solana.com/docs/core/fees#example) The examples below show how to set the CU limit and CU price on a transaction using Solana SDKs. | SDK | Source Code Reference | | --- | --- | | `@solana/web3.js` (Typescript) | [`ComputeBudgetProgram`](https://github.com/solana-foundation/solana-web3.js/blob/v1.98.0/src/programs/compute-budget.ts#L218) | | `solana-sdk` (Rust) | [`ComputeBudgetInstruction`](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/src/compute_budget.rs#L17-L31) | Typescript Rust const limitInstruction \= ComputeBudgetProgram.setComputeUnitLimit({ units: 300\_000 }); const priceInstruction \= ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 }); Typescript Rust import { LAMPORTS\_PER\_SOL, SystemProgram, Transaction, Keypair, Connection, ComputeBudgetProgram, sendAndConfirmTransaction } from "@solana/web3.js"; const connection \= new Connection("http://localhost:8899", "confirmed"); const sender \= Keypair.generate(); const recipient \= new Keypair(); const airdropSignature \= await connection.requestAirdrop( sender.publicKey, LAMPORTS\_PER\_SOL ); await connection.confirmTransaction(airdropSignature, "confirmed"); // Create compute budget instructions const limitInstruction \= ComputeBudgetProgram.setComputeUnitLimit({ units: 300\_000 }); const priceInstruction \= ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 }); const transferInstruction \= SystemProgram.transfer({ fromPubkey: sender.publicKey, toPubkey: recipient.publicKey, lamports: 0.01 \* LAMPORTS\_PER\_SOL }); // Add the compute budget and transfer instructions to a new transaction const transaction \= new Transaction() .add(limitInstruction) .add(priceInstruction) .add(transferInstruction); const signature \= await sendAndConfirmTransaction(connection, transaction, \[\ \ sender\ \ \]); console.log("Transaction Signature:", signature); Console RunClick to execute the code. Typescript Rust import { LAMPORTS\_PER\_SOL, SystemProgram, Transaction, Keypair, Connection, ComputeBudgetProgram, sendAndConfirmTransaction } from "@solana/web3.js"; const connection \= new Connection("http://localhost:8899", "confirmed"); const sender \= Keypair.generate(); const recipient \= new Keypair(); const airdropSignature \= await connection.requestAirdrop( sender.publicKey, LAMPORTS\_PER\_SOL ); await connection.confirmTransaction(airdropSignature, "confirmed"); // Create compute budget instructions const limitInstruction \= ComputeBudgetProgram.setComputeUnitLimit({ units: 300\_000 }); const priceInstruction \= ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 }); const transferInstruction \= SystemProgram.transfer({ fromPubkey: sender.publicKey, toPubkey: recipient.publicKey, lamports: 0.01 \* LAMPORTS\_PER\_SOL }); // Add the compute budget and transfer instructions to a new transaction const transaction \= new Transaction() .add(limitInstruction) .add(priceInstruction) .add(transferInstruction); const signature \= await sendAndConfirmTransaction(connection, transaction, \[\ \ sender\ \ \]); console.log("Transaction Signature:", signature); Console RunClick to execute the code. Is this page helpful? [Previous\ \ Transactions](https://solana.com/docs/core/transactions) [Next\ \ Programs](https://solana.com/docs/core/programs) ### Table of Contents [Base fee](https://solana.com/docs/core/fees#base-fee) [Prioritization fee](https://solana.com/docs/core/fees#prioritization-fee) [Compute unit limit](https://solana.com/docs/core/fees#compute-unit-limit) [Compute unit price](https://solana.com/docs/core/fees#compute-unit-price) [Example](https://solana.com/docs/core/fees#example) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/core/fees.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter Transaction Fees | Solana --- # Program-Derived Address | Solana [Solana Documentation](https://solana.com/docs) [Core Concepts](https://solana.com/docs/core) [Program-Derived Address](https://solana.com/docs/core/pda) ============================================================ Copy MarkdownOpen A Solana [account address](https://solana.com/docs/core/accounts#account-address) points to the account's location on the blockchain. Many account addresses are the public key of a keypair, in which case the corresponding private key is used to sign transactions involving the account. A useful alternative to a public key address is a program-derived address (PDA). PDAs provide an easy method to store, map, and fetch program state. A PDA is an address that is created deterministically using a program ID and a combination of optional predefined inputs. PDAs look similar to public key addresses, but do not have a corresponding private key. The Solana runtime enables programs to sign for PDAs without needing a private key. Using a PDA eliminates the need to keep track of the account's address. Instead, you can recall the specific inputs used for the PDA's derivation. (To learn how programs use PDAs for signing, see the [Cross Program Invocations](https://solana.com/docs/core/cpi) section.) [Background](https://solana.com/docs/core/pda#background) ---------------------------------------------------------- Solana [keypairs](https://github.com/anza-xyz/solana-sdk/blob/sdk%40v2.2.2/keypair/src/lib.rs#L26) are points on the [Ed25519 curve](https://ed25519.cr.yp.to/) (elliptic-curve cryptography). They consist of a public key and a private key. The public key becomes the account address, and the private key is used to generate valid [signature](https://solana.com/docs/core/transactions#signatures) for the account. ![Two accounts with on-curve addresses](https://solana.com/assets/docs/core/pda/address-on-curve.svg)Two accounts with on-curve addresses A PDA is intentionally derived to fall off the Ed25519 curve. This means it does not have a valid corresponding private key and can't perform cryptographic operations. (Such as providing a signature.) However, Solana enables programs to sign for PDAs without needing a private key. ![Off Curve Address](https://solana.com/assets/docs/core/pda/address-off-curve.svg)Off Curve Address You can think of PDAs as a way to create hashmap-like structures on-chain using a predefined set of inputs. (For example, strings, numbers, and other account addresses.) ![Program Derived Address](https://solana.com/assets/docs/core/pda/pda.svg)Program Derived Address [Derive a PDA](https://solana.com/docs/core/pda#derive-a-pda) -------------------------------------------------------------- Before creating an account with a PDA, you must first derive the address. Deriving a PDA _does not_ automatically create an on-chain account at that address— the account must be explicitly created through the program used to derive the PDA. You can think of a PDA like an address on a map: just because an address exists doesn't mean there is anything built there. The Solana SDKs support PDA creation with the functions shown in the table below. Each function receives the following input: * **Program ID**: The address of the program being used to derive the PDA. This program can sign on behalf of the PDA. * **Optional seeds**: Predefined inputs, such as strings, numbers or other account addresses. | SDK | Function | | --- | --- | | `@solana/kit` (Typescript) | [`getProgramDerivedAddress`](https://github.com/anza-xyz/kit/blob/v2.1.0/packages/addresses/src/program-derived-address.ts#L157) | | `@solana/web3.js` (Typescript) | [`findProgramAddressSync`](https://github.com/solana-foundation/solana-web3.js/blob/v1.98.0/src/publickey.ts#L212) | | `solana_sdk` (Rust) | [`find_program_address`](https://github.com/anza-xyz/solana-sdk/blob/sdk%40v2.2.2/pubkey/src/lib.rs#L617) | The function uses the program ID and optional seeds, then iterates through bump values to attempt to create a valid program address. The iteration of bump values starts at 255 and decrements by 1 until a valid PDA is found. After a valid PDA is found, the function returns the PDA and the bump seed. The bump seed is an extra byte appended to the optional seeds to ensure a valid off-curve address is generated. ![PDA Derivation](https://solana.com/assets/docs/core/pda/pda-derivation.svg)PDA Derivation ### [Canonical bump](https://solana.com/docs/core/pda#canonical-bump) A bump seed is an extra byte appended to the optional seeds. The derivation function iterates through bump values, starting at 255 and decrementing by 1, until a value produces a valid off-curve address. The first value that produces a valid off-curve address is called the "canonical bump." The following examples show PDA derivation using all possible bump seeds (255 to 0): Kit example is not included because the [createProgramDerivedAddress](https://github.com/anza-xyz/kit/blob/v2.1.0/packages/addresses/src/program-derived-address.ts#L101) function isn't exported. Legacy Rust import { PublicKey } from "@solana/web3.js"; const programId \= new PublicKey("11111111111111111111111111111111"); const optionalSeed \= "helloWorld"; // Loop through all bump seeds (255 down to 0) for (let bump \= 255; bump \>= 0; bump\--) { try { const PDA \= PublicKey.createProgramAddressSync( \[Buffer.from(optionalSeed), Buffer.from(\[bump\])\], programId ); console.log("bump " + bump + ": " + PDA); } catch (error) { console.log("bump " + bump + ": " + error); } } Console RunClick to execute the code. Legacy Rust import { PublicKey } from "@solana/web3.js"; const programId \= new PublicKey("11111111111111111111111111111111"); const optionalSeed \= "helloWorld"; // Loop through all bump seeds (255 down to 0) for (let bump \= 255; bump \>= 0; bump\--) { try { const PDA \= PublicKey.createProgramAddressSync( \[Buffer.from(optionalSeed), Buffer.from(\[bump\])\], programId ); console.log("bump " + bump + ": " + PDA); } catch (error) { console.log("bump " + bump + ": " + error); } } Console RunClick to execute the code. Expected TS Output Expected Rust Output bump 255: Error: Invalid seeds, address must fall off the curve bump 254: 46GZzzetjCURsdFPb7rcnspbEMnCBXe9kpjrsZAkKb6X bump 253: GBNWBGxKmdcd7JrMnBdZke9Fumj9sir4rpbruwEGmR4y bump 252: THfBMgduMonjaNsCisKa7Qz2cBoG1VCUYHyso7UXYHH bump 251: EuRrNqJAofo7y3Jy6MGvF7eZAYegqYTwH2dnLCwDDGdP bump 250: Error: Invalid seeds, address must fall off the curve ... // remaining bump outputs In this example, the first bump seed throws an error. The first bump seed to derive a valid PDA is 254. Bump seeds 253-251 also derive unique, valid PDAs. This means that given the same optional seeds and `programId`, a bump seed with a different value can still derive a valid PDA. Always include security checks to ensure a PDA passed to the program is derived from the canonical bump. Failure to do so may introduce vulnerabilities that allow unexpected accounts to be used in the program's instructions. It is best practice to only use the canonical bump when deriving PDAs. ### [Examples](https://solana.com/docs/core/pda#examples) The examples below derive a PDA using the Solana SDKs. Click **▷ Run** to execute the code. #### [Derive a PDA with a string seed](https://solana.com/docs/core/pda#derive-a-pda-with-a-string-seed) The example below derives a PDA using a program ID and an optional string seed. Kit Legacy Rust import { Address, getProgramDerivedAddress } from "@solana/kit"; const programAddress \= "11111111111111111111111111111111" as Address; const seeds \= \["helloWorld"\]; const \[pda, bump\] \= await getProgramDerivedAddress({ programAddress, seeds }); console.log(\`PDA: ${pda}\`); console.log(\`Bump: ${bump}\`); Console RunClick to execute the code. Kit Legacy Rust import { Address, getProgramDerivedAddress } from "@solana/kit"; const programAddress \= "11111111111111111111111111111111" as Address; const seeds \= \["helloWorld"\]; const \[pda, bump\] \= await getProgramDerivedAddress({ programAddress, seeds }); console.log(\`PDA: ${pda}\`); console.log(\`Bump: ${bump}\`); Console RunClick to execute the code. #### [Derive a PDA with an address seed](https://solana.com/docs/core/pda#derive-a-pda-with-an-address-seed) The example below derives a PDA using a program ID and an optional address seed. Kit Legacy Rust import { Address, getAddressEncoder, getProgramDerivedAddress } from "@solana/kit"; const programAddress \= "11111111111111111111111111111111" as Address; const addressEncoder \= getAddressEncoder(); const optionalSeedAddress \= addressEncoder.encode( "B9Lf9z5BfNPT4d5KMeaBFx8x1G4CULZYR1jA2kmxRDka" as Address ); const seeds \= \[optionalSeedAddress\]; const \[pda, bump\] \= await getProgramDerivedAddress({ programAddress, seeds }); console.log(\`PDA: ${pda}\`); console.log(\`Bump: ${bump}\`); Console RunClick to execute the code. Kit Legacy Rust import { Address, getAddressEncoder, getProgramDerivedAddress } from "@solana/kit"; const programAddress \= "11111111111111111111111111111111" as Address; const addressEncoder \= getAddressEncoder(); const optionalSeedAddress \= addressEncoder.encode( "B9Lf9z5BfNPT4d5KMeaBFx8x1G4CULZYR1jA2kmxRDka" as Address ); const seeds \= \[optionalSeedAddress\]; const \[pda, bump\] \= await getProgramDerivedAddress({ programAddress, seeds }); console.log(\`PDA: ${pda}\`); console.log(\`Bump: ${bump}\`); Console RunClick to execute the code. #### [Derive a PDA with multiple seeds](https://solana.com/docs/core/pda#derive-a-pda-with-multiple-seeds) The example below derives a PDA using a program ID and multiple optional seeds. Kit Legacy Rust import { Address, getAddressEncoder, getProgramDerivedAddress } from "@solana/kit"; const programAddress \= "11111111111111111111111111111111" as Address; const optionalSeedString \= "helloWorld"; const addressEncoder \= getAddressEncoder(); const optionalSeedAddress \= addressEncoder.encode( "B9Lf9z5BfNPT4d5KMeaBFx8x1G4CULZYR1jA2kmxRDka" as Address ); const seeds \= \[optionalSeedString, optionalSeedAddress\]; const \[pda, bump\] \= await getProgramDerivedAddress({ programAddress, seeds }); console.log(\`PDA: ${pda}\`); console.log(\`Bump: ${bump}\`); Console RunClick to execute the code. Kit Legacy Rust import { Address, getAddressEncoder, getProgramDerivedAddress } from "@solana/kit"; const programAddress \= "11111111111111111111111111111111" as Address; const optionalSeedString \= "helloWorld"; const addressEncoder \= getAddressEncoder(); const optionalSeedAddress \= addressEncoder.encode( "B9Lf9z5BfNPT4d5KMeaBFx8x1G4CULZYR1jA2kmxRDka" as Address ); const seeds \= \[optionalSeedString, optionalSeedAddress\]; const \[pda, bump\] \= await getProgramDerivedAddress({ programAddress, seeds }); console.log(\`PDA: ${pda}\`); console.log(\`Bump: ${bump}\`); Console RunClick to execute the code. [Create a PDA account](https://solana.com/docs/core/pda#create-a-pda-account) ------------------------------------------------------------------------------ The example below uses the [Anchor framework](https://www.anchor-lang.com/docs) to create a new account with a program-derived address. The program includes a single `initialize` instruction to create the new account, which will store the user address and bump seed used to derive the PDA. Program use anchor\_lang::prelude::\*; declare\_id!("75GJVCJNhaukaa2vCCqhreY31gaphv7XTScBChmr1ueR"); #\[program\] pub mod pda\_account { use super::\*; pub fn initialize(ctx: Context) \-> Result<()> { let account\_data \= &mut ctx.accounts.pda\_account; // store the address of the \`user\` account\_data.user \= \*ctx.accounts.user.key; // store the canonical bumpd account\_data.bump \= ctx.bumps.pda\_account; Ok(()) } } #\[derive(Accounts)\] pub struct Initialize<'info\> { #\[account(mut)\] pub user: Signer<'info\>, #\[account(\ \ init,\ \ // define the seeds to derive the PDA\ \ seeds \= \[b"data", user.key().as\_ref()\],\ \ // use the canonical bump\ \ bump,\ \ payer \= user,\ \ space \= 8 + DataAccount::INIT\_SPACE\ \ )\] pub pda\_account: Account<'info, DataAccount\>, pub system\_program: Program<'info, System\>, } #\[account\] #\[derive(InitSpace)\] pub struct DataAccount { pub user: Pubkey, pub bump: u8, } The `init` constraint tells Anchor to [invoke the System Program](https://solana.com/docs/core/programs#the-system-program) to create a new account using the PDA as the address. The seeds used to create the PDA are: * The address of the user account provided in the instruction * The fixed string: "data" * The canonical bump seed In this example, the bump constraint is not assigned a value, so Anchor will use `find_program_address` to derive the PDA and find the bump. pda\_account #\[account(\ \ init,\ \ seeds \= \[b"data", user.key().as\_ref()\],\ \ bump,\ \ payer \= user,\ \ space \= 8 + DataAccount::INIT\_SPACE\ \ )\] pub pda\_account: Account<'info, DataAccount\>, The test file below contains a transaction that invokes the `initialize` instruction to create a new account with a program-derived address. The file contains code to derive the PDA. The example also shows how to fetch the new account that will be created. Test import \* as anchor from "@coral-xyz/anchor"; import { Program } from "@coral-xyz/anchor"; import { PdaAccount } from "../target/types/pda\_account"; import { PublicKey } from "@solana/web3.js"; describe("pda-account", () \=> { const provider \= anchor.AnchorProvider.env(); anchor.setProvider(provider); const program \= anchor.workspace.PdaAccount as Program; const user \= provider.wallet as anchor.Wallet; // Derive the PDA address using the seeds specified on the program const \[PDA\] \= PublicKey.findProgramAddressSync( \[Buffer.from("data"), user.publicKey.toBuffer()\], program.programId ); it("Is initialized!", async () \=> { const transactionSignature \= await program.methods .initialize() .accounts({ user: user.publicKey }) .rpc(); console.log("Transaction Signature:", transactionSignature); }); it("Fetch Account", async () \=> { const pdaAccount \= await program.account.dataAccount.fetch(PDA); console.log(JSON.stringify(pdaAccount, null, 2)); }); }); If you invoke the `initialize` instruction again with the same `user` address seed, the transaction will fail. This happens because an account already exists at the derived address. Is this page helpful? [Previous\ \ Programs](https://solana.com/docs/core/programs) [Next\ \ Cross Program Invocation](https://solana.com/docs/core/cpi) ### Table of Contents [Background](https://solana.com/docs/core/pda#background) [Derive a PDA](https://solana.com/docs/core/pda#derive-a-pda) [Canonical bump](https://solana.com/docs/core/pda#canonical-bump) [Examples](https://solana.com/docs/core/pda#examples) [Derive a PDA with a string seed](https://solana.com/docs/core/pda#derive-a-pda-with-a-string-seed) [Derive a PDA with an address seed](https://solana.com/docs/core/pda#derive-a-pda-with-an-address-seed) [Derive a PDA with multiple seeds](https://solana.com/docs/core/pda#derive-a-pda-with-multiple-seeds) [Create a PDA account](https://solana.com/docs/core/pda#create-a-pda-account) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/core/pda.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter Program-Derived Address | Solana --- # Tokens on Solana | Solana This website uses cookies to offer you a better browsing experience. Find out more on how we use cookies. Opt-out[Details](https://solana.com/privacy-policy#collection-of-information) Accept [Solana Documentation](https://solana.com/docs) [Tokens on Solana](https://solana.com/docs/tokens) =================================================== Copy MarkdownOpen Tokens are digital assets that represent ownership over diverse categories of assets. Tokenization enables the digitalization of property rights. Tokens on Solana are referred to as SPL ([Solana Program Library](https://github.com/solana-program) ) Tokens. This section covers the basic concepts of how tokens are represented on Solana. Refer to the [SPL Token Basics](https://solana.com/docs/tokens/basics) section for code examples. [Key Points](https://solana.com/docs/tokens#key-points) -------------------------------------------------------- * [Token Programs](https://solana.com/docs/tokens#token-program) contain all instruction logic for interacting with tokens on the network (both fungible and non-fungible). * A [Mint Account](https://solana.com/docs/tokens#mint-account) represents a specific token and stores global metadata about the token such as the total supply and mint authority (address authorized to create new units of a token). * A [Token Account](https://solana.com/docs/tokens#token-account) tracks individual ownership of tokens for a specific mint account for a specific owner. * An [Associated Token Account](https://solana.com/docs/tokens#associated-token-account) is a Token Account created with an address derived from the owner and mint account addresses. [Token Programs](https://solana.com/docs/tokens#token-programs) ---------------------------------------------------------------- The Solana ecosystem has two main Token Programs. Source code for both programs below. [### Token Program (Original)\ \ * Basic token capability (mint, transfer, etc.)\ * Immutable and widely used](https://github.com/solana-program/token) [### Token Extension Program (Token 2022)\ \ * Includes all original Token Program features\ * Adds features through "extensions"](https://github.com/solana-program/token-2022) Token Programs contains all instruction logic for interacting with tokens on the network (both fungible and non-fungible). All tokens on Solana are effectively [data accounts](https://solana.com/docs/core/accounts#data-account) owned by a Token Program. ![Token Program](https://solana.com/assets/docs/core/tokens/token-program.svg)Token Program ### [Mint Account](https://solana.com/docs/tokens#mint-account) Tokens on Solana are uniquely identified by the address of a [Mint Account](https://github.com/solana-program/token/blob/6d18ff73b1dd30703a30b1ca941cb0f1d18c2b2a/program/src/state.rs#L16-L30) owned by the Token Program. This account acts as a global counter for a specific token and stores data such as: * **Supply**: Total supply of the token * **Decimals**: Decimal precision of the token * **Mint authority**: The account authorized to create new units of the token, increasing the supply * **Freeze authority**: The account authorized to freeze tokens in a Token Account, preventing them from being transferred or burned ![Mint Account](https://solana.com/assets/docs/core/tokens/mint-account.svg)Mint Account The full details stored on each Mint Account include the following: Mint Account State 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, /// 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 initialized pub is\_initialized: bool, /// Optional authority to freeze token accounts. pub freeze\_authority: COption, } For reference, here is a Solana Explorer link to the [USDC Mint Account](https://explorer.solana.com/address/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v) . ### [Token Account](https://solana.com/docs/tokens#token-account) The Token Program creates [Token Accounts](https://github.com/solana-program/token/blob/6d18ff73b1dd30703a30b1ca941cb0f1d18c2b2a/program/src/state.rs#L87-L108) to track individual ownership of each token unit. A Token Account stores data such as: * **Mint**: The token the Token Account holds units of * **Owner**: The account authorized to transfer tokens from the Token Account * **Amount**: Number of the tokens the Token Account currently holds ![Token Account](https://solana.com/assets/docs/core/tokens/token-account.svg)Token Account The full details stored on each Token Account include the following: Token Account State pub struct Account { /// The mint associated with this account pub mint: Pubkey, /// The owner of this account. pub owner: Pubkey, /// The amount of tokens this account holds. pub amount: u64, /// If \`delegate\` is \`Some\` then \`delegated\_amount\` represents /// the amount authorized by the delegate pub delegate: COption, /// The account's state pub state: AccountState, /// If is\_native.is\_some, this is a native token, and the value logs the /// rent-exempt reserve. An Account is required to be rent-exempt, so /// the value is used by the Processor to ensure that wrapped SOL /// accounts do not drop below this threshold. pub is\_native: COption, /// The amount delegated pub delegated\_amount: u64, /// Optional authority to close the account. pub close\_authority: COption, } A wallet needs a token account for each token (mint) it wants to hold, with the wallet address set as the token account owner. Each wallet can own multiple token accounts for the same token (mint), but a token account can only have one owner and hold units of one token (mint). ![Account Relationship](https://solana.com/assets/docs/core/tokens/token-account-relationship.svg)Account Relationship Note that each Token Account's data includes an `owner` field identifying who has authority over the Token Account. This differs from the program owner specified in the base [Account](https://solana.com/docs/core/accounts#account-type) type, which is the Token Program for all Token Accounts. ### [Associated Token Account](https://solana.com/docs/tokens#associated-token-account) Associated Token Accounts simplify the process of finding a token account's address for a specific mint and owner. Think of the Associated Token Account as the "default" token account for a specific mint and owner. An Associated Token Account is created with an address derived from the owner's address and the mint account's address. It's important to understand that an Associated Token Account is just a token account with a specific address. This introduces a key concept in Solana development: [Program Derived Address (PDA)](https://solana.com/docs/core/pda) . A PDA derives an address deterministically using predefined inputs, making it easy to find the address of an account. ![Associated Token Account](https://solana.com/assets/docs/core/tokens/associated-token-account.svg)Associated Token Account Note that each wallet needs its own token account to hold tokens from the same mint. ![Accounts Relationship Expanded](https://solana.com/assets/docs/core/tokens/token-account-relationship-ata.svg)Accounts Relationship Expanded [Token CLI Examples](https://solana.com/docs/tokens#token-cli-examples) ------------------------------------------------------------------------ The `spl-token` CLI helps you experiment with SPL tokens. The examples below use the [Solana Playground](https://beta.solpg.io/) terminal to run CLI commands directly in the browser without local installation. Creating tokens and accounts requires SOL for account rent deposits and transaction fees. For first-time Solana Playground users, create a Playground wallet and run the `solana airdrop` command in the Playground terminal. You can also get devnet SOL from the public [web faucet](https://faucet.solana.com/) . Terminal $ solana airdrop 2 Copy Run `spl-token --help` to see all available commands. Terminal $ spl-token --help Copy To install the `spl-token` CLI locally, run: Terminal $ cargo install spl-token-cli Copy Find more examples in the `spl-token` [documentation](https://www.solana-program.com/docs/token) . The account addresses shown in your terminal output differ from the examples below. Use the addresses from your Playground terminal when following along. For example, the `create-token` command outputs a mint account address with your Playground wallet as the mint authority. ### [Create a New Token](https://solana.com/docs/tokens#create-a-new-token) To create a new token (mint account), run: Terminal $ spl-token create-token Copy The output looks like: Terminal Output Creating token 99zqUzQGohamfYxyo8ykTEbi91iom3CLmwCA75FK5zTg Address: 99zqUzQGohamfYxyo8ykTEbi91iom3CLmwCA75FK5zTg Decimals: 9 Signature: 44fvKfT1ezBUwdzrCys3fvCdFxbLMnNvBstds76QZyE6cXag5NupBprSXwxPTzzjrC3cA6nvUZaLFTvmcKyzxrm1 A new mint account starts with zero supply. Check the current supply with: Terminal $ spl-token supply Copy The `supply` command for a new token returns `0`: Example spl-token supply 99zqUzQGohamfYxyo8ykTEbi91iom3CLmwCA75FK5zTg Creating a new Mint Account requires a transaction with two instructions. Here's a Javascript example on [Solana Playground](https://beta.solpg.io/660ce32ecffcf4b13384d00f) . 1. The System Program creates a new account with space for the Mint Account data and transfers ownership to the Token Program. 2. The Token Program initializes the data of the new account as a Mint Account ### [Create Token Account](https://solana.com/docs/tokens#create-token-account) To hold tokens of a specific mint, create a token account: Terminal $ spl-token create-account Copy Example command: Example spl-token create-account 99zqUzQGohamfYxyo8ykTEbi91iom3CLmwCA75FK5zTg Output: Terminal Output Creating account AfB7uwBEsGtrrBqPTVqEgzWed5XdYfM1psPNLmf7EeX9 Signature: 2BtrynuCLX9CNofFiaw6Yzbx6hit66pup9Sk7aFjwU2NEbFz7NCHD9w9sWhrCfEd73XveAGK1DxFpJoQZPXU9tS1 The `create-account` command creates an associated token account with your wallet address as the owner. To create a token account with a different owner: Terminal $ spl-token create-account --owner Copy Note: `` specifies the mint account for the token account. Example command: Example spl-token create-account \--owner 2i3KvjDCZWxBsqcxBHpdEaZYQwQSYE6LXUMx5VjY5XrR 99zqUzQGohamfYxyo8ykTEbi91iom3CLmwCA75FK5zTg Output: Terminal Output Creating account Hmyk3FSw4cfsuAes7sanp2oxSkE9ivaH6pMzDzbacqmt Signature: 44vqKdfzspT592REDPY4goaRJH3uJ3Ce13G4BCuUHg35dVUbHuGTHvqn4ZjYF9BGe9QrjMfe9GmuLkQhSZCBQuEt Creating an Associated Token Account requires one instruction that invokes the [Associated Token Program](https://github.com/solana-program/associated-token-account) . Here's a Javascript example on [Solana Playground](https://beta.solpg.io/660ce868cffcf4b13384d011) . The Associated Token Program uses [Cross Program Invocations](https://solana.com/docs/core/cpi) to: * [Invoke the System Program](https://github.com/solana-program/associated-token-account/blob/9d94201e8158f06015ff80ad47fefac62a2ec450/program/src/tools/account.rs#L19) to create a new account using the provided PDA as the address * [Invoke the Token Program](https://github.com/solana-program/associated-token-account/blob/9d94201e8158f06015ff80ad47fefac62a2ec450/program/src/processor.rs#L138-L161) to initialize the Token Account data To create a new Token Account with a new keypair instead of an Associated Token Account address, send a transaction with two instructions. Here's a Javascript example on [Solana Playground](https://beta.solpg.io/660ce716cffcf4b13384d010) . 1. The System Program creates a new account with space for the Token Account data and transfers ownership to the Token Program. 2. The Token Program initializes the data as a Token Account ### [Mint Tokens](https://solana.com/docs/tokens#mint-tokens) To create new units of a token, mint tokens to a Token Account: Terminal $ spl-token mint \[OPTIONS\] \[--\] \[RECIPIENT\_TOKEN\_ACCOUNT\_ADDRESS\] Copy Example command: Example spl-token mint 99zqUzQGohamfYxyo8ykTEbi91iom3CLmwCA75FK5zTg 100 Output: Terminal Output Minting 100 tokens Token: 99zqUzQGohamfYxyo8ykTEbi91iom3CLmwCA75FK5zTg Recipient: AfB7uwBEsGtrrBqPTVqEgzWed5XdYfM1psPNLmf7EeX9 Signature: 2NJ1m7qCraPSBAVxbr2ssmWZmBU9Jc8pDtJAnyZsZJRcaYCYMqq1oRY1gqA4ddQno3g3xcnny5fzr1dvsnFKMEqG To mint tokens to a different token account: Example spl-token mint 99zqUzQGohamfYxyo8ykTEbi91iom3CLmwCA75FK5zTg 100 -- Hmyk3FSw4cfsuAes7sanp2oxSkE9ivaH6pMzDzbacqmt Output: Terminal Output Minting 100 tokens Token: 99zqUzQGohamfYxyo8ykTEbi91iom3CLmwCA75FK5zTg Recipient: Hmyk3FSw4cfsuAes7sanp2oxSkE9ivaH6pMzDzbacqmt Signature: 3SQvNM3o9DsTiLwcEkSPT1Edr14RgE2wC54TEjonEP2swyVCp2jPWYWdD6RwXUGpvDNUkKWzVBZVFShn5yntxVd7 The `MintTo` instruction on the Token Program creates new tokens. The mint authority must sign the transaction. The instruction mints tokens to a Token Account and increases the total supply on the Mint Account. Here's a Javascript example on [Solana Playground](https://beta.solpg.io/660cea45cffcf4b13384d012) . ### [Transfer Tokens](https://solana.com/docs/tokens#transfer-tokens) To transfer tokens between token accounts: Terminal spl-token transfer \[OPTIONS\] Example command: Example spl-token transfer 99zqUzQGohamfYxyo8ykTEbi91iom3CLmwCA75FK5zTg 100 Hmyk3FSw4cfsuAes7sanp2oxSkE9ivaH6pMzDzbacqmt Output: Terminal Output Transfer 100 tokens Sender: AfB7uwBEsGtrrBqPTVqEgzWed5XdYfM1psPNLmf7EeX9 Recipient: Hmyk3FSw4cfsuAes7sanp2oxSkE9ivaH6pMzDzbacqmt Signature: 5y6HVwV8V2hHGLTVmTmdySRiEUCZnWmkasAvJ7J6m7JR46obbGKCBqUFgLpZu5zQGwM4Xy6GZ4M5LKd1h6Padx3o The `Transfer` instruction on the Token Program handles token transfers. The owner of the sender's Token Account must sign the transaction. The instruction moves tokens between Token Accounts. Here's a Javascript example on [Solana Playground](https://beta.solpg.io/660ced84cffcf4b13384d013) . Both sender and recipient need token accounts for the specific token (mint). The sender can include instructions to create the recipient's token account in the same transaction. ### [Create Token Metadata](https://solana.com/docs/tokens#create-token-metadata) The Token Extensions Program lets you store metadata (name, symbol, image link) directly on the Mint Account. To create a token with metadata extension: Example spl-token create-token \--program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb \--enable-metadata Output: Terminal Output Creating token BdhzpzhTD1MFqBiwNdrRy4jFo2FHFufw3n9e8sVjJczP under program TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb To initialize metadata inside the mint, please run \`spl-token initialize-metadata BdhzpzhTD1MFqBiwNdrRy4jFo2FHFufw3n9e8sVjJczP \`, and sign with the mint authority. Address: BdhzpzhTD1MFqBiwNdrRy4jFo2FHFufw3n9e8sVjJczP Decimals: 9 Signature: 5iQofFeXdYhMi9uTzZghcq8stAaa6CY6saUwcdnELST13eNSifiuLbvR5DnRt311frkCTUh5oecj8YEvZSB3wfai To initialize the metadata: Terminal spl-token initialize-metadata The token URI links to off-chain metadata. See an example JSON format [here](https://raw.githubusercontent.com/solana-developers/opos-asset/main/assets/DeveloperPortal/metadata.json) . Example command: Example spl-token initialize-metadata BdhzpzhTD1MFqBiwNdrRy4jFo2FHFufw3n9e8sVjJczP "TokenName" "TokenSymbol" "https://raw.githubusercontent.com/solana-developers/opos-asset/main/assets/DeveloperPortal/metadata.json" View the metadata on [Solana Explorer](https://explorer.solana.com/address/BdhzpzhTD1MFqBiwNdrRy4jFo2FHFufw3n9e8sVjJczP?cluster=devnet) . Learn more in the [Metadata Extension Guide](https://solana.com/developers/guides/token-extensions/metadata-pointer) . For details about Token Extensions, see the Token Extensions [Getting Started Guide](https://solana.com/developers/guides/token-extensions/getting-started) and the [SPL documentation](https://www.solana-program.com/docs/token-2022/extensions) . Is this page helpful? [Previous\ \ Cross Program Invocation](https://solana.com/docs/core/cpi) [Next\ \ SPL Token Basics](https://solana.com/docs/tokens/basics) ### Table of Contents [Key Points](https://solana.com/docs/tokens#key-points) [Token Programs](https://solana.com/docs/tokens#token-programs) [Mint Account](https://solana.com/docs/tokens#mint-account) [Token Account](https://solana.com/docs/tokens#token-account) [Associated Token Account](https://solana.com/docs/tokens#associated-token-account) [Token CLI Examples](https://solana.com/docs/tokens#token-cli-examples) [Create a New Token](https://solana.com/docs/tokens#create-a-new-token) [Create Token Account](https://solana.com/docs/tokens#create-token-account) [Mint Tokens](https://solana.com/docs/tokens#mint-tokens) [Transfer Tokens](https://solana.com/docs/tokens#transfer-tokens) [Create Token Metadata](https://solana.com/docs/tokens#create-token-metadata) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/tokens/index.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter Tokens on Solana | Solana --- # Cross Program Invocation | Solana [Solana Documentation](https://solana.com/docs) [Core Concepts](https://solana.com/docs/core) [Cross Program Invocation](https://solana.com/docs/core/cpi) ============================================================= Copy MarkdownOpen A cross-program invocation (CPI) occurs when one Solana program directly invokes the instructions of another program. This allows for program composability. If you think of a Solana [instruction](https://solana.com/docs/core/instructions) as an API endpoint that a program exposes to the network, a CPI is like one endpoint internally invoking another. When making a CPI, a program can [sign](https://solana.com/docs/references/terminology#signature) on behalf of a [PDA](https://solana.com/docs/core/pda) derived from its program ID. These signer privileges extend from the caller program to the callee program. ![Cross-program invocation example](https://solana.com/assets/docs/core/cpi/cpi.svg)Cross-program invocation example When making a CPI, account privileges extend from one program to another. Let's say Program A receives an instruction with a signer account and a writable account. Program A then makes a CPI to Program B. Now, Program B can use the same accounts as Program A, with their original permissions. (Meaning Program B can sign with the signer account and can write to the writable account.) If Program B makes its own CPIs, it can pass these same permissions forward, up to a depth of 4. The maximum height of the program instruction invocation is called the [`max_instruction_stack_depth`](https://github.com/anza-xyz/agave/blob/v2.1.13/compute-budget/src/compute_budget.rs#L38) and is set to the [MAX\_INSTRUCTION\_STACK\_DEPTH](https://github.com/anza-xyz/agave/blob/v2.1.13/compute-budget/src/compute_budget.rs#L13) constant of 5. The stack height begins at 1 for the initial transaction and increases by 1 each time a program invokes another instruction, limiting invocation depth for CPIs to 4. [CPIs with PDA signers](https://solana.com/docs/core/cpi#cpis-with-pda-signers) -------------------------------------------------------------------------------- When a CPI requires a PDA signer, the [`invoke_signed`](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/program/src/program.rs#L51-L73) function is used. It takes the signer seeds used for deriving signer [PDAs](https://solana.com/docs/core/pda) . The Solana runtime internally calls [`create_program_address`](https://github.com/anza-xyz/agave/blob/v2.1.13/programs/bpf_loader/src/syscalls/cpi.rs#L552) using the `signers_seeds` and the `program_id` of the caller program. When a PDA is verified, it is [added as a valid signer](https://github.com/anza-xyz/agave/blob/v2.1.13/programs/bpf_loader/src/syscalls/cpi.rs#L554) . Invoke signed pub fn invoke\_signed( instruction: &Instruction, account\_infos: &\[AccountInfo\], signers\_seeds: &\[&\[&\[u8\]\]\], ) \-> ProgramResult { // --snip-- invoke\_signed\_unchecked(instruction, account\_infos, signers\_seeds) } The examples below make a CPI with PDA signers using Anchor and Native Rust. Each example includes a single instruction to transfer SOL from a PDA to a recipient account, using a CPI signed by the PDA. #### [Anchor](https://solana.com/docs/core/cpi#anchor) The following examples show three approaches to implementing CPIs in an [Anchor](https://www.anchor-lang.com/docs) program. The examples are functionally equivalent, but each demonstrates a different level of abstraction. * **Example 1**: Uses Anchor's `CpiContext` and helper function. * **Example 2**: Uses the `system_instruction::transfer` function from `solana_program` crate. (Example 1 is an abstraction of this implementation.) * **Example 3**: Constructs the CPI instruction manually. This approach is useful when there is no crate available to help build the instruction you want to invoke. Example 1 Example 2 Example 3 Test use anchor\_lang::prelude::\*; use anchor\_lang::system\_program::{transfer, Transfer}; declare\_id!("BrcdB9sV7z9DvF9rDHG263HUxXgJM3iCQdF36TcxbFEn"); #\[program\] pub mod cpi { use super::\*; pub fn sol\_transfer(ctx: Context, amount: u64) \-> Result<()> { let from\_pubkey \= ctx.accounts.pda\_account.to\_account\_info(); let to\_pubkey \= ctx.accounts.recipient.to\_account\_info(); let program\_id \= ctx.accounts.system\_program.to\_account\_info(); let seed \= to\_pubkey.key(); let bump\_seed \= ctx.bumps.pda\_account; let signer\_seeds: &\[&\[&\[u8\]\]\] \= &\[&\[b"pda", seed.as\_ref(), &\[bump\_seed\]\]\]; let cpi\_context \= CpiContext::new( program\_id, Transfer { from: from\_pubkey, to: to\_pubkey, }, ) .with\_signer(signer\_seeds); transfer(cpi\_context, amount)?; Ok(()) } } #\[derive(Accounts)\] pub struct SolTransfer<'info\> { #\[account(\ \ mut,\ \ seeds \= \[b"pda", recipient.key().as\_ref()\],\ \ bump,\ \ )\] pda\_account: SystemAccount<'info\>, #\[account(mut)\] recipient: SystemAccount<'info\>, system\_program: Program<'info, System\>, } #### [Rust](https://solana.com/docs/core/cpi#rust) The example below makes a CPI with PDA signers from a program written in Native Rust. It includes a single instruction that transfers SOL from a PDA account to another. The CPI is signed by the PDA account. (The test file uses [LiteSVM](https://github.com/LiteSVM/litesvm) to test the program.) Example Test use borsh::BorshDeserialize; use solana\_program::{ account\_info::AccountInfo, entrypoint, entrypoint::ProgramResult, program::invoke\_signed, program\_error::ProgramError, pubkey::Pubkey, system\_instruction, }; // Declare program entrypoint entrypoint!(process\_instruction); // Define program instructions #\[derive(BorshDeserialize)\] enum ProgramInstruction { SolTransfer { amount: u64 }, } impl ProgramInstruction { fn unpack(input: &\[u8\]) \-> Result { Self::try\_from\_slice(input).map\_err(|\_| ProgramError::InvalidInstructionData) } } pub fn process\_instruction( program\_id: &Pubkey, accounts: &\[AccountInfo\], instruction\_data: &\[u8\], ) \-> ProgramResult { // Deserialize instruction data let instruction \= ProgramInstruction::unpack(instruction\_data)?; // Process instruction match instruction { ProgramInstruction::SolTransfer { amount } \=> { // Parse accounts let \[pda\_account\_info, recipient\_info, system\_program\_info\] \= accounts else { return Err(ProgramError::NotEnoughAccountKeys); }; // Derive PDA and verify it matches the account provided by client let recipient\_pubkey \= recipient\_info.key; let seeds \= &\[b"pda", recipient\_pubkey.as\_ref()\]; let (expected\_pda, bump\_seed) \= Pubkey::find\_program\_address(seeds, program\_id); if expected\_pda != \*pda\_account\_info.key { return Err(ProgramError::InvalidArgument); } // Create the transfer instruction let transfer\_ix \= system\_instruction::transfer( pda\_account\_info.key, recipient\_info.key, amount, ); // Create signer seeds for PDA let signer\_seeds: &\[&\[&\[u8\]\]\] \= &\[&\[b"pda", recipient\_pubkey.as\_ref(), &\[bump\_seed\]\]\]; // Invoke the transfer instruction with PDA as signer invoke\_signed( &transfer\_ix, &\[\ \ pda\_account\_info.clone(),\ \ recipient\_info.clone(),\ \ system\_program\_info.clone(),\ \ \], signer\_seeds, )?; Ok(()) } } } [CPIs without PDA signers](https://solana.com/docs/core/cpi#cpis-without-pda-signers) -------------------------------------------------------------------------------------- When a CPI doesn't require PDA signers, the [`invoke`](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/program/src/program.rs#L26-L28) function is used. The `invoke` function calls the `invoke_signed` function with an empty `signers_seeds` array. The empty signers array indicates that no PDAs are required for signing. Invoke function pub fn invoke(instruction: &Instruction, account\_infos: &\[AccountInfo\]) \-> ProgramResult { invoke\_signed(instruction, account\_infos, &\[\]) } The examples below make a CPI using Anchor and Native Rust. It includes a single instruction that transfers SOL from one account to another. #### [Anchor](https://solana.com/docs/core/cpi#anchor-1) The following examples show three approaches to implementing CPIs in an [Anchor](https://www.anchor-lang.com/docs) program. The examples are functionally equivalent, but each demonstrates a different level of abstraction. * **Example 1**: Uses Anchor's `CpiContext` and helper function. * **Example 2**: Uses the `system_instruction::transfer` function from the `solana_program` crate. * **Example 3**: Constructs the CPI instruction manually. This approach is useful when no crate exists to help build the instruction you want to invoke. Example 1 Example 2 Example 3 Test use anchor\_lang::prelude::\*; use anchor\_lang::system\_program::{transfer, Transfer}; declare\_id!("9AvUNHjxscdkiKQ8tUn12QCMXtcnbR9BVGq3ULNzFMRi"); #\[program\] pub mod cpi { use super::\*; pub fn sol\_transfer(ctx: Context, amount: u64) \-> Result<()> { let from\_pubkey \= ctx.accounts.sender.to\_account\_info(); let to\_pubkey \= ctx.accounts.recipient.to\_account\_info(); let program\_id \= ctx.accounts.system\_program.to\_account\_info(); let cpi\_context \= CpiContext::new( program\_id, Transfer { from: from\_pubkey, to: to\_pubkey, }, ); transfer(cpi\_context, amount)?; Ok(()) } } #\[derive(Accounts)\] pub struct SolTransfer<'info\> { #\[account(mut)\] sender: Signer<'info\>, #\[account(mut)\] recipient: SystemAccount<'info\>, system\_program: Program<'info, System\>, } #### [Rust](https://solana.com/docs/core/cpi#rust-1) The following example shows how to make a CPI from a program written in Native Rust. It includes a single instruction that transfers SOL from one account to another. (The test file uses [LiteSVM](https://github.com/LiteSVM/litesvm) to test the program.) Example Test use borsh::BorshDeserialize; use solana\_program::{ account\_info::AccountInfo, entrypoint, entrypoint::ProgramResult, program::invoke, program\_error::ProgramError, pubkey::Pubkey, system\_instruction, }; // Declare program entrypoint entrypoint!(process\_instruction); // Define program instructions #\[derive(BorshDeserialize)\] enum ProgramInstruction { SolTransfer { amount: u64 }, } impl ProgramInstruction { fn unpack(input: &\[u8\]) \-> Result { Self::try\_from\_slice(input).map\_err(|\_| ProgramError::InvalidInstructionData) } } pub fn process\_instruction( \_program\_id: &Pubkey, accounts: &\[AccountInfo\], instruction\_data: &\[u8\], ) \-> ProgramResult { // Deserialize instruction data let instruction \= ProgramInstruction::unpack(instruction\_data)?; // Process instruction match instruction { ProgramInstruction::SolTransfer { amount } \=> { // Parse accounts let \[sender\_info, recipient\_info, system\_program\_info\] \= accounts else { return Err(ProgramError::NotEnoughAccountKeys); }; // Verify the sender is a signer if !sender\_info.is\_signer { return Err(ProgramError::MissingRequiredSignature); } // Create and invoke the transfer instruction let transfer\_ix \= system\_instruction::transfer( sender\_info.key, recipient\_info.key, amount, ); invoke( &transfer\_ix, &\[\ \ sender\_info.clone(),\ \ recipient\_info.clone(),\ \ system\_program\_info.clone(),\ \ \], )?; Ok(()) } } } Is this page helpful? [Previous\ \ Program-Derived Address](https://solana.com/docs/core/pda) [Next\ \ Tokens on Solana](https://solana.com/docs/tokens) ### Table of Contents [CPIs with PDA signers](https://solana.com/docs/core/cpi#cpis-with-pda-signers) [Anchor](https://solana.com/docs/core/cpi#anchor) [Rust](https://solana.com/docs/core/cpi#rust) [CPIs without PDA signers](https://solana.com/docs/core/cpi#cpis-without-pda-signers) [Anchor](https://solana.com/docs/core/cpi#anchor-1) [Rust](https://solana.com/docs/core/cpi#rust-1) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/core/cpi.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter Cross Program Invocation | Solana --- # Rust SDK for Solana | Solana This website uses cookies to offer you a better browsing experience. Find out more on how we use cookies. Opt-out[Details](https://solana.com/privacy-policy#collection-of-information) Accept [Solana Documentation](https://solana.com/docs) Solana SDKsOfficial SDKs [Rust SDK for Solana](https://solana.com/docs/clients/official/rust) ===================================================================== Copy MarkdownOpen [Client Crates](https://solana.com/docs/clients/official/rust#client-crates) ----------------------------------------------------------------------------- | Crate | Description | Docs | GitHub | | --- | --- | --- | --- | | solana-sdk | Core SDK | [View](https://docs.rs/solana-sdk/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/sdk) | | solana-client | Interact with Solana via RPC | [View](https://docs.rs/solana-client/) | [Source](https://github.com/anza-xyz/agave/tree/master/client) | | solana-commitment-config | Transaction commitment level configuration | [View](https://docs.rs/solana-commitment-config/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/commitment-config) | The `solana-sdk` crate is composed of the following component crates, which can be used independently: | Crate | Description | Docs | GitHub | | --- | --- | --- | --- | | solana-account | Solana Account type | [View](https://docs.rs/solana-account/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/account) | | solana-epoch-info | Information about a Solana epoch | [View](https://docs.rs/solana-epoch-info/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/epoch-info) | | solana-epoch-rewards-hasher | Solana epoch rewards hasher | [View](https://docs.rs/solana-epoch-rewards-hasher/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/epoch-rewards-hasher) | | solana-fee-structure | Solana fee structures | [View](https://docs.rs/solana-fee-structure/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/fee-structure) | | solana-inflation | Configuration for Solana network inflation | [View](https://docs.rs/solana-inflation/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/inflation) | | solana-message | Solana transaction message types | [View](https://docs.rs/solana-message/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/message) | | solana-program | Solana Program | [View](https://docs.rs/solana-program/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/program) | | solana-program-memory | Basic low-level memory operations for Solana | [View](https://docs.rs/solana-program-memory/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/program-memory) | | solana-pubkey | Solana account addresses | [View](https://docs.rs/solana-pubkey/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/pubkey) | | solana-sanitize | Solana Message Sanitization | [View](https://docs.rs/solana-sanitize/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/sanitize) | | solana-sdk-ids | Solana SDK IDs | [View](https://docs.rs/solana-sdk-ids/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/sdk-ids) | | solana-sdk-macro | Solana SDK Macro | [View](https://docs.rs/solana-sdk-macro/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/sdk-macro) | | solana-serde | Solana serde helpers | [View](https://docs.rs/solana-serde/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/serde) | | solana-serde-varint | Solana definitions for integers that serialize to variable size | [View](https://docs.rs/solana-serde-varint/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/serde-varint) | | solana-short-vec | Solana compact serde-encoding of vectors with small length | [View](https://docs.rs/solana-short-vec/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/short-vec) | | solana-time-utils | std::time utilities for Solana | [View](https://docs.rs/solana-time-utils/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/time-utils) | | solana-keypair | Concrete implementation of a Solana Signer | [View](https://docs.rs/solana-keypair/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/keypair) | | solana-offchain-message | Solana offchain message signing | [View](https://docs.rs/solana-offchain-message/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/offchain-message) | | solana-presigner | A Solana Signer implementation representing an externally-constructed Signature | [View](https://docs.rs/solana-presigner/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/presigner) | | solana-seed-derivable | Solana trait defining the interface by which keys are derived | [View](https://docs.rs/solana-seed-derivable/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/seed-derivable) | | solana-seed-phrase | Solana functions for generating keypairs from seed phrases | [View](https://docs.rs/solana-seed-phrase/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/seed-phrase) | | solana-shred-version | Calculation of shred versions | [View](https://docs.rs/solana-shred-version/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/shred-version) | | solana-signature | Solana 64-byte signature type | [View](https://docs.rs/solana-signature/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/signature) | | solana-signer | Abstractions for Solana transaction signers | [View](https://docs.rs/solana-signer/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/signer) | | solana-transaction | Solana transaction-types | [View](https://docs.rs/solana-transaction/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/transaction) | | solana-transaction-error | Solana TransactionError type | [View](https://docs.rs/solana-transaction-error/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/transaction-error) | [Program Crates](https://solana.com/docs/clients/official/rust#program-crates) ------------------------------------------------------------------------------- Use `solana-program` to build on-chain programs. * [Example: Build a Solana program](https://solana.com/docs/programs/rust) | Crate | Description | Docs | GitHub | | --- | --- | --- | --- | | solana-program | Build on-chain programs | [View](https://docs.rs/solana-program) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/program) | Pinocchio is a zero-dependency library to create Solana programs in Rust and can be used as a replacement for `solana-program` to write on-chain programs. | Crate | Description | Docs | GitHub | | --- | --- | --- | --- | | pinocchio | Zero-dependency on-chain programs | [View](https://docs.rs/pinocchio) | [Source](https://github.com/anza-xyz/pinocchio) | Pinocchio is still in development and will likely have breaking changes in the near future. Pinocchio includes program-specific crates for interacting with Solana programs: | Crate | Description | Docs | GitHub | | --- | --- | --- | --- | | pinocchio-system | Interact with System program | [View](https://docs.rs/pinocchio-system/) | [Source](https://github.com/anza-xyz/pinocchio/tree/main/programs/system) | | pinocchio-token | Interact with Token program | [View](https://docs.rs/pinocchio-token/) | [Source](https://github.com/anza-xyz/pinocchio/tree/main/programs/token) | | pinocchio-token-2022 | Interact with Token-2022 program | [View](https://docs.rs/pinocchio-token-2022/) | [Source](https://github.com/anza-xyz/pinocchio/tree/main/programs/token-2022) | | pinocchio-associated-token-account | Interact with Associated Token program | [View](https://docs.rs/pinocchio-associated-token-account/) | [Source](https://github.com/anza-xyz/pinocchio/tree/main/programs/associated-token-account) | | pinocchio-memo | Interact with Memo program | [View](https://docs.rs/pinocchio-memo/) | [Source](https://github.com/anza-xyz/pinocchio/tree/main/programs/memo) | [Interface Crates](https://solana.com/docs/clients/official/rust#interface-crates) ----------------------------------------------------------------------------------- | Crate | Description | Docs | GitHub | | --- | --- | --- | --- | | solana-system-interface | Interact with System program | [View](https://docs.rs/solana-system-interface/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/system-interface) | | spl-token-interface | Interact with Token program | [View](https://docs.rs/spl-token-interface/) | [Source](https://github.com/solana-program/token/tree/main/interface) | | spl-token-2022-interface | Interact with Token-2022 program | [View](https://docs.rs/spl-token-2022-interface/) | [Source](https://github.com/solana-program/token-2022/tree/main/interface) | | spl-associated-token-account-interface | Interact with Associated Token program | [View](https://docs.rs/spl-associated-token-account-interface/) | [Source](https://github.com/solana-program/associated-token-account/tree/main/interface) | | solana-compute-budget-interface | Interact with Compute Budget program | [View](https://docs.rs/solana-compute-budget-interface/) | [Source](https://github.com/anza-xyz/solana-sdk/tree/master/compute-budget-interface) | | spl-memo-interface | Interact with Memo program | [View](https://docs.rs/spl-memo-interface/) | [Source](https://github.com/solana-program/memo/tree/main/interface) | | spl-token-metadata-interface | Interact with Token Metadata extension | [View](https://docs.rs/spl-token-metadata-interface/) | [Source](https://github.com/solana-program/token-metadata/tree/main/interface) | | spl-token-group-interface | Interact with Token Group extension | [View](https://docs.rs/spl-token-group-interface/) | [Source](https://github.com/solana-program/token-group/tree/main/interface) | Is this page helpful? [Previous\ \ Next.js + Solana React Hooks](https://solana.com/docs/frontend/nextjs-solana) [Next\ \ Typescript SDK](https://solana.com/docs/clients/official/javascript) ### Table of Contents [Client Crates](https://solana.com/docs/clients/official/rust#client-crates) [Program Crates](https://solana.com/docs/clients/official/rust#program-crates) [Interface Crates](https://solana.com/docs/clients/official/rust#interface-crates) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/clients/official/rust.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter Rust SDK for Solana | Solana --- # Transactions | Solana [Solana Documentation](https://solana.com/docs) [Core Concepts](https://solana.com/docs/core) [Transactions](https://solana.com/docs/core/transactions) ========================================================== Copy MarkdownOpen To interact with the Solana network, you must send a transaction. You can think of a transaction as an envelope that holds several forms. Each form is an instruction that tells the network what to do. Sending the transaction is like mailing the envelope so the forms can be processed. The example below shows a simplified version of two transactions. When the first transaction is processed, it will execute a single instruction. When the second transaction is processed, it will execute three instructions **in sequential order**: first instruction 1, followed by instruction 2, followed by instruction 3. Transactions are **atomic**: If a single instruction fails, the entire transaction will fail and no changes will occur. ![A simplified diagram showing two transactions](https://solana.com/assets/docs/core/transactions/transaction-simple.svg)A simplified diagram showing two transactions A [`Transaction`](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/src/transaction/mod.rs#L207) consists of the following information: * `signatures`: An array of [signatures](https://solana.com/docs/core/transactions#signatures) * `message`: Transaction information, including the list of instructions to be processed Transaction pub struct Transaction { #\[wasm\_bindgen(skip)\] #\[serde(with \= "short\_vec")\] pub signatures: Vec, #\[wasm\_bindgen(skip)\] pub message: Message, } ![Diagram showing the two parts of a transaction](https://solana.com/assets/docs/core/transactions/tx_format.png)Diagram showing the two parts of a transaction Transactions have a total size limit of [1232](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/packet/src/lib.rs#L29) bytes. This limit includes both the [`signatures`](https://solana.com/docs/core/transactions#signatures) array and the [`message`](https://solana.com/docs/core/transactions#message) struct. This limit is designed to avoid packet fragmentation on typical internet infrastructure. While IPv6 supports MTUs larger than 9000 bytes, most internet routers use a default MTU of 1500 bytes (standard Ethernet). To ensure transactions fit within a single packet without fragmentation, Solana uses 1280 bytes (the minimum MTU required for IPv6) minus 48 bytes for network headers (40 bytes IPv6 + 8 bytes fragment/UDP header), resulting in the 1232 byte transaction size limit. ![Diagram showing the transaction format and size limits](https://solana.com/assets/docs/core/transactions/issues_with_legacy_txs.png)Diagram showing the transaction format and size limits [Signatures](https://solana.com/docs/core/transactions#signatures) ------------------------------------------------------------------- The transaction's `signatures` array contains `Signature` structs. Each [`Signature`](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/signature/src/lib.rs#L30) is 64 bytes and is created by signing the transaction's `Message` with the account's private key. A signature must be provided for each [signer account](https://solana.com/docs/core/transactions#account-addresses) included on any of the transaction's instructions. The first signature belongs to the account that will pay the transaction's [base fee](https://solana.com/docs/core/docs/core/fees#base-fee) and is the transaction signature. The transaction signature can be used to look up the transaction's details on the network. [Message](https://solana.com/docs/core/transactions#message) ------------------------------------------------------------- The transaction's `message` is a [`Message`](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/program/src/message/legacy.rs#L131) struct that contains the following information: * `header`: The message [header](https://solana.com/docs/core/transactions#header) * `account_keys`: An array of [account addresses](https://solana.com/docs/core/transactions#account-addresses) required by the transaction's instructions * `recent_blockhash`: A [blockhash](https://solana.com/docs/core/transactions#recent-blockhash) that acts as a timestamp for the transaction * `instructions`: An array of [instructions](https://solana.com/docs/core/transactions#instructions) To save space, the transaction does not store permissions for each account individually. Instead, account permissions are determined using the `header` and `account_keys`. Message pub struct Message { /// The message header, identifying signed and read-only \`account\_keys\`. pub header: MessageHeader, /// All the account keys used by this transaction. #\[serde(with \= "short\_vec")\] pub account\_keys: Vec, /// The id of a recent ledger entry. pub recent\_blockhash: Hash, /// Programs that will be executed in sequence and committed in /// one atomic transaction if all succeed. #\[serde(with \= "short\_vec")\] pub instructions: Vec, } The message's `header` is a [`MessageHeader`](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/program/src/message/mod.rs#L97) struct. It contains the following information: * `num_required_signatures`: The total number of signatures required by the transaction * `num_readonly_signed_accounts`: The total number of read-only accounts that require signatures * `num_readonly_unsigned_accounts`: The total number of read-only accounts that don't require signatures MessageHeader pub struct MessageHeader { /// The number of signatures required for this message to be considered /// valid. The signers of those signatures must match the first /// \`num\_required\_signatures\` of \[\`Message::account\_keys\`\]. pub num\_required\_signatures: u8, /// The last \`num\_readonly\_signed\_accounts\` of the signed keys are read-only /// accounts. pub num\_readonly\_signed\_accounts: u8, /// The last \`num\_readonly\_unsigned\_accounts\` of the unsigned keys are /// read-only accounts. pub num\_readonly\_unsigned\_accounts: u8, } ![Diagram showing the three parts of the message header](https://solana.com/assets/docs/core/transactions/message_header.png)Diagram showing the three parts of the message header ### [Account addresses](https://solana.com/docs/core/transactions#account-addresses) The message's [`account_keys`](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/program/src/message/legacy.rs#L138) is an array of account addresses, sent in [compact array format](https://solana.com/docs/references/terminology#compact-array-format) . The array's prefix indicates its length. Each item in the array is a public key, pointing to an account used by its instructions. The `accounts_keys` array must be complete, and strictly ordered, as follows: 1. Signer + Writable 2. Signer + Read-only 3. Not signer + Writable 4. Not signer + Read-only Strict ordering allows the `account_keys` array to be combined with the information in the message's [`header`](https://solana.com/docs/core/transactions#header) to determine the permissions for each account. ![Diagram showing the order of the account addresses array](https://solana.com/assets/docs/core/transactions/compat_array_of_account_addresses.png)Diagram showing the order of the account addresses array ### [Recent blockhash](https://solana.com/docs/core/transactions#recent-blockhash) The message's `recent_blockhash` is a hash value that acts as a transaction timestamp and prevents duplicate transactions. A blockhash expires after [150 blocks](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/clock/src/lib.rs#L134) . (Equivalent to one minute—assuming each block is 400ms.) After the block expires, the transaction is expired and cannot be processed. The [`getLatestBlockhash`](https://solana.com/docs/rpc/http/getlatestblockhash) RPC method allows you to get the current blockhash and last block height at which the blockhash will be valid. ### [Instructions](https://solana.com/docs/core/transactions#instructions) The message's [`instructions`](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/program/src/message/legacy.rs#L146) is an array of all the instructions to be processed, sent in [compact array format](https://solana.com/docs/references/terminology#compact-array-format) . The array's prefix indicates its length. Each item in the array is a [`CompiledInstruction`](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/program/src/instruction.rs#L22) struct and includes the following information: 1. `program_id_index`: An index pointing to an address in the [`account_keys`](https://solana.com/docs/core/transactions#account-addresses) array. This value indicates the address of the program that processes the instruction. 2. `accounts`: An array of indices pointing to addresses in the `account_keys` array. Each index points to the address of an account required for this instruction. 3. `data`: A byte array specifying which instruction to invoke on the program. It also includes any additional data required by the instruction. (For example, function arguments) CompiledInstruction pub struct CompiledInstruction { /// Index into the transaction keys array indicating the program account that executes this instruction. pub program\_id\_index: u8, /// Ordered indices into the transaction keys array indicating which accounts to pass to the program. #\[serde(with \= "short\_vec")\] pub accounts: Vec, /// The program input data. #\[serde(with \= "short\_vec")\] pub data: Vec, } ![Compact array of Instructions](https://solana.com/assets/docs/core/transactions/compact_array_of_ixs.png)Compact array of Instructions [Example transaction structure](https://solana.com/docs/core/transactions#example-transaction-structure) --------------------------------------------------------------------------------------------------------- The following example shows the structure of a transaction that contains a single SOL transfer instruction. Kit Legacy Rust import { createSolanaRpc, generateKeyPairSigner, lamports, createTransactionMessage, setTransactionMessageFeePayerSigner, setTransactionMessageLifetimeUsingBlockhash, appendTransactionMessageInstructions, pipe, signTransactionMessageWithSigners, getCompiledTransactionMessageDecoder } from "@solana/kit"; import { getTransferSolInstruction } from "@solana-program/system"; const rpc \= createSolanaRpc("http://localhost:8899"); const { value: latestBlockhash } \= await rpc.getLatestBlockhash().send(); // Generate sender and recipient keypairs const sender \= await generateKeyPairSigner(); const recipient \= await generateKeyPairSigner(); // Define the amount to transfer const LAMPORTS\_PER\_SOL \= 1\_000\_000\_000n; const transferAmount \= lamports(LAMPORTS\_PER\_SOL / 100n); // 0.01 SOL // Create a transfer instruction for transferring SOL from sender to recipient const transferInstruction \= getTransferSolInstruction({ source: sender, destination: recipient.address, amount: transferAmount }); // Create transaction message const transactionMessage \= pipe( createTransactionMessage({ version: 0 }), (tx) \=> setTransactionMessageFeePayerSigner(sender, tx), (tx) \=> setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx), (tx) \=> appendTransactionMessageInstructions(\[transferInstruction\], tx) ); const signedTransaction \= await signTransactionMessageWithSigners(transactionMessage); // Decode the messageBytes const compiledTransactionMessage \= getCompiledTransactionMessageDecoder().decode(signedTransaction.messageBytes); console.log(JSON.stringify(compiledTransactionMessage, null, 2)); Console RunClick to execute the code. Kit Legacy Rust import { createSolanaRpc, generateKeyPairSigner, lamports, createTransactionMessage, setTransactionMessageFeePayerSigner, setTransactionMessageLifetimeUsingBlockhash, appendTransactionMessageInstructions, pipe, signTransactionMessageWithSigners, getCompiledTransactionMessageDecoder } from "@solana/kit"; import { getTransferSolInstruction } from "@solana-program/system"; const rpc \= createSolanaRpc("http://localhost:8899"); const { value: latestBlockhash } \= await rpc.getLatestBlockhash().send(); // Generate sender and recipient keypairs const sender \= await generateKeyPairSigner(); const recipient \= await generateKeyPairSigner(); // Define the amount to transfer const LAMPORTS\_PER\_SOL \= 1\_000\_000\_000n; const transferAmount \= lamports(LAMPORTS\_PER\_SOL / 100n); // 0.01 SOL // Create a transfer instruction for transferring SOL from sender to recipient const transferInstruction \= getTransferSolInstruction({ source: sender, destination: recipient.address, amount: transferAmount }); // Create transaction message const transactionMessage \= pipe( createTransactionMessage({ version: 0 }), (tx) \=> setTransactionMessageFeePayerSigner(sender, tx), (tx) \=> setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx), (tx) \=> appendTransactionMessageInstructions(\[transferInstruction\], tx) ); const signedTransaction \= await signTransactionMessageWithSigners(transactionMessage); // Decode the messageBytes const compiledTransactionMessage \= getCompiledTransactionMessageDecoder().decode(signedTransaction.messageBytes); console.log(JSON.stringify(compiledTransactionMessage, null, 2)); Console RunClick to execute the code. The code below shows the output from the previous code snippets. The format differs between SDKs, but notice that each instruction contains the same required information. Kit Legacy Rust { "version": 0, "header": { "numSignerAccounts": 1, "numReadonlySignerAccounts": 0, "numReadonlyNonSignerAccounts": 1 }, "staticAccounts": \[\ \ "HoCy8p5xxDDYTYWEbQZasEjVNM5rxvidx8AfyqA4ywBa",\ \ "5T388jBjovy7d8mQ3emHxMDTbUF8b7nWvAnSiP3EAdFL",\ \ "11111111111111111111111111111111"\ \ \], "lifetimeToken": "EGCWPUEXhqHJWYBfDirq3mHZb4qDpATmYqBZMBy9TBC1", "instructions": \[\ \ {\ \ "programAddressIndex": 2,\ \ "accountIndices": \[0, 1\],\ \ "data": {\ \ "0": 2,\ \ "1": 0,\ \ "2": 0,\ \ "3": 0,\ \ "4": 128,\ \ "5": 150,\ \ "6": 152,\ \ "7": 0,\ \ "8": 0,\ \ "9": 0,\ \ "10": 0,\ \ "11": 0\ \ }\ \ }\ \ \] } After a transaction is submitted, you can retrieve its details using the transaction signature and the [getTransaction](https://solana.com/docs/rpc/http/gettransaction) RPC method. The response will have a structure similar to the following snippet. You can also find the transaction using [Solana Explorer](https://explorer.solana.com/) . Transaction Data { "blockTime": 1745196488, "meta": { "computeUnitsConsumed": 150, "err": null, "fee": 5000, "innerInstructions": \[\], "loadedAddresses": { "readonly": \[\], "writable": \[\] }, "logMessages": \[\ \ "Program 11111111111111111111111111111111 invoke \[1\]",\ \ "Program 11111111111111111111111111111111 success"\ \ \], "postBalances": \[989995000, 10000000, 1\], "postTokenBalances": \[\], "preBalances": \[1000000000, 0, 1\], "preTokenBalances": \[\], "rewards": \[\], "status": { "Ok": null } }, "slot": 13049, "transaction": { "message": { "header": { "numReadonlySignedAccounts": 0, "numReadonlyUnsignedAccounts": 1, "numRequiredSignatures": 1 }, "accountKeys": \[\ \ "8PLdpLxkuv9Nt8w3XcGXvNa663LXDjSrSNon4EK7QSjQ",\ \ "7GLg7bqgLBv1HVWXKgWAm6YoPf1LoWnyWGABbgk487Ma",\ \ "11111111111111111111111111111111"\ \ \], "recentBlockhash": "7ZCxc2SDhzV2bYgEQqdxTpweYJkpwshVSDtXuY7uPtjf", "instructions": \[\ \ {\ \ "accounts": \[0, 1\],\ \ "data": "3Bxs4NN8M2Yn4TLb",\ \ "programIdIndex": 2,\ \ "stackHeight": null\ \ }\ \ \], "indexToProgramIds": {} }, "signatures": \[\ \ "3jUKrQp1UGq5ih6FTDUUt2kkqUfoG2o4kY5T1DoVHK2tXXDLdxJSXzuJGY4JPoRivgbi45U2bc7LZfMa6C4R3szX"\ \ \] }, "version": "legacy" } Is this page helpful? [Previous\ \ Instructions](https://solana.com/docs/core/instructions) [Next\ \ Transaction Fees](https://solana.com/docs/core/fees) ### Table of Contents [Signatures](https://solana.com/docs/core/transactions#signatures) [Message](https://solana.com/docs/core/transactions#message) [Header](https://solana.com/docs/core/transactions#header) [Account addresses](https://solana.com/docs/core/transactions#account-addresses) [Recent blockhash](https://solana.com/docs/core/transactions#recent-blockhash) [Instructions](https://solana.com/docs/core/transactions#instructions) [Example transaction structure](https://solana.com/docs/core/transactions#example-transaction-structure) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/core/transactions.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter Transactions | Solana --- # Accounts | Solana [Solana Documentation](https://solana.com/docs) [Core Concepts](https://solana.com/docs/core) [Accounts](https://solana.com/docs/core/accounts) ================================================== Copy MarkdownOpen All data on the Solana network is stored in accounts. You can think of the Solana network as a public database with a single Accounts table. The relationship between an account and its address is similar to that of a key-value pair, with the key being the address and the value being the account. Each account has the same basic [structure](https://solana.com/docs/core/accounts#account-structure) and can be located using its [address](https://solana.com/docs/core/accounts#account-address) . ![Diagram of 3 accounts and their addresses. Includes the account structure definition.](https://solana.com/assets/docs/core/accounts/accounts.png)Diagram of 3 accounts and their addresses. Includes the account structure definition. [Account address](https://solana.com/docs/core/accounts#account-address) ------------------------------------------------------------------------- The account's address is a 32-byte unique ID used to locate the account on the Solana blockchain. Account addresses are often shown as base58 encoded strings. Most accounts use an [Ed25519](https://ed25519.cr.yp.to/) [public key](https://solana.com/docs/core/accounts#public-key) as their address, but this is not required, as Solana also supports [program derived addresses](https://solana.com/docs/core/accounts#program-derived-address) . ![An account with its base58 encoded public key address](https://solana.com/assets/docs/core/accounts/account-address.svg)An account with its base58 encoded public key address ### [Public key](https://solana.com/docs/core/accounts#public-key) The example below demonstrates how to use the Solana SDK to create a keypair. A `Keypair` includes: * A public key which serves as the account address * A private key which is used to sign transactions Kit Legacy Rust import { generateKeyPairSigner } from "@solana/kit"; // Kit does not enable extractable private keys const keypairSigner \= await generateKeyPairSigner(); console.log(keypairSigner); Console RunClick to execute the code. Kit Legacy Rust import { generateKeyPairSigner } from "@solana/kit"; // Kit does not enable extractable private keys const keypairSigner \= await generateKeyPairSigner(); console.log(keypairSigner); Console RunClick to execute the code. ### [Program derived address](https://solana.com/docs/core/accounts#program-derived-address) A [program derived address](https://solana.com/docs/core/pda) (PDA) is an address that is deterministically derived using a program ID and one or more optional inputs (seeds). The example below demonstrates how to use the Solana SDK to create a program derived address. Kit Legacy Rust import { Address, getProgramDerivedAddress } from "@solana/kit"; const programAddress \= "11111111111111111111111111111111" as Address; const seeds \= \["helloWorld"\]; const \[pda, bump\] \= await getProgramDerivedAddress({ programAddress, seeds }); console.log(\`PDA: ${pda}\`); console.log(\`Bump: ${bump}\`); Console RunClick to execute the code. Kit Legacy Rust import { Address, getProgramDerivedAddress } from "@solana/kit"; const programAddress \= "11111111111111111111111111111111" as Address; const seeds \= \["helloWorld"\]; const \[pda, bump\] \= await getProgramDerivedAddress({ programAddress, seeds }); console.log(\`PDA: ${pda}\`); console.log(\`Bump: ${bump}\`); Console RunClick to execute the code. [Account structure](https://solana.com/docs/core/accounts#account-structure) ----------------------------------------------------------------------------- Every [`Account`](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/account/src/lib.rs#L48-L60) has a maximum size of [10MiB](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/program/src/system_instruction.rs#L85) and contains following information: * `lamports`: The number of lamports in the account * `data`: The account's data * `owner`: The ID of the program that owns the account * `executable`: Indicates whether the account contains executable binary * `rent_epoch`: The deprecated rent epoch field Account pub struct Account { /// lamports in the account pub lamports: u64, /// data held in this account #\[cfg\_attr(feature \= "serde", serde(with \= "serde\_bytes"))\] pub data: Vec, /// the program that owns this account. If executable, the program that loads this account. pub owner: Pubkey, /// this account's data contains a loaded program (and is now read-only) pub executable: bool, /// the epoch at which this account will next owe rent pub rent\_epoch: Epoch, } Lamports -------- The account's balance in [lamports](https://solana.com/docs/references/terminology#lamport) . Every account must have a minimum lamport balance, called [rent](https://solana.com/docs/references/terminology#rent) , which allows its data to be stored on-chain. Rent is proportional to the size of the account. Although this balance is called rent, it works more like a deposit, as the full balance can be recovered when the account is closed. (The name "rent" comes from the now deprecated rent epoch field.) (See the [minimum balance](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/rent/src/lib.rs#L93-L97) formula and the applicable [constants](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/rent/src/lib.rs#L47-L70) .) Data ---- This field is commonly referred to as "account data". The `data` in this field is considered arbitrary as it can contain any sequence of bytes. Each program defines the structure of the data stored in this field. * Program accounts: This field contains either executable program code or the address of a [program data account](https://solana.com/docs/core/accounts#program-data-accounts) which stores the executable program code. * Data accounts: This field generally stores state data, meant to be read. Reading data from a Solana account involves two steps: 1. Fetching the account using its [address](https://solana.com/docs/core/accounts#account-address) 2. Deserializing the account's `data` field from raw bytes into the appropriate data structure, as defined by the program that owns the account. Owner ----- This field contains the program ID of the account's owner. Every Solana account has a [program](https://solana.com/docs/core/programs) designated as its owner. The account's owner is the only program that can change the account's `data` or deduct lamports, as indicated by the program's instructions. (In the case of a program account, the owner is its [loader program](https://solana.com/docs/core/programs#loader-programs) .) Executable ---------- This field indicates whether an account is a [program account](https://solana.com/docs/core/accounts#program-accounts) or a [data account](https://solana.com/docs/core/accounts#data-accounts) * If `true`: The account is a program account * If `false`: The account is a data account Rent epoch ---------- **The `rent_epoch` field is deprecated.** In the past, this field tracked when an account would need to pay rent. However, this rent collection mechanism has since been deprecated. Lamports -------- The account's balance in [lamports](https://solana.com/docs/references/terminology#lamport) . Every account must have a minimum lamport balance, called [rent](https://solana.com/docs/references/terminology#rent) , which allows its data to be stored on-chain. Rent is proportional to the size of the account. Although this balance is called rent, it works more like a deposit, as the full balance can be recovered when the account is closed. (The name "rent" comes from the now deprecated rent epoch field.) (See the [minimum balance](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/rent/src/lib.rs#L93-L97) formula and the applicable [constants](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/rent/src/lib.rs#L47-L70) .) Data ---- This field is commonly referred to as "account data". The `data` in this field is considered arbitrary as it can contain any sequence of bytes. Each program defines the structure of the data stored in this field. * Program accounts: This field contains either executable program code or the address of a [program data account](https://solana.com/docs/core/accounts#program-data-accounts) which stores the executable program code. * Data accounts: This field generally stores state data, meant to be read. Reading data from a Solana account involves two steps: 1. Fetching the account using its [address](https://solana.com/docs/core/accounts#account-address) 2. Deserializing the account's `data` field from raw bytes into the appropriate data structure, as defined by the program that owns the account. Owner ----- This field contains the program ID of the account's owner. Every Solana account has a [program](https://solana.com/docs/core/programs) designated as its owner. The account's owner is the only program that can change the account's `data` or deduct lamports, as indicated by the program's instructions. (In the case of a program account, the owner is its [loader program](https://solana.com/docs/core/programs#loader-programs) .) Executable ---------- This field indicates whether an account is a [program account](https://solana.com/docs/core/accounts#program-accounts) or a [data account](https://solana.com/docs/core/accounts#data-accounts) * If `true`: The account is a program account * If `false`: The account is a data account Rent epoch ---------- **The `rent_epoch` field is deprecated.** In the past, this field tracked when an account would need to pay rent. However, this rent collection mechanism has since been deprecated. Account Examples // Example Token Mint Account Account { lamports: 1461600, data.len: 82, owner: TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb, executable: false, rent\_epoch: 0, data: 010000001e213c90625a7e643d9555bb01b6c3fe6416d7afd523ce8c7ddd9b923ceafb9d00000000000000000901010000001e213c90625a7e643d9555bb01b6, } // Example Token Program Account Account { lamports: 4513200894, data.len: 134080, owner: BPFLoader2111111111111111111111111111111111, executable: true, rent\_epoch: 18446744073709551615, data: 7f454c460201010000000000000000000300f70001000000d8f90000000000004000000000000000800902000000000000000000400038000400400009000800, } [Types of accounts](https://solana.com/docs/core/accounts#types-of-accounts) ----------------------------------------------------------------------------- There are two basic categories that accounts fall into: * [Program accounts](https://solana.com/docs/core/accounts#program-accounts) : Accounts that contain executable code * [Data accounts](https://solana.com/docs/core/accounts#data-accounts) : Accounts that do not contain executable code This separation of a program's code and its state is a key feature of Solana's account model. (Similar to operating systems, which typically have separate files for programs and their data.) ### [Program accounts](https://solana.com/docs/core/accounts#program-accounts) Every program is owned by a [loader program](https://solana.com/docs/core/programs#loader-programs) , which is used to deploy and manage the account. When a new [program](https://solana.com/docs/core/programs) is deployed, an account is created to store its [executable](https://solana.com/docs/core/accounts#executable) code. This is called a program account. (For simplicity, you can consider the program account to be the program itself.) In the diagram below, you can see a loader program is used to deploy a program account. The program account's `data` contains the executable program code. ![Diagram of a program account, its 4 component and its loader program.](https://solana.com/assets/docs/core/accounts/program-account-simple.svg)Diagram of a program account, its 4 component and its loader program. #### [Program data accounts](https://solana.com/docs/core/accounts#program-data-accounts) Programs deployed using loader-v3 do not contain program code in their `data` field. Instead, their `data` points to a separate **program data account**, which contains the program code. (See the diagram below.) ![A program account with data. The data points to a separate program data account](https://solana.com/assets/docs/core/accounts/program-account-expanded.svg)A program account with data. The data points to a separate program data account During program deployment or upgrades, buffer accounts are used to temporarily stage the upload. The example below fetches the Token Program account. Notice that the `executable` field is set to `true`, indicating the account is a program. Kit Legacy Rust import { Address, createSolanaRpc } from "@solana/kit"; const rpc \= createSolanaRpc("https://api.mainnet.solana.com"); const programId \= "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" as Address; const accountInfo \= await rpc .getAccountInfo(programId, { encoding: "base64" }) .send(); console.log(accountInfo); Console RunClick to execute the code. Kit Legacy Rust import { Address, createSolanaRpc } from "@solana/kit"; const rpc \= createSolanaRpc("https://api.mainnet.solana.com"); const programId \= "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" as Address; const accountInfo \= await rpc .getAccountInfo(programId, { encoding: "base64" }) .send(); console.log(accountInfo); Console RunClick to execute the code. ### [Data accounts](https://solana.com/docs/core/accounts#data-accounts) Data accounts do not contain executable code. Instead, they store information. #### [Program state account](https://solana.com/docs/core/accounts#program-state-account) Programs use data accounts to maintain their state. To do so, they must first create a new data account. The process of creating a program state account is often abstracted, but it is helpful to understand the underlying process. To manage its state, a new program must: 1. Invoke the [System Program](https://solana.com/docs/core/programs#the-system-program) to create an account. (The System Program then transfers ownership to the new program.) 2. Initialize the account data, as defined by its [instructions](https://solana.com/docs/core/instructions) . ![Diagram of a data account owned by a program account](https://solana.com/assets/docs/core/accounts/data-account.svg)Diagram of a data account owned by a program account The example below creates and fetches a Token Mint account owned by the Token 2022 program. Kit Legacy Rust import { airdropFactory, appendTransactionMessageInstructions, createSolanaRpc, createSolanaRpcSubscriptions, createTransactionMessage, generateKeyPairSigner, getSignatureFromTransaction, lamports, pipe, sendAndConfirmTransactionFactory, setTransactionMessageFeePayerSigner, setTransactionMessageLifetimeUsingBlockhash, signTransactionMessageWithSigners } from "@solana/kit"; import { getCreateAccountInstruction } from "@solana-program/system"; import { getInitializeMintInstruction, getMintSize, TOKEN\_2022\_PROGRAM\_ADDRESS, fetchMint } from "@solana-program/token-2022"; // Create Connection, local validator in this example const rpc \= createSolanaRpc("http://localhost:8899"); const rpcSubscriptions \= createSolanaRpcSubscriptions("ws://localhost:8900"); // Generate keypairs for fee payer const feePayer \= await generateKeyPairSigner(); // Fund fee payer await airdropFactory({ rpc, rpcSubscriptions })({ recipientAddress: feePayer.address, lamports: lamports(1\_000\_000\_000n), commitment: "confirmed" }); // Generate keypair to use as address of mint const mint \= await generateKeyPairSigner(); // Get default mint account size (in bytes), no extensions enabled const space \= BigInt(getMintSize()); // Get minimum balance for rent exemption const rent \= await rpc.getMinimumBalanceForRentExemption(space).send(); // Instruction to create new account for mint (token 2022 program) // Invokes the system program const createAccountInstruction \= getCreateAccountInstruction({ payer: feePayer, newAccount: mint, lamports: rent, space, programAddress: TOKEN\_2022\_PROGRAM\_ADDRESS }); // Instruction to initialize mint account data // Invokes the token 2022 program const initializeMintInstruction \= getInitializeMintInstruction({ mint: mint.address, decimals: 9, mintAuthority: feePayer.address }); const instructions \= \[createAccountInstruction, initializeMintInstruction\]; // Get latest blockhash to include in transaction const { value: latestBlockhash } \= await rpc.getLatestBlockhash().send(); // Create transaction message const transactionMessage \= pipe( createTransactionMessage({ version: 0 }), // Create transaction message (tx) \=> setTransactionMessageFeePayerSigner(feePayer, tx), // Set fee payer (tx) \=> setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx), // Set transaction blockhash (tx) \=> appendTransactionMessageInstructions(instructions, tx) // Append instructions ); // Sign transaction message with required signers (fee payer and mint keypair) const signedTransaction \= await signTransactionMessageWithSigners(transactionMessage); // Send and confirm transaction await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })( signedTransaction, { commitment: "confirmed" } ); // Get transaction signature const transactionSignature \= getSignatureFromTransaction(signedTransaction); console.log("Mint Address:", mint.address); console.log("Transaction Signature:", transactionSignature); const accountInfo \= await rpc.getAccountInfo(mint.address).send(); console.log(accountInfo); const mintAccount \= await fetchMint(rpc, mint.address); console.log(mintAccount); Console RunClick to execute the code. Kit Legacy Rust import { airdropFactory, appendTransactionMessageInstructions, createSolanaRpc, createSolanaRpcSubscriptions, createTransactionMessage, generateKeyPairSigner, getSignatureFromTransaction, lamports, pipe, sendAndConfirmTransactionFactory, setTransactionMessageFeePayerSigner, setTransactionMessageLifetimeUsingBlockhash, signTransactionMessageWithSigners } from "@solana/kit"; import { getCreateAccountInstruction } from "@solana-program/system"; import { getInitializeMintInstruction, getMintSize, TOKEN\_2022\_PROGRAM\_ADDRESS, fetchMint } from "@solana-program/token-2022"; // Create Connection, local validator in this example const rpc \= createSolanaRpc("http://localhost:8899"); const rpcSubscriptions \= createSolanaRpcSubscriptions("ws://localhost:8900"); // Generate keypairs for fee payer const feePayer \= await generateKeyPairSigner(); // Fund fee payer await airdropFactory({ rpc, rpcSubscriptions })({ recipientAddress: feePayer.address, lamports: lamports(1\_000\_000\_000n), commitment: "confirmed" }); // Generate keypair to use as address of mint const mint \= await generateKeyPairSigner(); // Get default mint account size (in bytes), no extensions enabled const space \= BigInt(getMintSize()); // Get minimum balance for rent exemption const rent \= await rpc.getMinimumBalanceForRentExemption(space).send(); // Instruction to create new account for mint (token 2022 program) // Invokes the system program const createAccountInstruction \= getCreateAccountInstruction({ payer: feePayer, newAccount: mint, lamports: rent, space, programAddress: TOKEN\_2022\_PROGRAM\_ADDRESS }); // Instruction to initialize mint account data // Invokes the token 2022 program const initializeMintInstruction \= getInitializeMintInstruction({ mint: mint.address, decimals: 9, mintAuthority: feePayer.address }); const instructions \= \[createAccountInstruction, initializeMintInstruction\]; // Get latest blockhash to include in transaction const { value: latestBlockhash } \= await rpc.getLatestBlockhash().send(); // Create transaction message const transactionMessage \= pipe( createTransactionMessage({ version: 0 }), // Create transaction message (tx) \=> setTransactionMessageFeePayerSigner(feePayer, tx), // Set fee payer (tx) \=> setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx), // Set transaction blockhash (tx) \=> appendTransactionMessageInstructions(instructions, tx) // Append instructions ); // Sign transaction message with required signers (fee payer and mint keypair) const signedTransaction \= await signTransactionMessageWithSigners(transactionMessage); // Send and confirm transaction await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })( signedTransaction, { commitment: "confirmed" } ); // Get transaction signature const transactionSignature \= getSignatureFromTransaction(signedTransaction); console.log("Mint Address:", mint.address); console.log("Transaction Signature:", transactionSignature); const accountInfo \= await rpc.getAccountInfo(mint.address).send(); console.log(accountInfo); const mintAccount \= await fetchMint(rpc, mint.address); console.log(mintAccount); Console RunClick to execute the code. #### [System accounts](https://solana.com/docs/core/accounts#system-accounts) Not all accounts are assigned a new owner after being created by the System Program. Accounts owned by the System Program are called system accounts. All wallet accounts are system accounts, which allows them to pay [transaction fees](https://solana.com/docs/core/docs/core/fees) . ![A wallet owned by the System Program containing 1,000,000 lamports](https://solana.com/assets/docs/core/accounts/system-account.svg)A wallet owned by the System Program containing 1,000,000 lamports When SOL is sent to a new address for the first time, an account is created at that address owned by the System Program. In the example below, a new keypair is generated and funded with SOL. After running the code, you can see the address of the account's `owner` is `11111111111111111111111111111111` (the [System Program](https://solana.com/docs/core/programs#the-system-program) ). Kit Legacy Rust import { airdropFactory, createSolanaRpc, createSolanaRpcSubscriptions, generateKeyPairSigner, lamports } from "@solana/kit"; // Create a connection to Solana cluster const rpc \= createSolanaRpc("http://localhost:8899"); const rpcSubscriptions \= createSolanaRpcSubscriptions("ws://localhost:8900"); // Generate a new keypair const keypair \= await generateKeyPairSigner(); console.log(\`Public Key: ${keypair.address}\`); // Funding an address with SOL automatically creates an account const signature \= await airdropFactory({ rpc, rpcSubscriptions })({ recipientAddress: keypair.address, lamports: lamports(1\_000\_000\_000n), commitment: "confirmed" }); const accountInfo \= await rpc.getAccountInfo(keypair.address).send(); console.log(accountInfo); Console RunClick to execute the code. Kit Legacy Rust import { airdropFactory, createSolanaRpc, createSolanaRpcSubscriptions, generateKeyPairSigner, lamports } from "@solana/kit"; // Create a connection to Solana cluster const rpc \= createSolanaRpc("http://localhost:8899"); const rpcSubscriptions \= createSolanaRpcSubscriptions("ws://localhost:8900"); // Generate a new keypair const keypair \= await generateKeyPairSigner(); console.log(\`Public Key: ${keypair.address}\`); // Funding an address with SOL automatically creates an account const signature \= await airdropFactory({ rpc, rpcSubscriptions })({ recipientAddress: keypair.address, lamports: lamports(1\_000\_000\_000n), commitment: "confirmed" }); const accountInfo \= await rpc.getAccountInfo(keypair.address).send(); console.log(accountInfo); Console RunClick to execute the code. #### [Sysvar accounts](https://solana.com/docs/core/accounts#sysvar-accounts) Sysvar accounts exist at predefined addresses and provide access to cluster state data. They update dynamically with data about the network cluster. See the full list of [Sysvar Accounts](https://docs.anza.xyz/runtime/sysvars) . The example below fetches and deserializes data from the Sysvar Clock account. Kit Legacy Rust import { createSolanaRpc } from "@solana/kit"; import { fetchSysvarClock, SYSVAR\_CLOCK\_ADDRESS } from "@solana/sysvars"; const rpc \= createSolanaRpc("https://api.mainnet.solana.com"); const accountInfo \= await rpc .getAccountInfo(SYSVAR\_CLOCK\_ADDRESS, { encoding: "base64" }) .send(); console.log(accountInfo); // Automatically fetch and deserialize the account data const clock \= await fetchSysvarClock(rpc); console.log(clock); Console RunClick to execute the code. Kit Legacy Rust import { createSolanaRpc } from "@solana/kit"; import { fetchSysvarClock, SYSVAR\_CLOCK\_ADDRESS } from "@solana/sysvars"; const rpc \= createSolanaRpc("https://api.mainnet.solana.com"); const accountInfo \= await rpc .getAccountInfo(SYSVAR\_CLOCK\_ADDRESS, { encoding: "base64" }) .send(); console.log(accountInfo); // Automatically fetch and deserialize the account data const clock \= await fetchSysvarClock(rpc); console.log(clock); Console RunClick to execute the code. Is this page helpful? [Previous\ \ Core Concepts](https://solana.com/docs/core) [Next\ \ Instructions](https://solana.com/docs/core/instructions) ### Table of Contents [Account address](https://solana.com/docs/core/accounts#account-address) [Public key](https://solana.com/docs/core/accounts#public-key) [Program derived address](https://solana.com/docs/core/accounts#program-derived-address) [Account structure](https://solana.com/docs/core/accounts#account-structure) [Types of accounts](https://solana.com/docs/core/accounts#types-of-accounts) [Program accounts](https://solana.com/docs/core/accounts#program-accounts) [Program data accounts](https://solana.com/docs/core/accounts#program-data-accounts) [Data accounts](https://solana.com/docs/core/accounts#data-accounts) [Program state account](https://solana.com/docs/core/accounts#program-state-account) [System accounts](https://solana.com/docs/core/accounts#system-accounts) [Sysvar accounts](https://solana.com/docs/core/accounts#sysvar-accounts) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/core/accounts.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter Accounts | Solana --- # Frontend | Solana This website uses cookies to offer you a better browsing experience. Find out more on how we use cookies. Opt-out[Details](https://solana.com/privacy-policy#collection-of-information) Accept [Solana Documentation](https://solana.com/docs) [Frontend](https://solana.com/docs/frontend) ============================================= Copy MarkdownOpen Frontend development on Solana involves working with Programs, wallets and popular JavaScript frameworks like React. Interacting with these components requires handling connection, transaction creation and reading from Solana Accounts. To help with this work, a variety Solana Client libraries are available in different frameworks. [Main libraries](https://solana.com/docs/frontend#main-libraries) ------------------------------------------------------------------ [### @solana/client\ \ * Simple Solana client bundling RPC, wallets, transactions\ * Includes built-in state store, actions, watchers, connectors](https://github.com/solana-foundation/framework-kit/tree/main/packages/client) [### @solana/react-hooks\ \ * Complete hooks for wallets, balances, transfers, signatures, queries\ * React provider hooks wrapping `@solana/client` runtime state](https://github.com/solana-foundation/framework-kit/tree/main/packages/react-hooks) [### @solana/web3-compat\ \ * Web3.js compatible toolkit to simplify upgrading.\ * Newer internals relying on a mix of web3.js and kit.](https://github.com/solana-foundation/framework-kit/tree/main/packages/web3-compat) [### @solana/kit\ \ * Low level Solana SDK powering the other Solana libraries like `@solana/react-hooks`\ * Fully tree-shakable, uses modern web standards, and powers the runtime](https://github.com/solana-foundation/framework-kit/tree/main/packages/kit) @solana/web3.js is deprecated\` Many Solana ecosystem projects still rely on the deprecated `@solana/web3.js`. Prefer `@solana/web3-compat` to simplify your migration path. * [@solana/client guide](https://solana.com/docs/frontend/client) : lean, headless runtime for RPC, wallets, and transactions. * [@solana/react-hooks guide](https://solana.com/docs/frontend/react-hooks) : React hooks layered on the same client runtime. * [@solana/web3-compat guide](https://solana.com/docs/frontend/web3-compat) : compatibility layer to migrate from `@solana/web3.js` to Kit powered stacks. Is this page helpful? [Previous\ \ Limitations](https://solana.com/docs/programs/limitations) [Next\ \ @solana/client](https://solana.com/docs/frontend/client) ### Table of Contents [Main libraries](https://solana.com/docs/frontend#main-libraries) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/frontend/index.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter Frontend | Solana --- # Install the Solana CLI and Anchor with one command | Solana This website uses cookies to offer you a better browsing experience. Find out more on how we use cookies. Opt-out[Details](https://solana.com/privacy-policy#collection-of-information) Accept [Solana Documentation](https://solana.com/docs) Getting Started [Quick Installation](https://solana.com/docs/intro/installation) ================================================================= Copy MarkdownOpen A quick installation to set up your local Solana development environment with one command. Install Rust, the Solana CLI, and Anchor Framework on Windows (WSL), Linux, and Mac. (If preferred, you may [install each dependency individually](https://solana.com/docs/intro/installation/dependencies) .) [Prerequisites](https://solana.com/docs/intro/installation#prerequisites) -------------------------------------------------------------------------- ### Windows ### Linux [Installation](https://solana.com/docs/intro/installation#installation) ------------------------------------------------------------------------ 1. Enter the following command into your terminal to install all the necessary dependencies: Terminal $ curl --proto '=https' --tlsv1.2 -sSfL https://solana-install.solana.workers.dev | bash Copy A successful installation will return output like the following: Example output Installed Versions: Rust: rustc 1.91.1 (ed61e7d7e 2025-11-07) Solana CLI: solana-cli 3.0.10 (src:96c3a851; feat:3604001754, client:Agave) Anchor CLI: anchor-cli 0.32.1 Surfpool CLI: surfpool 0.12.0 Node.js: v24.10.0 Yarn: 1.22.1 2. Verify a successful installation by checking the version of each installed dependency. Terminal $ rustc --version && solana --version && anchor --version && surfpool --version && node --version && yarn --version Copy If the quick installation command fails, please refer to the [Install Dependencies](https://solana.com/docs/intro/installation/dependencies) section below for instructions to install each dependency individually. Is this page helpful? [Next\ \ Install Dependencies](https://solana.com/docs/intro/installation/dependencies) ### Table of Contents [Prerequisites](https://solana.com/docs/intro/installation#prerequisites) [Installation](https://solana.com/docs/intro/installation#installation) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/intro/installation/index.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter Install the Solana CLI and Anchor with one command | Solana --- # Programs | Solana [Solana Documentation](https://solana.com/docs) [Core Concepts](https://solana.com/docs/core) [Programs](https://solana.com/docs/core/programs) ================================================== Copy MarkdownOpen On Solana, a smart contract is called a program. A program is a stateless [account](https://solana.com/docs/core/accounts#program-account) that contains executable code. This code is organized into functions called instructions. Users interact with a program by sending a [transaction](https://solana.com/docs/core/transactions) containing one or more [instructions](https://solana.com/docs/core/instructions) . A transaction can include instructions from multiple programs. When a program is deployed, Solana uses [LLVM](https://llvm.org/) to compile it into executable and linkable format ([ELF](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format) ). The ELF file contains the program's binary in Solana Bytecode Format (sBPF) and is saved on-chain in an executable account. sBPF is Solana's custom version of [eBPF](https://en.wikipedia.org/wiki/EBPF) bytecode. [Write programs](https://solana.com/docs/core/programs#write-programs) ----------------------------------------------------------------------- The majority of programs are written in [Rust](https://rust-book.cs.brown.edu/title-page.html) , with two common development approaches: * [Anchor](https://www.anchor-lang.com/docs) : Anchor is a framework designed for fast and easy Solana development. It uses [Rust macros](https://doc.rust-lang.org/book/ch20-05-macros.html) to reduce boilerplate code—making it great for beginners. * [Native Rust](https://solana.com/docs/programs/rust) : Write programs in Rust without leveraging any frameworks. This approach offers more flexibility but comes with increased complexity. [Update programs](https://solana.com/docs/core/programs#update-programs) ------------------------------------------------------------------------- To [modify](https://github.com/anza-xyz/agave/blob/v2.1.13/programs/bpf_loader/src/lib.rs#L704) an existing program, an account must be designated as the [upgrade authority](https://github.com/anza-xyz/agave/blob/v2.1.13/programs/bpf_loader/src/lib.rs#L894) . (Typically the same account that originally [deployed the program](https://solana.com/docs/programs/deploying) .) If the upgrade authority is revoked and set to `None`, the program can no longer be updated. [Verify programs](https://solana.com/docs/core/programs#verify-programs) ------------------------------------------------------------------------- Solana supports [verifiable builds](https://solana.com/docs/programs/verified-builds) , which allow users to check whether a program's on-chain code matches its public source code. The Anchor framework provides [built-in support](https://www.anchor-lang.com/docs/verifiable-builds) for creating a verifiable build. To check whether an existing program is verified, search for its program ID on the [Solana Explorer](https://explorer.solana.com/address/PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY) . Alternatively, you may use the Ellipsis Labs [Solana Verifiable Build CLI](https://github.com/Ellipsis-Labs/solana-verifiable-build) , to independently verify on-chain programs. [Built-in programs](https://solana.com/docs/core/programs#built-in-programs) ----------------------------------------------------------------------------- ### [The System Program](https://solana.com/docs/core/programs#the-system-program) The System Program is the only account that can create new accounts. By default, all new accounts are owned by the [System Program](https://github.com/anza-xyz/agave/tree/v2.1.13/programs/system/src) , although many are assigned a new owner upon creation. The System Program performs the following key functions: | Function | Description | | --- | --- | | [New Account Creation](https://github.com/anza-xyz/agave/blob/v2.1.13/programs/system/src/system_processor.rs#L146) | Only the System Program can create new accounts. | | [Space Allocation](https://github.com/anza-xyz/agave/blob/v2.1.13/programs/system/src/system_processor.rs#L71) | Sets the byte capacity for the data field of each account. | | [Assign Program Ownership](https://github.com/anza-xyz/agave/blob/v2.1.13/programs/system/src/system_processor.rs#L113) | Once the System Program creates an account, it can reassign the designated program owner to a different program account. That's how custom programs take ownership of new accounts created by the System Program. | | [Transfer SOL](https://github.com/anza-xyz/agave/blob/v2.1.13/programs/system/src/system_processor.rs#L215) | Transfers lamports (SOL) from System Accounts to other accounts. | The address of the system program is `11111111111111111111111111111111`. ### [Loader programs](https://solana.com/docs/core/programs#loader-programs) Every program is owned by another—its loader. Loaders are used to deploy, redeploy, upgrade or close programs. They are also used to finalize a program and transfer program authority. Loader programs are sometimes referred to as, 'BPF Loaders'. There are currently five loader programs, as shown in the table below. | Loader | Program ID | Notes | Instructions Link | | --- | --- | --- | --- | | native | `NativeLoader1111111111111111111111111111111` | Owns the other four loaders | — | | v1 | `BPFLoader1111111111111111111111111111111111` | Management instructions are disabled, but programs still execute | — | | v2 | `BPFLoader2111111111111111111111111111111111` | Management instructions are disabled, but programs still execute | [Instructions](https://docs.rs/solana-loader-v2-interface/latest/solana_loader_v2_interface/enum.LoaderInstruction.html) | | v3 | `BPFLoaderUpgradeab1e11111111111111111111111` | Programs can be updated after deployment. Program executable is stored in a separate program data account | [Instructions](https://docs.rs/solana-loader-v3-interface/latest/solana_loader_v3_interface/instruction/enum.UpgradeableLoaderInstruction.html) | | v4 | `LoaderV411111111111111111111111111111111111` | In development (unreleased) | [Instructions](https://docs.rs/solana-loader-v4-interface/latest/solana_loader_v4_interface/instruction/enum.LoaderV4Instruction.html) | Programs deployed with loader-v3 or loader-v4 may be modifiable after deployment, as determined by its upgrade authority. When a new program is deployed, the latest loader version will be used by default. ### [Precompiled programs](https://solana.com/docs/core/programs#precompiled-programs) In addition to the loader programs, Solana provides the following precompiled programs. #### [Verify ed25519 signature](https://solana.com/docs/core/programs#verify-ed25519-signature) The ed25519 program is used to verify one or more ed25519 signatures. | Program | Program ID | Description | Instructions | | --- | --- | --- | --- | | Ed25519 Program | `Ed25519SigVerify111111111111111111111111111` | Verifies ed25519 signatures. If any signature fails, an error is returned. | [Instructions](https://docs.rs/solana-ed25519-program/latest/solana_ed25519_program/index.html) | The ed25519 program processes an instruction. The instruction's first `u8` contains a count of the number of signatures to be checked, followed by a single byte padding. After that, the following struct is serialized, one for each signature to be checked. Ed25519SignatureOffsets struct Ed25519SignatureOffsets { signature\_offset: u16, // offset to ed25519 signature of 64 bytes signature\_instruction\_index: u16, // instruction index to find signature public\_key\_offset: u16, // offset to public key of 32 bytes public\_key\_instruction\_index: u16, // instruction index to find public key message\_data\_offset: u16, // offset to start of message data message\_data\_size: u16, // size of message data message\_instruction\_index: u16, // index of instruction data to get message data } Signature verification pseudocode process\_instruction() { for i in 0..count { // i'th index values referenced: instructions = &transaction.message().instructions instruction\_index = ed25519\_signature\_instruction\_index != u16::MAX ? ed25519\_signature\_instruction\_index : current\_instruction; signature = instructions\[instruction\_index\].data\[ed25519\_signature\_offset..ed25519\_signature\_offset + 64\] instruction\_index = ed25519\_pubkey\_instruction\_index != u16::MAX ? ed25519\_pubkey\_instruction\_index : current\_instruction; pubkey = instructions\[instruction\_index\].data\[ed25519\_pubkey\_offset..ed25519\_pubkey\_offset + 32\] instruction\_index = ed25519\_message\_instruction\_index != u16::MAX ? ed25519\_message\_instruction\_index : current\_instruction; message = instructions\[instruction\_index\].data\[ed25519\_message\_data\_offset..ed25519\_message\_data\_offset + ed25519\_message\_data\_size\] if pubkey.verify(signature, message) != Success { return Error } } return Success } #### [Verify secp256k1 recovery](https://solana.com/docs/core/programs#verify-secp256k1-recovery) The secp256k1 program is used to verify secp256k1 public key recovery operations. | Program | Program ID | Description | Instructions | | --- | --- | --- | --- | | Secp256k1 Program | `KeccakSecp256k11111111111111111111111111111` | Verifies secp256k1 public key recovery operations (ecrecover). | [Instructions](https://docs.rs/solana-secp256k1-program/latest/solana_secp256k1_program/index.html) | The secp256k1 program processes an instruction. The instruction's first byte contains a count of the number of public keys to be checked. After that, the following struct is created once for each public key, then serialized and added to the instruction data. Secp256k1SignatureOffsets struct Secp256k1SignatureOffsets { secp\_signature\_offset: u16, // offset to \[signature,recovery\_id\] of 64+1 bytes secp\_signature\_instruction\_index: u8, // instruction index to find signature secp\_pubkey\_offset: u16, // offset to ethereum\_address pubkey of 20 bytes secp\_pubkey\_instruction\_index: u8, // instruction index to find pubkey secp\_message\_data\_offset: u16, // offset to start of message data secp\_message\_data\_size: u16, // size of message data secp\_message\_instruction\_index: u8, // instruction index to find message data } Recovery verification pseudocode process\_instruction() { for i in 0..count { // i'th index values referenced: instructions = &transaction.message().instructions signature = instructions\[secp\_signature\_instruction\_index\].data\[secp\_signature\_offset..secp\_signature\_offset + 64\] recovery\_id = instructions\[secp\_signature\_instruction\_index\].data\[secp\_signature\_offset + 64\] ref\_eth\_pubkey = instructions\[secp\_pubkey\_instruction\_index\].data\[secp\_pubkey\_offset..secp\_pubkey\_offset + 20\] message\_hash = keccak256(instructions\[secp\_message\_instruction\_index\].data\[secp\_message\_data\_offset..secp\_message\_data\_offset + secp\_message\_data\_size\]) pubkey = ecrecover(signature, recovery\_id, message\_hash) eth\_pubkey = keccak256(pubkey\[1..\])\[12..\] if eth\_pubkey != ref\_eth\_pubkey { return Error } } return Success } This allows the user to specify any instruction data in the transaction for signature and message data. By specifying a special instructions sysvar, one can also receive data from the transaction itself. Cost of the transaction will count the number of signatures to verify multiplied by the signature cost verify multiplier. The secp256r1 program is used to verify up to 8 secp256r1 signatures. | Program | Program ID | Description | Instructions | | --- | --- | --- | --- | | Secp256r1 Program | `Secp256r1SigVerify1111111111111111111111111` | Verifies up to 8 secp256r1 signatures. Takes a signature, public key, and message. Returns error if any fail. | [Instructions](https://docs.rs/solana-secp256r1-program/latest/solana_secp256r1_program/all.html) | The secp256r1 program processes an instruction. The instruction's first `u8` is a count of the number of signatures to be checked, followed by a single byte padding. After that, the following struct is created for each signature, then serialized and added to the instruction data. Secp256r1SignatureOffsets struct Secp256r1SignatureOffsets { signature\_offset: u16, // offset to compact secp256r1 signature of 64 bytes signature\_instruction\_index: u16, // instruction index to find signature public\_key\_offset: u16, // offset to compressed public key of 33 bytes public\_key\_instruction\_index: u16, // instruction index to find public key message\_data\_offset: u16, // offset to start of message data message\_data\_size: u16, // size of message data message\_instruction\_index: u16, // index of instruction data to get message data } Low S values are enforced for all signatures to avoid accidental signature malleability. Signature verification psuedocode process\_instruction() { if data.len() < SIGNATURE\_OFFSETS\_START { return Error } num\_signatures = data\[0\] as usize if num\_signatures == 0 || num\_signatures > 8 { return Error } expected\_data\_size = num\_signatures \* SIGNATURE\_OFFSETS\_SERIALIZED\_SIZE + SIGNATURE\_OFFSETS\_START if data.len() < expected\_data\_size { return Error } for i in 0..num\_signatures { offsets = parse\_signature\_offsets(data, i) signature = get\_data\_slice(data, instruction\_datas, offsets.signature\_instruction\_index, offsets.signature\_offset, SIGNATURE\_SERIALIZED\_SIZE) if s > half\_curve\_order { return Error } pubkey = get\_data\_slice(data, instruction\_datas, offsets.public\_key\_instruction\_index, offsets.public\_key\_offset, COMPRESSED\_PUBKEY\_SERIALIZED\_SIZE) message = get\_data\_slice(data, instruction\_datas, offsets.message\_instruction\_index, offsets.message\_data\_offset, offsets.message\_data\_size) if !verify\_signature(signature, pubkey, message) { return Error } } return Success } ### [Core programs](https://solana.com/docs/core/programs#core-programs) The programs in the list below provide the network's core functionality. | Program | Program ID | Description | Instructions | | --- | --- | --- | --- | | **System** | `11111111111111111111111111111111` | Create new accounts, allocate account data, assign accounts to owning programs, transfer lamports from System Program-owned accounts, and pay transaction fees | [SystemInstruction](https://docs.rs/solana-program/latest/solana_program/system_instruction/enum.SystemInstruction.html) | | **Vote** | `Vote111111111111111111111111111111111111111` | Create and manage accounts that track validator voting state and rewards | [VoteInstruction](https://docs.rs/solana-vote-program/latest/solana_vote_program/vote_instruction/enum.VoteInstruction.html) | | **Stake** | `Stake11111111111111111111111111111111111111` | Create and manage accounts representing stake and rewards for delegations to validators | [StakeInstruction](https://docs.rs/solana-sdk/latest/solana_sdk/stake/instruction/enum.StakeInstruction.html) | | **Config** | `Config1111111111111111111111111111111111111` | Add configuration data to the chain, followed by the list of public keys that are allowed to modify it. Unlike the other programs, the Config program does not define any individual instructions. It has just one implicit instruction: "store". Its instruction data is a set of keys that gate access to the account and the data stored inside of it | [ConfigInstruction](https://docs.rs/solana-config-program/latest/solana_config_program/config_instruction/index.html) | | **Compute Budget** | `ComputeBudget111111111111111111111111111111` | Set compute unit limits and prices for transactions, allowing users to control compute resources and prioritization fees | [ComputeBudgetInstruction](https://docs.rs/solana-compute-budget-interface/latest/solana_compute_budget_interface/enum.ComputeBudgetInstruction.html) | | **Address Lookup Table** | `AddressLookupTab1e1111111111111111111111111` | Manage address lookup tables, which allow transactions to reference more accounts than would otherwise fit in the transaction's account list | [ProgramInstruction](https://docs.rs/solana-sdk/latest/solana_sdk/address_lookup_table/instruction/enum.ProgramInstruction.html) | | **ZK ElGamal Proof** | `ZkE1Gama1Proof11111111111111111111111111111` | Provides zero-knowledge proof verification for ElGamal-encrypted data | — | Is this page helpful? [Previous\ \ Transaction Fees](https://solana.com/docs/core/fees) [Next\ \ Program-Derived Address](https://solana.com/docs/core/pda) ### Table of Contents [Write programs](https://solana.com/docs/core/programs#write-programs) [Update programs](https://solana.com/docs/core/programs#update-programs) [Verify programs](https://solana.com/docs/core/programs#verify-programs) [Built-in programs](https://solana.com/docs/core/programs#built-in-programs) [The System Program](https://solana.com/docs/core/programs#the-system-program) [Loader programs](https://solana.com/docs/core/programs#loader-programs) [Precompiled programs](https://solana.com/docs/core/programs#precompiled-programs) [Verify ed25519 signature](https://solana.com/docs/core/programs#verify-ed25519-signature) [Verify secp256k1 recovery](https://solana.com/docs/core/programs#verify-secp256k1-recovery) [Core programs](https://solana.com/docs/core/programs#core-programs) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/core/programs.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter --- # Quick Start | Solana This website uses cookies to offer you a better browsing experience. Find out more on how we use cookies. Opt-out[Details](https://solana.com/privacy-policy#collection-of-information) Accept [Solana Documentation](https://solana.com/docs) Getting Started [Quick Start](https://solana.com/docs/intro/quick-start) ========================================================= Copy MarkdownOpen Welcome to the Solana quick start guide! This hands-on guide will introduce you to the **Solana Playground** (Solpg), where you can learn core-concepts, regardless of your prior experience. In this tutorial, you will learn about: * **Solana accounts**: How the Solana network stores data * **Sending transactions**: How to interact with the Solana network by sending transactions * **Building and deploying programs**: Create your first Solana program and deploy it to the network * **Program-Derived addresses**: Learn how to create deterministic addresses for accounts * **Cross-Program Invocations**: Learn how to call other programs from within your program, enabling complex interactions and program composability [The Solana Playground](https://solana.com/docs/intro/quick-start#the-solana-playground) ----------------------------------------------------------------------------------------- The Solana Playground is a browser-based development environment that allows you to develop, deploy, and test Solana programs without installing anything locally. Follow along, copy, and paste code, and see results immediately. Basic programming knowledge helps but is not required. Time to dive in and start building with Solana! As a new user, the first step to interacting with the Solana Playground is to create a Playground [wallet](https://solana.com/docs/references/terminology#wallet) and add [SOL](https://solana.com/docs/references/terminology#sol) . This wallet will allow you to interact with the Solana network directly from your browser. [Create a Playground wallet](https://solana.com/docs/intro/quick-start#create-a-playground-wallet) --------------------------------------------------------------------------------------------------- ### [Navigate to the Solana Playground](https://solana.com/docs/intro/quick-start#navigate-to-the-solana-playground) Using your web browser, navigate to the [Solana Playground](https://beta.solpg.io/) . ### [Connect to the Playground](https://solana.com/docs/intro/quick-start#connect-to-the-playground) Click the 🔴 **Not connected** text at the bottom left corner of the screen. ![Not Connected](https://solana.com/assets/docs/intro/quickstart/pg-not-connected.png)Not Connected ### [Save your keypair](https://solana.com/docs/intro/quick-start#save-your-keypair) Click **Save keypair** to save your key pair locally. When you're ready, click **Continue**. ![Create Playground Wallet](https://solana.com/assets/docs/intro/quickstart/pg-create-wallet.png)Create Playground Wallet At the bottom of the screen, you will see that you are now connected to the Playground wallet. You will also see the [connected cluster](https://solana.com/docs/references/terminology#connected-cluster) (`devnet`), the [wallet address](https://solana.com/docs/references/terminology#wallet-address) , and your [SOL](https://solana.com/docs/references/terminology#sol) balance. ![Connected](https://solana.com/assets/docs/intro/quickstart/pg-connected.png)Connected Your browser's local storage saves your Playground wallet. Clearing your browser cache will remove your saved wallet. Use your Playground wallet for testing and development only. Never send real assets (from [`mainnet`](https://solana.com/docs/references/terminology#connected-cluster) ) to this address. Congratulations! You created your first Solana Wallet. You are now ready to add SOL to your wallet. ### [Add SOL to your wallet](https://solana.com/docs/intro/quick-start#add-sol-to-your-wallet) Before starting development, you need to add devnet SOL to your wallet. As a developer, SOL is used for two main use cases: * To create new accounts for storing data or deploying programs * Paying transaction fees when interacting with the Solana network You can add devnet SOL to your wallet using the Playground terminal or with the Devnet Faucet. Each option is described below: #### [Option 1: Use the Playground terminal](https://solana.com/docs/intro/quick-start#option-1-use-the-playground-terminal) Run the following command in the Playground terminal: Terminal $ solana airdrop 5 Copy #### [Option 2: Use the Devnet faucet](https://solana.com/docs/intro/quick-start#option-2-use-the-devnet-faucet) If option 1 fails, due to rate limits or other errors, use Solana's [Web Faucet](https://faucet.solana.com/) . * Enter your wallet address * Select an amount * Click **Confirm Airdrop** ![Faucet Airdrop](https://solana.com/assets/docs/intro/quickstart/faucet-airdrop.gif)Faucet Airdrop Is this page helpful? [Previous\ \ Surfpool CLI Basics](https://solana.com/docs/intro/installation/surfpool-cli-basics) [Next\ \ Reading from Network](https://solana.com/docs/intro/quick-start/reading-from-network) ### Table of Contents [The Solana Playground](https://solana.com/docs/intro/quick-start#the-solana-playground) [Create a Playground wallet](https://solana.com/docs/intro/quick-start#create-a-playground-wallet) [Navigate to the Solana Playground](https://solana.com/docs/intro/quick-start#navigate-to-the-solana-playground) [Connect to the Playground](https://solana.com/docs/intro/quick-start#connect-to-the-playground) [Save your keypair](https://solana.com/docs/intro/quick-start#save-your-keypair) [Add SOL to your wallet](https://solana.com/docs/intro/quick-start#add-sol-to-your-wallet) [Option 1: Use the Playground terminal](https://solana.com/docs/intro/quick-start#option-1-use-the-playground-terminal) [Option 2: Use the Devnet faucet](https://solana.com/docs/intro/quick-start#option-2-use-the-devnet-faucet) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/intro/quick-start/index.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter Quick Start | Solana --- # Payments | Solana This website uses cookies to offer you a better browsing experience. Find out more on how we use cookies. Opt-out[Details](https://solana.com/privacy-policy#collection-of-information) Accept [Payments](https://solana.com/docs) [Payments](https://solana.com/docs/payments) ============================================= Copy MarkdownOpen Solana is built with certain features that are ideal for payments including native fee abstraction, sub-cent fees, embedded memos, predictably stable fees, and fast confirmation times. In 2025, Solana processed over [**$1 trillion**](https://app.artemisanalytics.com/asset/solana?from=assets) in stablecoin volume. This guide will help you build advanced payment systems for multiple use cases including remittances, treasury optimization, global payouts, cross-border payments, merchant acceptance, invoices, and more. [Get Started](https://solana.com/docs/payments#get-started) ------------------------------------------------------------ [### How Payments Work on Solana\ \ New to Solana? Learn the core concepts of sending and receiving payments on Solana.](https://solana.com/docs/payments/how-payments-work) [### Send a Payment\ \ Send your first stablecoin payment between accounts with optional memos for reconciliation.](https://solana.com/docs/payments/send-payments) [### Accept Payments\ \ Integrate stablecoin payments into your checkout flow.](https://solana.com/docs/payments/accept-payments) [### Payouts & Disbursements\ \ Disburse funds to users, vendors, or employees at scale.](https://solana.com/docs/payments/send-payments/payment-processing) [Why Solana](https://solana.com/docs/payments#why-solana) ---------------------------------------------------------- * **Instant settlement**. Funds secured in ~400ms. No T+2, no manual batch processing, no reconciliation delays. * **Sub-cent fees**. Median fee ~$0.001 per transaction. Batch multiple payments into a single transaction to improve payment efficiency and reduce costs further. * **Local fee markets.** Dedicated fee markets for payments so your flows are unaffected by other network activity. * **Parallel execution**. Process transactions in parallel to further increase your payment throughput. * **Familiar UX**. Sponsor or abstract away network fees so users pay in stablecoins without acquiring SOL. * **Programmable**. Build custom payment applications with compliance built in (reconciliation memos, blacklists, automated tax accounting, etc.). Is this page helpful? [Previous\ \ getStakeActivation](https://solana.com/docs/rpc/deprecated/getstakeactivation) [Next\ \ How Payments Work on Solana](https://solana.com/docs/payments/how-payments-work) ### Table of Contents [Get Started](https://solana.com/docs/payments#get-started) [Why Solana](https://solana.com/docs/payments#why-solana) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/payments/index.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter --- # Solana RPC Methods: HTTP & Websockets | Solana This website uses cookies to offer you a better browsing experience. Find out more on how we use cookies. Opt-out[Details](https://solana.com/privacy-policy#collection-of-information) Accept [Solana Documentation](https://solana.com/docs) [Solana RPC Methods & Documentation](https://solana.com/docs/rpc) ================================================================== Copy MarkdownOpen Interact with Solana nodes directly with the JSON RPC API via the HTTP and Websocket methods. [Configuring State Commitment](https://solana.com/docs/rpc#configuring-state-commitment) ----------------------------------------------------------------------------------------- For preflight checks and transaction processing, Solana nodes choose which bank state to query based on a commitment requirement set by the client. The commitment describes how finalized a block is at that point in time. When querying the ledger state, it's recommended to use lower levels of commitment to report progress and higher levels to ensure the state will not be rolled back. In descending order of commitment (most finalized to least finalized), clients may specify: * `finalized` - the node will query the most recent block confirmed by supermajority of the cluster as having reached maximum lockout, meaning the cluster has recognized this block as finalized * `confirmed` - the node will query the most recent block that has been voted on by supermajority of the cluster. * It incorporates votes from gossip and replay. * It does not count votes on descendants of a block, only direct votes on that block. * This confirmation level also upholds "optimistic confirmation" guarantees in release 1.3 and onwards. * `processed` - the node will query its most recent block. Note that the block may still be skipped by the cluster. For processing many dependent transactions in series, it's recommended to use `confirmed` commitment, which balances speed with rollback safety. For total safety, it's recommended to use `finalized` commitment. ### [Default Commitment](https://solana.com/docs/rpc#default-commitment) If commitment configuration is not provided, the node will [default to `finalized` commitment](https://github.com/anza-xyz/agave/blob/aa0922d6845e119ba466f88497e8209d1c82febc/sdk/src/commitment_config.rs#L199-L203) Only methods that query bank state accept the commitment parameter. They are indicated in the API Reference below. [RpcResponse Structure](https://solana.com/docs/rpc#rpcresponse-structure) --------------------------------------------------------------------------- Many methods that take a commitment parameter return an RpcResponse JSON object comprised of two parts: * `context` : An RpcResponseContext JSON structure including a `slot` field at which the operation was evaluated. * `value` : The value returned by the operation itself. [Parsed Responses](https://solana.com/docs/rpc#parsed-responses) ----------------------------------------------------------------- Some methods support an `encoding` parameter, and can return account or instruction data in parsed JSON format if `"encoding":"jsonParsed"` is requested and the node has a parser for the owning program. Solana nodes currently support JSON parsing for the following native and SPL programs: | Program | Account State | Instructions | | --- | --- | --- | | Address Lookup | v1.15.0 | v1.15.0 | | BPF Loader | n/a | stable | | BPF Upgradeable Loader | stable | stable | | Config | stable | | | SPL Associated Token Account | n/a | stable | | SPL Memo | n/a | stable | | SPL Token | stable | stable | | SPL Token 2022 | stable | stable | | Stake | stable | stable | | Vote | stable | stable | The list of account parsers can be found [here](https://github.com/solana-labs/solana/blob/master/account-decoder/src/parse_account_data.rs) , and instruction parsers [here](https://github.com/solana-labs/solana/blob/master/transaction-status/src/parse_instruction.rs) . [Filter criteria](https://solana.com/docs/rpc#filter-criteria) --------------------------------------------------------------- Some methods support providing a `filters` object to enable pre-filtering the data returned within the RpcResponse JSON object. The following filters exist: * `memcmp: object` - compares a provided series of bytes with program account data at a particular offset. Fields: * `offset: usize` - offset into program account data to start comparison * `bytes: string` - data to match, as encoded string * `encoding: string` - encoding for filter `bytes` data, either "base58" or "base64". Data is limited in size to 128 or fewer decoded bytes. **NEW: This field, and base64 support generally, is only available in solana-core v1.14.0 or newer. Please omit when querying nodes on earlier versions** * `dataSize: u64` - compares the program account data length with the provided data size Is this page helpful? [Previous\ \ Terminology](https://solana.com/docs/references/terminology) [Next\ \ Data Structures as JSON](https://solana.com/docs/rpc/json-structures) ### Table of Contents [Configuring State Commitment](https://solana.com/docs/rpc#configuring-state-commitment) [Default Commitment](https://solana.com/docs/rpc#default-commitment) [RpcResponse Structure](https://solana.com/docs/rpc#rpcresponse-structure) [Parsed Responses](https://solana.com/docs/rpc#parsed-responses) [Filter criteria](https://solana.com/docs/rpc#filter-criteria) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/rpc/index.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter Solana RPC Methods: HTTP & Websockets | Solana --- # Clusters and Public RPC Endpoints | Solana [Solana Documentation](https://solana.com/docs) References [Clusters and Public RPC Endpoints](https://solana.com/docs/references/clusters) ================================================================================= Copy MarkdownOpen The Solana blockchain has several different groups of validators, known as Clusters. Each serving different purposes within the overall ecosystem and containing dedicated API nodes to fulfill [JSON-RPC](https://solana.com/docs/rpc/) requests for their respective Cluster. The individual nodes within a Cluster are owned and operated by third parties, with a public endpoint available for each. [Solana public RPC endpoints](https://solana.com/docs/references/clusters#solana-public-rpc-endpoints) ------------------------------------------------------------------------------------------------------- The Solana Labs organization operates a public RPC endpoint for each Cluster. Each of these public endpoints are subject to rate limits, but are available for users and developers to interact with the Solana blockchain. > Public endpoint rate limits are subject to change. The specific rate limits listed on this document are not guaranteed to be the most up-to-date. ### [Using explorers with different Clusters](https://solana.com/docs/references/clusters#using-explorers-with-different-clusters) Many of the popular Solana blockchain explorers support selecting any of the Clusters, often allowing advanced users to add a custom/private RPC endpoint as well. An example of some of these Solana blockchain explorers include: * [http://explorer.solana.com/](https://explorer.solana.com/) . * [http://orb.helius.dev/](https://orb.helius.dev/) . * [http://solana.fm/](https://solana.fm/) . * [http://solscan.io/](https://solscan.io/) . * [http://solanabeach.io/](http://solanabeach.io/) . * [http://validators.app/](http://validators.app/) . [On a high level](https://solana.com/docs/references/clusters#on-a-high-level) ------------------------------------------------------------------------------- * Mainnet: Live production environment for deployed applications. * Devnet: Testing with public accessibility for developers experimenting with their applications. * Testnet: Stress-testing for network upgrades and validator performance. **Example use cases**: You may want to debug a new program on Devnet or verify performance metrics on Testnet before Mainnet deployment. | **Cluster** | **Endpoint** | **Purpose** | **Notes** | | --- | --- | --- | --- | | Mainnet | `https://api.mainnet.solana.com` | Live production environment | Requires SOL for transactions | | Devnet | `https://api.devnet.solana.com` | Public testing and development | Free SOL airdrop for testing | | Testnet | `https://api.testnet.solana.com` | Validator and stress testing | May have intermittent downtime | [Devnet](https://solana.com/docs/references/clusters#devnet) ------------------------------------------------------------- Devnet serves as a playground for anyone who wants to take Solana for a test drive, as a user, token holder, app developer, or validator. * Application developers should target Devnet. * Potential validators should first target Devnet. * Key differences between Devnet and Mainnet: * Devnet tokens are **not real** * Devnet includes a token faucet for airdrops for application testing * Devnet may be subject to ledger resets * Devnet typically runs the same software release branch version as Mainnet Beta, but may run a newer minor release version than Mainnet. * Gossip entrypoint for Devnet: `entrypoint.devnet.solana.com:8001` ### [Devnet endpoint](https://solana.com/docs/references/clusters#devnet-endpoint) * `https://api.devnet.solana.com` - single Solana Labs hosted API node; rate-limited #### [Example `solana` command-line configuration](https://solana.com/docs/references/clusters#example-solana-command-line-configuration) To connect to the `devnet` Cluster using the Solana CLI: solana config set \--url https://api.devnet.solana.com ### [Devnet rate limits](https://solana.com/docs/references/clusters#devnet-rate-limits) * Maximum number of requests per 10 seconds per IP: 100 * Maximum number of requests per 10 seconds per IP for a single RPC: 40 * Maximum concurrent connections per IP: 40 * Maximum connection rate per 10 seconds per IP: 40 * Maximum amount of data per 30 second: 100 MB [Testnet](https://solana.com/docs/references/clusters#testnet) --------------------------------------------------------------- Testnet is where the Solana core contributors stress test recent release features on a live cluster, particularly focused on network performance, stability and validator behavior. * Testnet tokens are **not real** * Testnet may be subject to ledger resets. * Testnet includes a token faucet for airdrops for application testing * Testnet typically runs a newer software release branch than both Devnet and Mainnet * Gossip entrypoint for Testnet: `entrypoint.testnet.solana.com:8001` ### [Testnet endpoint](https://solana.com/docs/references/clusters#testnet-endpoint) * `https://api.testnet.solana.com` - single Solana Labs API node; rate-limited #### [Example `solana` command-line configuration](https://solana.com/docs/references/clusters#example-solana-command-line-configuration-1) To connect to the `testnet` Cluster using the Solana CLI: solana config set \--url https://api.testnet.solana.com ### [Testnet rate limits](https://solana.com/docs/references/clusters#testnet-rate-limits) * Maximum number of requests per 10 seconds per IP: 100 * Maximum number of requests per 10 seconds per IP for a single RPC: 40 * Maximum concurrent connections per IP: 40 * Maximum connection rate per 10 seconds per IP: 40 * Maximum amount of data per 30 second: 100 MB [Mainnet](https://solana.com/docs/references/clusters#mainnet) --------------------------------------------------------------- A permissionless, persistent cluster for Solana users, builders, validators and token holders. * Tokens that are issued on Mainnet are **real** SOL * Gossip entrypoint for Mainnet: `entrypoint.mainnet.solana.com:8001` ### [Mainnet endpoint](https://solana.com/docs/references/clusters#mainnet-endpoint) * `https://api.mainnet.solana.com` - Solana Labs hosted API node cluster, backed by a load balancer; rate-limited #### [Example `solana` command-line configuration](https://solana.com/docs/references/clusters#example-solana-command-line-configuration-2) To connect to the `mainnet` Cluster using the Solana CLI: solana config set \--url https://api.mainnet.solana.com ### [Mainnet rate limits](https://solana.com/docs/references/clusters#mainnet-rate-limits) * Maximum number of requests per 10 seconds per IP: 100 * Maximum number of requests per 10 seconds per IP for a single RPC: 40 * Maximum concurrent connections per IP: 40 * Maximum connection rate per 10 seconds per IP: 40 * Maximum amount of data per 30 seconds: 100 MB > The public RPC endpoints are not intended for production applications. Please use dedicated/private RPC servers when you launch your application, drop NFTs, etc. The public services are subject to abuse and rate limits may change without prior notice. Likewise, high-traffic websites may be blocked without prior notice. [Common HTTP Error Codes](https://solana.com/docs/references/clusters#common-http-error-codes) ----------------------------------------------------------------------------------------------- * 403 -- Your IP address or website has been blocked. It is time to run your own RPC server(s) or find a private service. * 429 -- Your IP address is exceeding the rate limits. Slow down! Use the [Retry-After](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) HTTP response header to determine how long to wait before making another request. Is this page helpful? [Previous\ \ Solana Gaming SDKs](https://solana.com/docs/clients/community/game-sdks) [Next\ \ Staking](https://solana.com/docs/references/staking) ### Table of Contents [Solana public RPC endpoints](https://solana.com/docs/references/clusters#solana-public-rpc-endpoints) [Using explorers with different Clusters](https://solana.com/docs/references/clusters#using-explorers-with-different-clusters) [On a high level](https://solana.com/docs/references/clusters#on-a-high-level) [Devnet](https://solana.com/docs/references/clusters#devnet) [Devnet endpoint](https://solana.com/docs/references/clusters#devnet-endpoint) [Example `solana` command-line configuration](https://solana.com/docs/references/clusters#example-solana-command-line-configuration) [Devnet rate limits](https://solana.com/docs/references/clusters#devnet-rate-limits) [Testnet](https://solana.com/docs/references/clusters#testnet) [Testnet endpoint](https://solana.com/docs/references/clusters#testnet-endpoint) [Example `solana` command-line configuration](https://solana.com/docs/references/clusters#example-solana-command-line-configuration-1) [Testnet rate limits](https://solana.com/docs/references/clusters#testnet-rate-limits) [Mainnet](https://solana.com/docs/references/clusters#mainnet) [Mainnet endpoint](https://solana.com/docs/references/clusters#mainnet-endpoint) [Example `solana` command-line configuration](https://solana.com/docs/references/clusters#example-solana-command-line-configuration-2) [Mainnet rate limits](https://solana.com/docs/references/clusters#mainnet-rate-limits) [Common HTTP Error Codes](https://solana.com/docs/references/clusters#common-http-error-codes) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/references/clusters.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter --- # Tokens on Solana | Solana [Solana Documentation](https://solana.com/docs) [Tokens on Solana](https://solana.com/docs/tokens) =================================================== Copy MarkdownOpen Tokens are digital assets that represent ownership over diverse categories of assets. Tokenization enables the digitalization of property rights. Tokens on Solana are referred to as SPL ([Solana Program Library](https://github.com/solana-program) ) Tokens. This section covers the basic concepts of how tokens are represented on Solana. Refer to the [SPL Token Basics](https://solana.com/docs/tokens/basics) section for code examples. [Key Points](https://solana.com/docs/core/tokens#key-points) ------------------------------------------------------------- * [Token Programs](https://solana.com/docs/core/tokens#token-program) contain all instruction logic for interacting with tokens on the network (both fungible and non-fungible). * A [Mint Account](https://solana.com/docs/core/tokens#mint-account) represents a specific token and stores global metadata about the token such as the total supply and mint authority (address authorized to create new units of a token). * A [Token Account](https://solana.com/docs/core/tokens#token-account) tracks individual ownership of tokens for a specific mint account for a specific owner. * An [Associated Token Account](https://solana.com/docs/core/tokens#associated-token-account) is a Token Account created with an address derived from the owner and mint account addresses. [Token Programs](https://solana.com/docs/core/tokens#token-programs) --------------------------------------------------------------------- The Solana ecosystem has two main Token Programs. Source code for both programs below. [### Token Program (Original)\ \ * Basic token capability (mint, transfer, etc.)\ * Immutable and widely used](https://github.com/solana-program/token) [### Token Extension Program (Token 2022)\ \ * Includes all original Token Program features\ * Adds features through "extensions"](https://github.com/solana-program/token-2022) Token Programs contains all instruction logic for interacting with tokens on the network (both fungible and non-fungible). All tokens on Solana are effectively [data accounts](https://solana.com/docs/core/accounts#data-account) owned by a Token Program. ![Token Program](https://solana.com/assets/docs/core/tokens/token-program.svg)Token Program ### [Mint Account](https://solana.com/docs/core/tokens#mint-account) Tokens on Solana are uniquely identified by the address of a [Mint Account](https://github.com/solana-program/token/blob/6d18ff73b1dd30703a30b1ca941cb0f1d18c2b2a/program/src/state.rs#L16-L30) owned by the Token Program. This account acts as a global counter for a specific token and stores data such as: * **Supply**: Total supply of the token * **Decimals**: Decimal precision of the token * **Mint authority**: The account authorized to create new units of the token, increasing the supply * **Freeze authority**: The account authorized to freeze tokens in a Token Account, preventing them from being transferred or burned ![Mint Account](https://solana.com/assets/docs/core/tokens/mint-account.svg)Mint Account The full details stored on each Mint Account include the following: Mint Account State 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, /// 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 initialized pub is\_initialized: bool, /// Optional authority to freeze token accounts. pub freeze\_authority: COption, } For reference, here is a Solana Explorer link to the [USDC Mint Account](https://explorer.solana.com/address/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v) . ### [Token Account](https://solana.com/docs/core/tokens#token-account) The Token Program creates [Token Accounts](https://github.com/solana-program/token/blob/6d18ff73b1dd30703a30b1ca941cb0f1d18c2b2a/program/src/state.rs#L87-L108) to track individual ownership of each token unit. A Token Account stores data such as: * **Mint**: The token the Token Account holds units of * **Owner**: The account authorized to transfer tokens from the Token Account * **Amount**: Number of the tokens the Token Account currently holds ![Token Account](https://solana.com/assets/docs/core/tokens/token-account.svg)Token Account The full details stored on each Token Account include the following: Token Account State pub struct Account { /// The mint associated with this account pub mint: Pubkey, /// The owner of this account. pub owner: Pubkey, /// The amount of tokens this account holds. pub amount: u64, /// If \`delegate\` is \`Some\` then \`delegated\_amount\` represents /// the amount authorized by the delegate pub delegate: COption, /// The account's state pub state: AccountState, /// If is\_native.is\_some, this is a native token, and the value logs the /// rent-exempt reserve. An Account is required to be rent-exempt, so /// the value is used by the Processor to ensure that wrapped SOL /// accounts do not drop below this threshold. pub is\_native: COption, /// The amount delegated pub delegated\_amount: u64, /// Optional authority to close the account. pub close\_authority: COption, } A wallet needs a token account for each token (mint) it wants to hold, with the wallet address set as the token account owner. Each wallet can own multiple token accounts for the same token (mint), but a token account can only have one owner and hold units of one token (mint). ![Account Relationship](https://solana.com/assets/docs/core/tokens/token-account-relationship.svg)Account Relationship Note that each Token Account's data includes an `owner` field identifying who has authority over the Token Account. This differs from the program owner specified in the base [Account](https://solana.com/docs/core/accounts#account-type) type, which is the Token Program for all Token Accounts. ### [Associated Token Account](https://solana.com/docs/core/tokens#associated-token-account) Associated Token Accounts simplify the process of finding a token account's address for a specific mint and owner. Think of the Associated Token Account as the "default" token account for a specific mint and owner. An Associated Token Account is created with an address derived from the owner's address and the mint account's address. It's important to understand that an Associated Token Account is just a token account with a specific address. This introduces a key concept in Solana development: [Program Derived Address (PDA)](https://solana.com/docs/core/pda) . A PDA derives an address deterministically using predefined inputs, making it easy to find the address of an account. ![Associated Token Account](https://solana.com/assets/docs/core/tokens/associated-token-account.svg)Associated Token Account Note that each wallet needs its own token account to hold tokens from the same mint. ![Accounts Relationship Expanded](https://solana.com/assets/docs/core/tokens/token-account-relationship-ata.svg)Accounts Relationship Expanded [Token CLI Examples](https://solana.com/docs/core/tokens#token-cli-examples) ----------------------------------------------------------------------------- The `spl-token` CLI helps you experiment with SPL tokens. The examples below use the [Solana Playground](https://beta.solpg.io/) terminal to run CLI commands directly in the browser without local installation. Creating tokens and accounts requires SOL for account rent deposits and transaction fees. For first-time Solana Playground users, create a Playground wallet and run the `solana airdrop` command in the Playground terminal. You can also get devnet SOL from the public [web faucet](https://faucet.solana.com/) . Terminal $ solana airdrop 2 Copy Run `spl-token --help` to see all available commands. Terminal $ spl-token --help Copy To install the `spl-token` CLI locally, run: Terminal $ cargo install spl-token-cli Copy Find more examples in the `spl-token` [documentation](https://www.solana-program.com/docs/token) . The account addresses shown in your terminal output differ from the examples below. Use the addresses from your Playground terminal when following along. For example, the `create-token` command outputs a mint account address with your Playground wallet as the mint authority. ### [Create a New Token](https://solana.com/docs/core/tokens#create-a-new-token) To create a new token (mint account), run: Terminal $ spl-token create-token Copy The output looks like: Terminal Output Creating token 99zqUzQGohamfYxyo8ykTEbi91iom3CLmwCA75FK5zTg Address: 99zqUzQGohamfYxyo8ykTEbi91iom3CLmwCA75FK5zTg Decimals: 9 Signature: 44fvKfT1ezBUwdzrCys3fvCdFxbLMnNvBstds76QZyE6cXag5NupBprSXwxPTzzjrC3cA6nvUZaLFTvmcKyzxrm1 A new mint account starts with zero supply. Check the current supply with: Terminal $ spl-token supply Copy The `supply` command for a new token returns `0`: Example spl-token supply 99zqUzQGohamfYxyo8ykTEbi91iom3CLmwCA75FK5zTg Creating a new Mint Account requires a transaction with two instructions. Here's a Javascript example on [Solana Playground](https://beta.solpg.io/660ce32ecffcf4b13384d00f) . 1. The System Program creates a new account with space for the Mint Account data and transfers ownership to the Token Program. 2. The Token Program initializes the data of the new account as a Mint Account ### [Create Token Account](https://solana.com/docs/core/tokens#create-token-account) To hold tokens of a specific mint, create a token account: Terminal $ spl-token create-account Copy Example command: Example spl-token create-account 99zqUzQGohamfYxyo8ykTEbi91iom3CLmwCA75FK5zTg Output: Terminal Output Creating account AfB7uwBEsGtrrBqPTVqEgzWed5XdYfM1psPNLmf7EeX9 Signature: 2BtrynuCLX9CNofFiaw6Yzbx6hit66pup9Sk7aFjwU2NEbFz7NCHD9w9sWhrCfEd73XveAGK1DxFpJoQZPXU9tS1 The `create-account` command creates an associated token account with your wallet address as the owner. To create a token account with a different owner: Terminal $ spl-token create-account --owner Copy Note: `` specifies the mint account for the token account. Example command: Example spl-token create-account \--owner 2i3KvjDCZWxBsqcxBHpdEaZYQwQSYE6LXUMx5VjY5XrR 99zqUzQGohamfYxyo8ykTEbi91iom3CLmwCA75FK5zTg Output: Terminal Output Creating account Hmyk3FSw4cfsuAes7sanp2oxSkE9ivaH6pMzDzbacqmt Signature: 44vqKdfzspT592REDPY4goaRJH3uJ3Ce13G4BCuUHg35dVUbHuGTHvqn4ZjYF9BGe9QrjMfe9GmuLkQhSZCBQuEt Creating an Associated Token Account requires one instruction that invokes the [Associated Token Program](https://github.com/solana-program/associated-token-account) . Here's a Javascript example on [Solana Playground](https://beta.solpg.io/660ce868cffcf4b13384d011) . The Associated Token Program uses [Cross Program Invocations](https://solana.com/docs/core/cpi) to: * [Invoke the System Program](https://github.com/solana-program/associated-token-account/blob/9d94201e8158f06015ff80ad47fefac62a2ec450/program/src/tools/account.rs#L19) to create a new account using the provided PDA as the address * [Invoke the Token Program](https://github.com/solana-program/associated-token-account/blob/9d94201e8158f06015ff80ad47fefac62a2ec450/program/src/processor.rs#L138-L161) to initialize the Token Account data To create a new Token Account with a new keypair instead of an Associated Token Account address, send a transaction with two instructions. Here's a Javascript example on [Solana Playground](https://beta.solpg.io/660ce716cffcf4b13384d010) . 1. The System Program creates a new account with space for the Token Account data and transfers ownership to the Token Program. 2. The Token Program initializes the data as a Token Account ### [Mint Tokens](https://solana.com/docs/core/tokens#mint-tokens) To create new units of a token, mint tokens to a Token Account: Terminal $ spl-token mint \[OPTIONS\] \[--\] \[RECIPIENT\_TOKEN\_ACCOUNT\_ADDRESS\] Copy Example command: Example spl-token mint 99zqUzQGohamfYxyo8ykTEbi91iom3CLmwCA75FK5zTg 100 Output: Terminal Output Minting 100 tokens Token: 99zqUzQGohamfYxyo8ykTEbi91iom3CLmwCA75FK5zTg Recipient: AfB7uwBEsGtrrBqPTVqEgzWed5XdYfM1psPNLmf7EeX9 Signature: 2NJ1m7qCraPSBAVxbr2ssmWZmBU9Jc8pDtJAnyZsZJRcaYCYMqq1oRY1gqA4ddQno3g3xcnny5fzr1dvsnFKMEqG To mint tokens to a different token account: Example spl-token mint 99zqUzQGohamfYxyo8ykTEbi91iom3CLmwCA75FK5zTg 100 -- Hmyk3FSw4cfsuAes7sanp2oxSkE9ivaH6pMzDzbacqmt Output: Terminal Output Minting 100 tokens Token: 99zqUzQGohamfYxyo8ykTEbi91iom3CLmwCA75FK5zTg Recipient: Hmyk3FSw4cfsuAes7sanp2oxSkE9ivaH6pMzDzbacqmt Signature: 3SQvNM3o9DsTiLwcEkSPT1Edr14RgE2wC54TEjonEP2swyVCp2jPWYWdD6RwXUGpvDNUkKWzVBZVFShn5yntxVd7 The `MintTo` instruction on the Token Program creates new tokens. The mint authority must sign the transaction. The instruction mints tokens to a Token Account and increases the total supply on the Mint Account. Here's a Javascript example on [Solana Playground](https://beta.solpg.io/660cea45cffcf4b13384d012) . ### [Transfer Tokens](https://solana.com/docs/core/tokens#transfer-tokens) To transfer tokens between token accounts: Terminal spl-token transfer \[OPTIONS\] Example command: Example spl-token transfer 99zqUzQGohamfYxyo8ykTEbi91iom3CLmwCA75FK5zTg 100 Hmyk3FSw4cfsuAes7sanp2oxSkE9ivaH6pMzDzbacqmt Output: Terminal Output Transfer 100 tokens Sender: AfB7uwBEsGtrrBqPTVqEgzWed5XdYfM1psPNLmf7EeX9 Recipient: Hmyk3FSw4cfsuAes7sanp2oxSkE9ivaH6pMzDzbacqmt Signature: 5y6HVwV8V2hHGLTVmTmdySRiEUCZnWmkasAvJ7J6m7JR46obbGKCBqUFgLpZu5zQGwM4Xy6GZ4M5LKd1h6Padx3o The `Transfer` instruction on the Token Program handles token transfers. The owner of the sender's Token Account must sign the transaction. The instruction moves tokens between Token Accounts. Here's a Javascript example on [Solana Playground](https://beta.solpg.io/660ced84cffcf4b13384d013) . Both sender and recipient need token accounts for the specific token (mint). The sender can include instructions to create the recipient's token account in the same transaction. ### [Create Token Metadata](https://solana.com/docs/core/tokens#create-token-metadata) The Token Extensions Program lets you store metadata (name, symbol, image link) directly on the Mint Account. To create a token with metadata extension: Example spl-token create-token \--program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb \--enable-metadata Output: Terminal Output Creating token BdhzpzhTD1MFqBiwNdrRy4jFo2FHFufw3n9e8sVjJczP under program TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb To initialize metadata inside the mint, please run \`spl-token initialize-metadata BdhzpzhTD1MFqBiwNdrRy4jFo2FHFufw3n9e8sVjJczP \`, and sign with the mint authority. Address: BdhzpzhTD1MFqBiwNdrRy4jFo2FHFufw3n9e8sVjJczP Decimals: 9 Signature: 5iQofFeXdYhMi9uTzZghcq8stAaa6CY6saUwcdnELST13eNSifiuLbvR5DnRt311frkCTUh5oecj8YEvZSB3wfai To initialize the metadata: Terminal spl-token initialize-metadata The token URI links to off-chain metadata. See an example JSON format [here](https://raw.githubusercontent.com/solana-developers/opos-asset/main/assets/DeveloperPortal/metadata.json) . Example command: Example spl-token initialize-metadata BdhzpzhTD1MFqBiwNdrRy4jFo2FHFufw3n9e8sVjJczP "TokenName" "TokenSymbol" "https://raw.githubusercontent.com/solana-developers/opos-asset/main/assets/DeveloperPortal/metadata.json" View the metadata on [Solana Explorer](https://explorer.solana.com/address/BdhzpzhTD1MFqBiwNdrRy4jFo2FHFufw3n9e8sVjJczP?cluster=devnet) . Learn more in the [Metadata Extension Guide](https://solana.com/developers/guides/token-extensions/metadata-pointer) . For details about Token Extensions, see the Token Extensions [Getting Started Guide](https://solana.com/developers/guides/token-extensions/getting-started) and the [SPL documentation](https://www.solana-program.com/docs/token-2022/extensions) . Is this page helpful? [Previous\ \ Cross Program Invocation](https://solana.com/docs/core/cpi) [Next\ \ SPL Token Basics](https://solana.com/docs/tokens/basics) ### Table of Contents [Key Points](https://solana.com/docs/core/tokens#key-points) [Token Programs](https://solana.com/docs/core/tokens#token-programs) [Mint Account](https://solana.com/docs/core/tokens#mint-account) [Token Account](https://solana.com/docs/core/tokens#token-account) [Associated Token Account](https://solana.com/docs/core/tokens#associated-token-account) [Token CLI Examples](https://solana.com/docs/core/tokens#token-cli-examples) [Create a New Token](https://solana.com/docs/core/tokens#create-a-new-token) [Create Token Account](https://solana.com/docs/core/tokens#create-token-account) [Mint Tokens](https://solana.com/docs/core/tokens#mint-tokens) [Transfer Tokens](https://solana.com/docs/core/tokens#transfer-tokens) [Create Token Metadata](https://solana.com/docs/core/tokens#create-token-metadata) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/tokens/index.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter Tokens on Solana | Solana --- # Instructions | Solana [Solana Documentation](https://solana.com/docs) [Core Concepts](https://solana.com/docs/core) [Instructions](https://solana.com/docs/core/instructions) ========================================================== Copy MarkdownOpen Instructions are the fundamental building block for interacting with the Solana blockchain. An instruction is essentially a public function that anyone using the Solana network can call. Each instruction is used to perform a specific action. The execution logic for instructions are stored on [programs](https://solana.com/docs/core/programs) , where each program defines its own set of instructions. To interact with the Solana network, one or more instructions are added to a [transaction](https://solana.com/docs/core/transactions) and sent to the network to be processed. [SOL transfer example](https://solana.com/docs/core/instructions#sol-transfer-example) --------------------------------------------------------------------------------------- The diagram below shows how transactions and instructions work together to allow users to interact with the network. In this example, SOL is transferred from one account to another. The sender account's [metadata](https://solana.com/docs/core/instructions#account-metadata) indicates that it must sign for the transaction. (This allows the System Program to deduct [lamports](https://solana.com/docs/references/terminology#lamport) .) Both the sender and recipient accounts must be writable, in order for their lamport balance to change. To execute this instruction, the sender's wallet sends the transaction containing its [signature](https://solana.com/docs/references/terminology#signature) and the message containing the SOL transfer instruction. ![SOL transfer diagram](https://solana.com/assets/docs/core/transactions/sol-transfer.svg)SOL transfer diagram After the transaction is sent, the System Program processes the transfer instruction and updates the lamport balance of both accounts. ![SOL transfer process diagram](https://solana.com/assets/docs/core/transactions/sol-transfer-process.svg)SOL transfer process diagram The example below shows the code relevant to the above diagrams. (See the System Program's transfer [instruction](https://github.com/anza-xyz/agave/blob/v2.1.13/programs/system/src/system_processor.rs#L183) .) Kit Legacy Rust import { airdropFactory, appendTransactionMessageInstructions, createSolanaRpc, createSolanaRpcSubscriptions, createTransactionMessage, generateKeyPairSigner, getSignatureFromTransaction, lamports, pipe, sendAndConfirmTransactionFactory, setTransactionMessageFeePayerSigner, setTransactionMessageLifetimeUsingBlockhash, signTransactionMessageWithSigners } from "@solana/kit"; import { getTransferSolInstruction } from "@solana-program/system"; // Create a connection to cluster const rpc \= createSolanaRpc("http://localhost:8899"); const rpcSubscriptions \= createSolanaRpcSubscriptions("ws://localhost:8900"); // Generate sender and recipient keypairs const sender \= await generateKeyPairSigner(); const recipient \= await generateKeyPairSigner(); const LAMPORTS\_PER\_SOL \= 1\_000\_000\_000n; const transferAmount \= lamports(LAMPORTS\_PER\_SOL / 100n); // 0.01 SOL // Fund sender with airdrop await airdropFactory({ rpc, rpcSubscriptions })({ recipientAddress: sender.address, lamports: lamports(LAMPORTS\_PER\_SOL), // 1 SOL commitment: "confirmed" }); // Check balance before transfer const { value: preBalance1 } \= await rpc.getBalance(sender.address).send(); const { value: preBalance2 } \= await rpc.getBalance(recipient.address).send(); // Create a transfer instruction for transferring SOL from sender to recipient const transferInstruction \= getTransferSolInstruction({ source: sender, destination: recipient.address, amount: transferAmount // 0.01 SOL in lamports }); // Add the transfer instruction to a new transaction const { value: latestBlockhash } \= await rpc.getLatestBlockhash().send(); const transactionMessage \= pipe( createTransactionMessage({ version: 0 }), (tx) \=> setTransactionMessageFeePayerSigner(sender, tx), (tx) \=> setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx), (tx) \=> appendTransactionMessageInstructions(\[transferInstruction\], tx) ); // Send the transaction to the network const signedTransaction \= await signTransactionMessageWithSigners(transactionMessage); await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })( signedTransaction, { commitment: "confirmed" } ); const transactionSignature \= getSignatureFromTransaction(signedTransaction); // Check balance after transfer const { value: postBalance1 } \= await rpc.getBalance(sender.address).send(); const { value: postBalance2 } \= await rpc.getBalance(recipient.address).send(); console.log( "Sender prebalance:", Number(preBalance1) / Number(LAMPORTS\_PER\_SOL) ); console.log( "Recipient prebalance:", Number(preBalance2) / Number(LAMPORTS\_PER\_SOL) ); console.log( "Sender postbalance:", Number(postBalance1) / Number(LAMPORTS\_PER\_SOL) ); console.log( "Recipient postbalance:", Number(postBalance2) / Number(LAMPORTS\_PER\_SOL) ); console.log("Transaction Signature:", transactionSignature); Console RunClick to execute the code. Kit Legacy Rust import { airdropFactory, appendTransactionMessageInstructions, createSolanaRpc, createSolanaRpcSubscriptions, createTransactionMessage, generateKeyPairSigner, getSignatureFromTransaction, lamports, pipe, sendAndConfirmTransactionFactory, setTransactionMessageFeePayerSigner, setTransactionMessageLifetimeUsingBlockhash, signTransactionMessageWithSigners } from "@solana/kit"; import { getTransferSolInstruction } from "@solana-program/system"; // Create a connection to cluster const rpc \= createSolanaRpc("http://localhost:8899"); const rpcSubscriptions \= createSolanaRpcSubscriptions("ws://localhost:8900"); // Generate sender and recipient keypairs const sender \= await generateKeyPairSigner(); const recipient \= await generateKeyPairSigner(); const LAMPORTS\_PER\_SOL \= 1\_000\_000\_000n; const transferAmount \= lamports(LAMPORTS\_PER\_SOL / 100n); // 0.01 SOL // Fund sender with airdrop await airdropFactory({ rpc, rpcSubscriptions })({ recipientAddress: sender.address, lamports: lamports(LAMPORTS\_PER\_SOL), // 1 SOL commitment: "confirmed" }); // Check balance before transfer const { value: preBalance1 } \= await rpc.getBalance(sender.address).send(); const { value: preBalance2 } \= await rpc.getBalance(recipient.address).send(); // Create a transfer instruction for transferring SOL from sender to recipient const transferInstruction \= getTransferSolInstruction({ source: sender, destination: recipient.address, amount: transferAmount // 0.01 SOL in lamports }); // Add the transfer instruction to a new transaction const { value: latestBlockhash } \= await rpc.getLatestBlockhash().send(); const transactionMessage \= pipe( createTransactionMessage({ version: 0 }), (tx) \=> setTransactionMessageFeePayerSigner(sender, tx), (tx) \=> setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx), (tx) \=> appendTransactionMessageInstructions(\[transferInstruction\], tx) ); // Send the transaction to the network const signedTransaction \= await signTransactionMessageWithSigners(transactionMessage); await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })( signedTransaction, { commitment: "confirmed" } ); const transactionSignature \= getSignatureFromTransaction(signedTransaction); // Check balance after transfer const { value: postBalance1 } \= await rpc.getBalance(sender.address).send(); const { value: postBalance2 } \= await rpc.getBalance(recipient.address).send(); console.log( "Sender prebalance:", Number(preBalance1) / Number(LAMPORTS\_PER\_SOL) ); console.log( "Recipient prebalance:", Number(preBalance2) / Number(LAMPORTS\_PER\_SOL) ); console.log( "Sender postbalance:", Number(postBalance1) / Number(LAMPORTS\_PER\_SOL) ); console.log( "Recipient postbalance:", Number(postBalance2) / Number(LAMPORTS\_PER\_SOL) ); console.log("Transaction Signature:", transactionSignature); Console RunClick to execute the code. [Instructions](https://solana.com/docs/core/instructions#instructions) ----------------------------------------------------------------------- ![Diagram depicting a transaction with an instruction, broken up into its 3 components](https://solana.com/assets/docs/core/transactions/instruction.svg)Diagram depicting a transaction with an instruction, broken up into its 3 components An [`Instruction`](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/instruction/src/lib.rs#L94) consists of the following information: * `program_id`: The [ID](https://solana.com/docs/core/instructions#program-id) of the program being invoked. * `accounts`: An array of [account metadata](https://solana.com/docs/core/instructions#account-metadata) * `data`: A byte array with additional \[data\] to be used by the instruction. Instruction struct pub struct Instruction { /// Pubkey of the program that executes this instruction. pub program\_id: Pubkey, /// Metadata describing accounts that should be passed to the program. pub accounts: Vec, /// Opaque data passed to the program for its own interpretation. pub data: Vec, } ### [Program ID](https://solana.com/docs/core/instructions#program-id) The instruction's [`program_id`](https://solana.com/docs/references/terminology#program-id) is the public key address of the program that contains the instruction's business logic. ### [Account metadata](https://solana.com/docs/core/instructions#account-metadata) The instruction's `accounts` array is an array of [`AccountMeta`](https://github.com/anza-xyz/agave/blob/v2.1.13/sdk/instruction/src/account_meta.rs#L25) structs. Metadata must be provided for each account the instruction interacts with. (This allows transaction to execute instructions in parallel, as long as they do not modify the same account.) The diagram below depicts a transaction that contains a single instruction. The instruction's `accounts` array contains metadata for two accounts. ![A transaction with one instruction. The instruction contains two AccountMeta structs in its accounts array.](https://solana.com/assets/docs/core/transactions/accountmeta.svg)A transaction with one instruction. The instruction contains two AccountMeta structs in its accounts array. The account metadata includes the following information: * pubkey: The account's public key address * is\_signer: Set to `true` if the account must sign the transaction * is\_writable: Set to `true` if the instruction modifies the account's data To know which accounts an instruction requires, including which must be writable, read-only, or sign the transaction, you must refer to the implementation of the instruction, as defined by the program. AccountMeta pub struct AccountMeta { /// An account's public key. pub pubkey: Pubkey, /// True if an \`Instruction\` requires a \`Transaction\` signature matching \`pubkey\`. pub is\_signer: bool, /// True if the account data or metadata may be mutated during program execution. pub is\_writable: bool, } ### [Data](https://solana.com/docs/core/instructions#data) The instruction's `data` is a byte array that specifies which of the program's instruction to invoke. It also includes any arguments required by the instruction. [Create instruction example](https://solana.com/docs/core/instructions#create-instruction-example) --------------------------------------------------------------------------------------------------- The example below shows the structure of a SOL transfer instruction. Kit Legacy Rust import { generateKeyPairSigner, lamports } from "@solana/kit"; import { getTransferSolInstruction } from "@solana-program/system"; // Generate sender and recipient keypairs const sender \= await generateKeyPairSigner(); const recipient \= await generateKeyPairSigner(); // Define the amount to transfer const LAMPORTS\_PER\_SOL \= 1\_000\_000\_000n; const transferAmount \= lamports(LAMPORTS\_PER\_SOL / 100n); // 0.01 SOL // Create a transfer instruction for transferring SOL from sender to recipient const transferInstruction \= getTransferSolInstruction({ source: sender, destination: recipient.address, amount: transferAmount }); console.log(JSON.stringify(transferInstruction, null, 2)); Console RunClick to execute the code. Kit Legacy Rust import { generateKeyPairSigner, lamports } from "@solana/kit"; import { getTransferSolInstruction } from "@solana-program/system"; // Generate sender and recipient keypairs const sender \= await generateKeyPairSigner(); const recipient \= await generateKeyPairSigner(); // Define the amount to transfer const LAMPORTS\_PER\_SOL \= 1\_000\_000\_000n; const transferAmount \= lamports(LAMPORTS\_PER\_SOL / 100n); // 0.01 SOL // Create a transfer instruction for transferring SOL from sender to recipient const transferInstruction \= getTransferSolInstruction({ source: sender, destination: recipient.address, amount: transferAmount }); console.log(JSON.stringify(transferInstruction, null, 2)); Console RunClick to execute the code. The code below shows the output from the previous code snippets. The format will differ between SDKs, but notice that each instruction contains the same three pieces of required information: `program_id`, `accounts`, `data`. Kit Legacy Rust { "accounts": \[\ \ {\ \ "address": "Hu28vRMGWpQXN56eaE7jRiDDRRz3vCXEs7EKHRfL6bC",\ \ "role": 3,\ \ "signer": {\ \ "address": "Hu28vRMGWpQXN56eaE7jRiDDRRz3vCXEs7EKHRfL6bC",\ \ "keyPair": {\ \ "privateKey": {},\ \ "publicKey": {}\ \ }\ \ }\ \ },\ \ {\ \ "address": "2mBY6CTgeyJNJDzo6d2Umipw2aGUquUA7hLdFttNEj7p",\ \ "role": 1\ \ }\ \ \], "programAddress": "11111111111111111111111111111111", "data": { "0": 2, "1": 0, "2": 0, "3": 0, "4": 128, "5": 150, "6": 152, "7": 0, "8": 0, "9": 0, "10": 0, "11": 0 } } The examples below show how to manually build the transfer instruction. (The `Expanded Instruction` tab is functionally equivalent to the `Instruction` tab.) In practice, you usually don’t have to construct an `Instruction` manually. Most programs provide client libraries with helper functions that create the instructions for you. If a library isn't available, you can manually build the instruction. KitLegacyRust Instruction Expanded Instruction const transferAmount \= 0.01; // 0.01 SOL const transferInstruction \= getTransferSolInstruction({ source: sender, destination: recipient.address, amount: transferAmount \* LAMPORTS\_PER\_SOL }); Is this page helpful? [Previous\ \ Accounts](https://solana.com/docs/core/accounts) [Next\ \ Transactions](https://solana.com/docs/core/transactions) ### Table of Contents [SOL transfer example](https://solana.com/docs/core/instructions#sol-transfer-example) [Instructions](https://solana.com/docs/core/instructions#instructions) [Program ID](https://solana.com/docs/core/instructions#program-id) [Account metadata](https://solana.com/docs/core/instructions#account-metadata) [Data](https://solana.com/docs/core/instructions#data) [Create instruction example](https://solana.com/docs/core/instructions#create-instruction-example) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/core/instructions.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter Instructions | Solana --- # Cross Program Invocation | Solana [Solana Documentation](https://solana.com/docs) Getting Started[Quick Start](https://solana.com/docs/intro/quick-start) [Cross Program Invocation](https://solana.com/docs/intro/quick-start/cross-program-invocation) =============================================================================================== Copy MarkdownOpen In this section, the CRUD program from the previous PDA section gets updated by adding Cross Program Invocations (CPIs), a feature that enables Solana programs to invoke each other. This tutorial also shows how programs can "sign" for Program Derived Addresses (PDAs) when making Cross Program Invocations. The `update` and `delete` instructions need modification to handle SOL transfers between accounts by invoking the System Program. The purpose of this section includes walking through the process of implementing CPIs in a Solana program using the Anchor framework, building upon the PDA concepts explored in the previous section. For more details, refer to the [Cross Program Invocation](https://solana.com/docs/core/cpi) page. For reference, this link includes the [final code](https://beta.solpg.io/668304cfcffcf4b13384d20a) after completing both the PDA and CPI sections. The [starter code](https://beta.solpg.io/679d75eecffcf4b13384d604) for this section includes just the PDA section completed. ### [Update the Update Instruction](https://solana.com/docs/intro/quick-start/cross-program-invocation#update-the-update-instruction) First, the program needs a simple "pay-to-update" mechanism by changing the `Update` struct and `update` function. Begin by updating the `lib.rs` file to bring into scope items from the `system_program` module. lib.rs use anchor\_lang::system\_program::{transfer, Transfer}; ### Diff Next, update the `Update` struct to include a new account called `vault_account`. This account, controlled by the program, receives SOL from a user when they update their message account. lib.rs #\[account(\ \ mut,\ \ seeds \= \[b"vault", user.key().as\_ref()\],\ \ bump,\ \ )\] pub vault\_account: SystemAccount<'info\>, ### Diff ### Explanation Next, add the CPI logic in the `update` instruction to transfer 0.001 SOL from the user's account to the vault account. lib.rs let transfer\_accounts \= Transfer { from: ctx.accounts.user.to\_account\_info(), to: ctx.accounts.vault\_account.to\_account\_info(), }; let cpi\_context \= CpiContext::new( ctx.accounts.system\_program.to\_account\_info(), transfer\_accounts, ); transfer(cpi\_context, 1\_000\_000)?; ### Diff ### Explanation Rebuild the program. Terminal $ build Copy ### [Update the Delete Instruction](https://solana.com/docs/intro/quick-start/cross-program-invocation#update-the-delete-instruction) Now add a "refund on delete" mechanism by changing the `Delete` struct and `delete` function. First, update the `Delete` struct to include the `vault_account`. This allows the transfer of any SOL in the vault back to the user when they close their message account. lib.rs #\[account(\ \ mut,\ \ seeds \= \[b"vault", user.key().as\_ref()\],\ \ bump,\ \ )\] pub vault\_account: SystemAccount<'info\>, Also add the `system_program` as the CPI for the transfer requires invoking the System Program. lib.rs pub system\_program: Program<'info, System\>, ### Diff ### Explanation Next, add the CPI logic in the `delete` instruction to transfer SOL from the vault account back to the user's account. lib.rs let user\_key \= ctx.accounts.user.key(); let signer\_seeds: &\[&\[&\[u8\]\]\] \= &\[&\[b"vault", user\_key.as\_ref(), &\[ctx.bumps.vault\_account\]\]\]; let transfer\_accounts \= Transfer { from: ctx.accounts.vault\_account.to\_account\_info(), to: ctx.accounts.user.to\_account\_info(), }; let cpi\_context \= CpiContext::new( ctx.accounts.system\_program.to\_account\_info(), transfer\_accounts, ).with\_signer(signer\_seeds); transfer(cpi\_context, ctx.accounts.vault\_account.lamports())?; Note that `_ctx: Context` changes to `ctx: Context` to use the context in the body of the function. ### Diff ### Explanation Rebuild the program. Terminal $ build Copy ### [Redeploy Program](https://solana.com/docs/intro/quick-start/cross-program-invocation#redeploy-program) After making these changes, redeploy the updated program. This ensures the modified program becomes available for testing. On Solana, updating a program simply requires deploying the program at the same program ID. Ensure your Playground wallet has devnet SOL. Get devnet SOL from the [Solana Faucet](https://faucet.solana.com/) . Terminal $ deploy Copy \[show output\] ### Explanation ### [Update Test File](https://solana.com/docs/intro/quick-start/cross-program-invocation#update-test-file) Next, update the `anchor.test.ts` file to include the new vault account in the instructions. This requires deriving the vault PDA and including it in the update and delete instruction calls. #### [Derive Vault PDA](https://solana.com/docs/intro/quick-start/cross-program-invocation#derive-vault-pda) First, add the vault PDA derivation: anchor.test.ts const \[vaultPda, vaultBump\] \= PublicKey.findProgramAddressSync( \[Buffer.from("vault"), wallet.publicKey.toBuffer()\], program.programId ); ### Diff #### [Change Update Test](https://solana.com/docs/intro/quick-start/cross-program-invocation#change-update-test) Then, update the update instruction to include the `vaultAccount` anchor.test.ts const transactionSignature \= await program.methods .update(message) .accounts({ messageAccount: messagePda, vaultAccount: vaultPda }) .rpc({ commitment: "confirmed" }); ### Diff #### [Change Delete Test](https://solana.com/docs/intro/quick-start/cross-program-invocation#change-delete-test) Then, update the delete instruction to include the `vaultAccount` anchor.test.ts const transactionSignature \= await program.methods .delete() .accounts({ messageAccount: messagePda, vaultAccount: vaultPda }) .rpc({ commitment: "confirmed" }); ### Diff ### [Rerun Test](https://solana.com/docs/intro/quick-start/cross-program-invocation#rerun-test) After making these changes, run the tests to ensure everything works as expected: Terminal $ test Copy \[show output\] You can then inspect the SolanaFM links to view the transaction details, where you'll find the CPIs for the transfer instructions within the update and delete instructions. ![Update CPI](https://solana.com/assets/docs/intro/quickstart/cpi-update.png)Update CPI ![Delete CPI](https://solana.com/assets/docs/intro/quickstart/cpi-delete.png)Delete CPI If you encounter any errors, you can reference the [final code](https://beta.solpg.io/668304cfcffcf4b13384d20a) . [Next Steps](https://solana.com/docs/intro/quick-start/cross-program-invocation#next-steps) -------------------------------------------------------------------------------------------- Congratulations on completing the Solana Quickstart guide. You've gained hands-on experience with key Solana concepts including: * Fetching and reading data from accounts * Building and sending transactions * Deploying and updating Solana programs * Working with Program Derived Addresses (PDAs) * Making Cross-Program Invocations (CPIs) To deepen your understanding of these concepts, check out the [Core Concepts](https://solana.com/docs/core/accounts) documentation which provides detailed explanations of the topics covered in this guide. ### [Explore More Examples](https://solana.com/docs/intro/quick-start/cross-program-invocation#explore-more-examples) If you prefer learning by example, check out the [Program Examples Repository](https://github.com/solana-developers/program-examples) for a variety of example programs. Solana Playground offers a convenient feature allowing you to import or view projects using their GitHub links. For example, open this [Solana Playground link](https://beta.solpg.io/https://github.com/solana-developers/program-examples/tree/main/basics/hello-solana/anchor) to view the Anchor project from this [Github repo](https://github.com/solana-developers/program-examples/tree/main/basics/hello-solana/anchor) . Click the `Import` button and enter a project name to add it to your list of projects in Solana Playground. Once a project gets imported, all changes receive automatic saving and persistence. Is this page helpful? [Previous\ \ Creating Deterministic Accounts](https://solana.com/docs/intro/quick-start/program-derived-address) [Next\ \ Core Concepts](https://solana.com/docs/core) ### Table of Contents [Update the Update Instruction](https://solana.com/docs/intro/quick-start/cross-program-invocation#update-the-update-instruction) [Update the Delete Instruction](https://solana.com/docs/intro/quick-start/cross-program-invocation#update-the-delete-instruction) [Redeploy Program](https://solana.com/docs/intro/quick-start/cross-program-invocation#redeploy-program) [Update Test File](https://solana.com/docs/intro/quick-start/cross-program-invocation#update-test-file) [Derive Vault PDA](https://solana.com/docs/intro/quick-start/cross-program-invocation#derive-vault-pda) [Change Update Test](https://solana.com/docs/intro/quick-start/cross-program-invocation#change-update-test) [Change Delete Test](https://solana.com/docs/intro/quick-start/cross-program-invocation#change-delete-test) [Rerun Test](https://solana.com/docs/intro/quick-start/cross-program-invocation#rerun-test) [Next Steps](https://solana.com/docs/intro/quick-start/cross-program-invocation#next-steps) [Explore More Examples](https://solana.com/docs/intro/quick-start/cross-program-invocation#explore-more-examples) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/intro/quick-start/cross-program-invocation.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter --- # Staking on Solana | Solana [Solana Documentation](https://solana.com/docs) References [Staking on Solana](https://solana.com/docs/references/staking) ================================================================ Copy MarkdownOpen _Note before reading: All references to increases in values are in absolute terms with regards to balance of SOL. This document makes no suggestion as to the monetary value of SOL at any time._ By staking your SOL tokens, you help secure the network and [earn rewards](https://docs.anza.xyz/implemented-proposals/staking-rewards) while doing so. You can stake by delegating your tokens to validators who process transactions and run the network. Delegating stake is a shared-risk shared-reward financial model that may provide returns to holders of tokens delegated for a long period. This is achieved by aligning the financial incentives of the token-holders (delegators) and the validators to whom they delegate. The more stake delegated to a validator, the more often this validator is chosen to write new transactions to the ledger. The more transactions the validator writes, the more rewards the validator and its delegators earn. Validators who configure their systems to be able to process more transactions earn proportionally more rewards and because they keep the network running as fast and as smoothly as possible. Validators incur costs by running and maintaining their systems, and this is passed on to delegators in the form of a fee collected as a percentage of rewards earned. This fee is known as a _commission_. Since validators earn more rewards the more stake is delegated to them, they may compete with one another to offer the lowest commission for their services. Although this is not implemented in the Solana protocol today, in the future, delegators could risk losing tokens when staking through a process known as _slashing_. Slashing involves the removal and destruction of a portion of a validator's SOL in response to intentional malicious behavior, such as creating invalid transactions or censoring certain types of transactions or network participants. There is no in protocol implementation of slashing currently. For more information on slashing see the [slashing roadmap](https://docs.anza.xyz/proposals/optimistic-confirmation-and-slashing#slashing-roadmap) . [How do I stake my SOL tokens?](https://solana.com/docs/references/staking#how-do-i-stake-my-sol-tokens) --------------------------------------------------------------------------------------------------------- You can stake SOL by moving your tokens into a wallet that supports staking. The wallet provides steps to create a stake account and do the delegation. ### [Supported Wallets](https://solana.com/docs/references/staking#supported-wallets) Many web and mobile wallets support Solana staking operations. Please check with your favorite wallet's maintainers regarding status ### [Solana command line tools](https://solana.com/docs/references/staking#solana-command-line-tools) * Solana command line tools can perform all stake operations in conjunction with a CLI-generated keypair file wallet, a paper wallet, or with a connected Ledger Nano. [Staking commands using the Solana Command Line Tools](https://docs.anza.xyz/cli/examples/delegate-stake) . ### [Create a Stake Account](https://solana.com/docs/references/staking#create-a-stake-account) Follow the wallet's instructions for creating a staking account. This account will be of a different type than one used to simply send and receive tokens. ### [Select a Validator](https://solana.com/docs/references/staking#select-a-validator) Follow the wallet's instructions for selecting a validator. You can get information about potentially performant validators from the links below. The Solana Foundation does not recommend any particular validator. The site solanabeach.io is built and maintained by one of our validators, Staking Facilities. It provides a some high-level graphical information about the network as a whole, as well as a list of each validator and some recent performance statistics about each one. * [https://solanabeach.io](https://solanabeach.io/) To view block production statistics, use the Solana command-line tools: * `solana validators` * `solana block-production` The Solana team does not make recommendations on how to interpret this information. Do your own due diligence. ### [Delegate your Stake](https://solana.com/docs/references/staking#delegate-your-stake) Follow the wallet's instructions for delegating your stake to your chosen validator. Is this page helpful? [Previous\ \ RPC Endpoints](https://solana.com/docs/references/clusters) [Next\ \ Stake Accounts](https://solana.com/docs/references/staking/stake-accounts) ### Table of Contents [How do I stake my SOL tokens?](https://solana.com/docs/references/staking#how-do-i-stake-my-sol-tokens) [Supported Wallets](https://solana.com/docs/references/staking#supported-wallets) [Solana command line tools](https://solana.com/docs/references/staking#solana-command-line-tools) [Create a Stake Account](https://solana.com/docs/references/staking#create-a-stake-account) [Select a Validator](https://solana.com/docs/references/staking#select-a-validator) [Delegate your Stake](https://solana.com/docs/references/staking#delegate-your-stake) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/references/staking/index.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter --- # Solana Gaming SDKs | Solana [Solana Documentation](https://solana.com/docs) Solana SDKsCommunity SDKs [Solana Gaming SDKs](https://solana.com/docs/clients/community/game-sdks) ========================================================================== Copy MarkdownOpen With Solana being a high performance blockchain with low fees and fast transactions, a great game developer community has formed around it. Here you can find details about the Solana game development SDKs available within the ecosystem. All the SDKs are open source and community built. If you are working on a SDK yourself feel free to open a PR to this page and add it. [Unity SDK](https://solana.com/docs/clients/community/game-sdks#unity-sdk) --------------------------------------------------------------------------- The Unity game engine is known for its beginner friendly approach and cross platform support including WebGL, iOS, and Android. Build once, export everywhere. * [Docs](https://docs.magicblock.gg/introduction) * [Source](https://github.com/magicblock-labs/Solana.Unity-SDK) * [Example Games](https://github.com/solana-developers/solana-game-examples) * [Tic Tac Toe](https://blog.magicblock.gg/bolt-tic-tac-toe/) The Solana Unity SDK is maintained by [Magicblock](https://www.magicblock.gg/) and comes with: * NFT support * Candy machine integration * Transactions * RPC functions * Phantom deep links * WebGL connector * Reliable WebSocket connection support * Mobile wallet-adapter * Sessions keys for auto approving transaction * Anchor client code generation and more. [Godot SDK](https://solana.com/docs/clients/community/game-sdks#godot-sdk) --------------------------------------------------------------------------- The [Godot Engine](https://godotengine.org/) is an open source game engine which gained lots of support in the last few years. The Solana SDK for Godot is maintained by [ZenRepublic](https://twitter.com/ZenRepublicNDM) and [Virus-Axel](https://twitter.com/AxelBenjam) . It comes with a wallet adapter integration, transactions, RPC functions, and Anchor client code generation. Even a fully functional Metaplex [candy machine integration](https://zenwiki.gitbook.io/solana-godot-sdk-docs/guides/setup-candy-machine) . * [Solana Godot Engine SDK](https://github.com/Virus-Axel/godot-solana-sdk) * [Docs](https://zenwiki.gitbook.io/solana-godot-sdk-docs) * [Demo](https://github.com/ZenRepublic/GodotSolanaSDKDemoPackage) * [Tutorial](https://www.youtube.com/watch?v=tszFPInYmXQ) * [Maintainer](https://twitter.com/ZenRepublicNDM) [Turbo.Computer - Rust Game Engine](https://solana.com/docs/clients/community/game-sdks#turbocomputer---rust-game-engine) -------------------------------------------------------------------------------------------------------------------------- Turbo is a rust game engine written from the ground up to focus on Solana, with a lightweight architecture and fast iteration times. It is beginner friendly and comes with full Solana RPC support. You can even use its AI tools to generate complete games. * [Website](https://turbo.computer/) * [Docs](https://docs.turbo.computer/) * [Twitter account](https://twitter.com/makegamesfast) * [Maintainer](https://twitter.com/jozanza) [Honeycomb Protocol](https://solana.com/docs/clients/community/game-sdks#honeycomb-protocol) ============================================================================================= Honeycomb provides a suite of onchain programs and state-compression tools that handle all crucial game lifecycle functions and composability within the Solana Virtual Machine (SVM). It supports lots of NFT functionality like staking, missions, loot boxes, player profiles, state compression, auto approving transactions and more. * [Twitter account](https://twitter.com/honeycomb_prtcl) * [Docs](https://docs.honeycombprotocol.com/) [Unreal SDKs](https://solana.com/docs/clients/community/game-sdks#unreal-sdks) =============================================================================== Unreal Engine is known for its great visuals and node based scripting framework. There are multiple Solana SDKs maintained by different companies. ### [Varmeta Unreal SDK](https://solana.com/docs/clients/community/game-sdks#varmeta-unreal-sdk) VAR META provides an open-source Unreal SDK for integrating Solana blockchain functionality into Unreal Engine projects. It enables developers to interact with Solana's smart contracts, manage wallets, and execute transactions directly within Unreal Engine. * [Unreal SDK by Varmeta](https://github.com/VAR-META-Tech/UnrealSolanaSDK) * [Maintainer](https://www.var-meta.com/) ### [Bitfrost Unreal SDK](https://solana.com/docs/clients/community/game-sdks#bitfrost-unreal-sdk) Bitfrost is working on an Unreal SDK which was already used in multiple games built during recent Solana game jams. It comes with C# `solnet` support in C++ and Blueprints, minting of metaplex NFTs, payment processor examples in game wallet and more. * [Solana Unreal SDK by Bitfrost](https://github.com/Bifrost-Technologies/Solana-Unreal-SDK) * [Tutorial](https://www.youtube.com/watch?v=S8fm8mFeUkk) * [Maintainer](https://twitter.com/BifrostTitan) ### [Thugz Unreal SDK](https://solana.com/docs/clients/community/game-sdks#thugz-unreal-sdk) Thugz is a tech studio and NFT project which is also maintaining on open source an Unreal SDK for Solana. It comes with lots of NFT focused functionality and the plugin is compatible with iOS and Android too. * [Thugz Blockchain plugin](https://www.fab.com/listings/a7e220ba-93e5-4a3b-99e7-17b13da76f05) * [Repository](https://github.com/ThugzLabs/Thugz-BC-Plugin-Packaged-for-UE5.4) * [Documentation](https://thugzblockchainplugin-docs.vercel.app/) * [Video Tutorial](https://www.youtube.com/watch?v=dS7sTZd_E9U&ab_channel=ThugzNFT) ### [Star Atlas Foundation Kit](https://solana.com/docs/clients/community/game-sdks#star-atlas-foundation-kit) The [Star Atlas](https://staratlas.com/) team open sourced some of their SDK stack called _Foundation Kit_. It is not actively maintained but can be a starting point for your project. * [Star Atlas Unreal SDK](https://github.com/staratlasmeta/FoundationKit) * [Tutorial](https://www.youtube.com/watch?v=S8fm8mFeUkk) [Next.js/React + Anchor](https://solana.com/docs/clients/community/game-sdks#nextjsreact--anchor) -------------------------------------------------------------------------------------------------- One of the easiest way to build on Solana is using the Web3js JavaScript framework in combination with the Solana Anchor framework. For more complex games, we recommend looking into using a Game Engine like [Unity](https://solana.com/docs/clients/community/game-sdks#unity-sdk) or [Unreal](https://solana.com/docs/clients/community/game-sdks#unreal-sdks) though. The fastest way to set it up a Next.js based game: npx create-solana-game your-game-name This will generate a great starting application with `wallet-adapter` support, an Anchor program, a React app, and a Unity client already configured to work together. A benefit of using Next.js is that you can use the same code in the backend and in the frontend, speeding up development. * [Web3.js](https://solana.com/docs/clients/javascript) * [Video Tutorial](https://www.youtube.com/watch?v=fnhivg_pemI&t=1s&ab_channel=Solana) > If you are working on a Solana SDK and want to add your preset to the preset you can open a PR here: [Solana games preset](https://github.com/solana-developers/solana-game-preset) [Phaser](https://solana.com/docs/clients/community/game-sdks#phaser) --------------------------------------------------------------------- A fast, free, and fun open source framework for Canvas and WebGL powered browser based games. [Phaser](https://phaser.io/) is a great way to get started with game development on Solana. The Phaser Solana Platformer Template is a great starting point for your game. * [Source Code](https://github.com/Bread-Heads-NFT/solana-phaser-template) * [Maintainer](https://twitter.com/blockiosaurus) [Flutter](https://solana.com/docs/clients/community/game-sdks#flutter) ----------------------------------------------------------------------- Flutter is an open source framework, maintained by Google, for building beautiful, natively compiled, multi-platform applications from a single codebase. The Solana Flutter SDK is maintained by the [Espresso Cash](https://www.espressocash.com/) team. * [Source Code](https://github.com/espresso-cash/espresso-cash-public) [Python](https://solana.com/docs/clients/community/game-sdks#python) --------------------------------------------------------------------- Python is an easy to learn programming and widely used language (often used in machine learning applications). The Seahorse framework enables developers to write Solana programs in Python. Seahorse is built on top of the Anchor framework and converts Python code into Anchor based rust code. Seahorse is currently in beta. * [Documentation](https://www.seahorse.dev/) * [Github Repo](https://github.com/solana-developers/seahorse) * [Anchor Playground Example](https://beta.solpg.io/tutorials/hello-seahorse) [Native C#](https://solana.com/docs/clients/community/game-sdks#native-c) -------------------------------------------------------------------------- The original port of Web3js to C#. It comes with a bunch of functionality like transactions, RPC functions and Anchor client code generation. * [Source and Docs](https://github.com/bmresearch/Solnet/blob/master/docs/articles/getting_started.md) Is this page helpful? [Previous\ \ Go SDK](https://solana.com/docs/clients/community/go) [Next\ \ RPC Endpoints](https://solana.com/docs/references/clusters) ### Table of Contents [Unity SDK](https://solana.com/docs/clients/community/game-sdks#unity-sdk) [Godot SDK](https://solana.com/docs/clients/community/game-sdks#godot-sdk) [Turbo.Computer - Rust Game Engine](https://solana.com/docs/clients/community/game-sdks#turbocomputer---rust-game-engine) [Honeycomb Protocol](https://solana.com/docs/clients/community/game-sdks#honeycomb-protocol) [Unreal SDKs](https://solana.com/docs/clients/community/game-sdks#unreal-sdks) [Varmeta Unreal SDK](https://solana.com/docs/clients/community/game-sdks#varmeta-unreal-sdk) [Bitfrost Unreal SDK](https://solana.com/docs/clients/community/game-sdks#bitfrost-unreal-sdk) [Thugz Unreal SDK](https://solana.com/docs/clients/community/game-sdks#thugz-unreal-sdk) [Star Atlas Foundation Kit](https://solana.com/docs/clients/community/game-sdks#star-atlas-foundation-kit) [Next.js/React + Anchor](https://solana.com/docs/clients/community/game-sdks#nextjsreact--anchor) [Phaser](https://solana.com/docs/clients/community/game-sdks#phaser) [Flutter](https://solana.com/docs/clients/community/game-sdks#flutter) [Python](https://solana.com/docs/clients/community/game-sdks#python) [Native C#](https://solana.com/docs/clients/community/game-sdks#native-c) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/clients/community/game-sdks.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter --- # How Payments Work on Solana | Solana [Payments](https://solana.com/docs) [How Payments Work on Solana](https://solana.com/docs/payments/how-payments-work) ================================================================================== Copy MarkdownOpen Before building payment flows on Solana, you'll need to understand five core concepts: wallets, stablecoins, token accounts, fees, and transactions. Solana payments map cleanly to multi-currency payment systems: | Traditional Payment Model | Solana | Description | | --- | --- | --- | | Customer ID / Account number | Wallet address | Unique identifier for an account holder | | Currency (USD, EUR) | Token Mint (USDG, USDC) | The asset type being transferred | | Balance by currency | Token Account (ATA) | Holds a balance of a specific currency/mint | Just as a bank customer has a single identity but holds separate balances for each currency, a Solana wallet has one address but a distinct token account for each asset it holds. Let's break down each component. [Wallets: Senders and Receivers](https://solana.com/docs/payments/how-payments-work#wallets-senders-and-receivers) ------------------------------------------------------------------------------------------------------------------- Every payment involves two parties, each identified by a **wallet address**—a unique 32-byte public key (e.g., `7EcDhS...`). * **Sender**: The wallet initiating the payment. Must hold sufficient stablecoin account balance and sign the transaction. * **Receiver**: The destination wallet. Does not need to sign or hold an existing balance. * **Fee Payer**: The optional fee payer wallet. Can be used to subsidize or enable stablecoin-only transactions between users. Think of wallet addresses like bank account numbers: public, safe to share, and required to send or receive funds. [Stablecoins](https://solana.com/docs/payments/how-payments-work#stablecoins) ------------------------------------------------------------------------------ Stablecoins are referred to as "tokens" on Solana. Tokens represent an asset type on the network. Each token has a unique identifier called a "mint address". When building payment systems, you'll reference these mint addresses to identify the asset you are interacting with. Here are some common stablecoin mints on mainnet: | Token | Issuer | Mint Address | | --- | --- | --- | | USDC | Circle | `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v` | | USDT | Tether | `Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB` | | PYUSD | PayPal | `2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo` | | USDG | Paxos | `2u1tszSeqZ3qBWF3uNGPFc8TzMk2tdiwknnRMWGWjGWH` | For more information on stablecoins on Solana, see the [Stablecoins](https://solana.com/solutions/stablecoins) solution page. When accepting payments, always validate the mint address and token program. Tokens can share names but have different issuers and underlying assets. [Token Accounts](https://solana.com/docs/payments/how-payments-work#token-accounts) ------------------------------------------------------------------------------------ Wallets don't hold tokens directly. Instead, each wallet has authority over a **token account** for each type of token it holds. Payments are made by transferring tokens from a sender's token account to a receiver's token account of the same mint: ![Token Accounts](https://solana.com/assets/docs/payments/payment-flow.png)Token Accounts An **Associated Token Account** is a deterministic token account tied to a specific wallet and mint. Given a wallet address and mint, the ATA address is always the same. 1. **One ATA per mint**. A wallet has exactly one ATA for USDC, one for USDT, etc. 2. **Must exist before receiving**. You cannot send tokens to an ATA that doesn't exist. 3. **Sender typically creates**. If the receiver's ATA doesn't exist, the sender can create it as part of the payment transaction. import { findAssociatedTokenPda } from "@solana-program/token"; const \[receiverATA\] \= await findAssociatedTokenPda({ mint: USDG\_MINT\_ADDRESS, owner: receiverWallet.address, tokenProgram: TOKEN\_PROGRAM\_ADDRESS }); [Token Programs](https://solana.com/docs/payments/how-payments-work#token-programs) ------------------------------------------------------------------------------------ On Solana, programs are executable logic that govern account state. Token accounts are managed by a **Token Program**—the on-chain code that verifies transfers and updates balances atomically. Solana has two token programs: | Program | Address | Example Tokens that
use this program | | --- | --- | --- | | **Token Program** | `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA` | USDC, USDT | | **Token-2022** | `TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb` | PYUSD, USDG | Token-2022 (also called "Token Extensions") adds features like transfer hooks, transfer fees, and confidential transfers. Both programs work similarly for basic transfers, but you must use the correct one when deriving ATAs. ### [Why This Matters](https://solana.com/docs/payments/how-payments-work#why-this-matters) The Token Program used to create a token governs the instructions and account state for the token. If you use the wrong program, you will not be able to transfer the token. ATAs are derived from three inputs: `wallet + mint + token_program`. Using the wrong program produces an **entirely different address**: import { findAssociatedTokenPda, TOKEN\_PROGRAM\_ADDRESS } from "@solana-program/token"; import { TOKEN\_2022\_PROGRAM\_ADDRESS } from "@solana-program/token-2022"; // USDC uses Token Program const \[usdcAta\] \= await findAssociatedTokenPda({ mint: USDC\_MINT, owner: walletAddress, tokenProgram: TOKEN\_PROGRAM\_ADDRESS // ✓ Correct }); // ❌ This will produce a different address because it uses the wrong program const \[wrongUsdcAta\] \= await findAssociatedTokenPda({ mint: USDC\_MINT, owner: walletAddress, tokenProgram: TOKEN\_2022\_PROGRAM\_ADDRESS // ❌ Wrong program }); // PYUSD uses Token-2022 const \[pyusdAta\] \= await findAssociatedTokenPda({ mint: PYUSD\_MINT, owner: walletAddress, tokenProgram: TOKEN\_2022\_PROGRAM\_ADDRESS // ✓ Correct }); Deriving an ATA with the wrong program will produce an invalid address. Always match the program to the token's mint. The same principle applies to transfer instructions. Each token program has its own transfer instruction, and you must invoke the correct one: import { getTransferInstruction } from "@solana-program/token"; import { getTransferInstruction as getTransferInstruction22 } from "@solana-program/token-2022"; // For USDC (Token Program) const usdcTransferIx \= getTransferInstruction({ source: senderUsdcAta, destination: receiverUsdcAta, authority: senderWallet, amount: 1\_000\_000n // 1 USDC (6 decimals) }); // For PYUSD (Token-2022) const pyusdTransferIx \= getTransferInstruction22({ source: senderPyusdAta, destination: receiverPyusdAta, authority: senderWallet, amount: 1\_000\_000n // 1 PYUSD (6 decimals) }); // \*Note\*: Most token program JS Client functions include the ability // to specify the token program address. Generally, defining it is a // good practice to ensure you are fully aware of the program you are using const usdcTransferIx2 \= getTransferInstruction( { source: senderUsdcAta, destination: receiverUsdcAta, authority: senderWallet, amount: 1\_000\_000n // 1 USDC (6 decimals) }, { tokenProgram: TOKEN\_PROGRAM\_ADDRESS } ); Sending a transfer instruction to the wrong program will fail. The program validates that it owns the token accounts involved—accounts created by Token Program cannot be transferred via Token-2022, and vice versa. To verify which program a token or token account uses, fetch the mint or token account and check its `owner` field: import { createSolanaRpc, address } from "@solana/kit"; const rpc \= createSolanaRpc("https://api.mainnet-beta.solana.com"); const accountInfo \= await rpc.getAccountInfo(address(mintAddress)).send(); // The owner field tells you which program manages this token const tokenProgram \= accountInfo.value?.owner; // Returns: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA (Token Program) // or: TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb (Token-2022) For payment applications, store the correct program address alongside each supported token: const SUPPORTED\_TOKENS \= { USDC: { mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", program: TOKEN\_PROGRAM\_ADDRESS, decimals: 6 }, PYUSD: { mint: "2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo", program: TOKEN\_2022\_PROGRAM\_ADDRESS, decimals: 6 } }; ### [Token Extensions](https://solana.com/docs/payments/how-payments-work#token-extensions) The Token Extensions Program (Token 2022) provides more features through extra instructions referred to as extensions. Extensions are optional features you can add to a token mint or token account. For more information on Token Extensions, see the [Token Extensions](https://solana.com/docs/tokens/extensions) documentation. [Fees](https://solana.com/docs/payments/how-payments-work#fees) ---------------------------------------------------------------- Solana payments involve up to three cost components: | Fee Type | SOL | USD (est.) | When | | --- | --- | --- | --- | | **Base transaction fee** | 5,000 lamports\* | ~$0.0007 | Every transaction (bundle multiple payments to amortize) | | **Priority fee** | Variable | Variable | Optional; faster inclusion during congestion | | **Account creation (rent)** | ~0.0029 SOL | ~$0.40 | Only when creating a new token account | **Total cost per payment**: Under $0.001 for most transfers. If creating a new token account, expect ~$0.40 total. Solana uses [local fee markets](https://github.com/solana-foundation/solana-improvement-documents/pull/436) —each program's transactions compete only with other transactions targeting the same state. This means payment fees stay low and predictable even during periods of high network activity elsewhere. Rent costs are also [planned to decrease 50% in the near future](https://github.com/solana-foundation/solana-improvement-documents/pull/436) . You can abstract fees entirely so users never interact with SOL. See [Fee Abstraction](https://solana.com/docs/payments/send-payments/payment-processing/fee-abstraction) for implementation patterns. [Transactions and Instructions](https://solana.com/docs/payments/how-payments-work#transactions-and-instructions) ------------------------------------------------------------------------------------------------------------------ A transaction is the atomic unit of execution on Solana—either every operation succeeds, or none do. Each transaction contains one or more instructions, which are individual commands (e.g., "transfer 10 USDC," "create token account"). A typical payment transaction might include two instructions: create the receiver's token account (if needed), then transfer tokens. Both execute atomically—no partial states. As you will see in [Payment Processing](https://solana.com/docs/payments/send-payments/payment-processing) , you can bundle multiple payments into a single transaction to reduce costs and increase throughput. [Putting It Together](https://solana.com/docs/payments/how-payments-work#putting-it-together) ---------------------------------------------------------------------------------------------- A typical payment flow: 1. **Gather input**. Get sender and receiver wallet addresses and the mint address of the token being transferred. 2. **Derive ATAs**. Determine the token accounts for both parties. 3. **Build and sign**. Construct the transaction with necessary transfer instructions, sign with the sender's key. 4. **Send & Confirm**. Transaction settles in under a second. [Next Steps](https://solana.com/docs/payments/how-payments-work#next-steps) ---------------------------------------------------------------------------- [### Interacting with Solana\ \ Connect to the network and explore Solana payment data.](https://solana.com/docs/payments/interacting-with-solana) [### Send your first payment\ \ Build and send a stablecoin transfer.](https://solana.com/docs/payments/send-payments) \* a lamport is the smallest unit of SOL and is equal to 0.000000001 SOL Is this page helpful? [Next\ \ Interacting with Solana](https://solana.com/docs/payments/interacting-with-solana) ### Table of Contents [Wallets: Senders and Receivers](https://solana.com/docs/payments/how-payments-work#wallets-senders-and-receivers) [Stablecoins](https://solana.com/docs/payments/how-payments-work#stablecoins) [Token Accounts](https://solana.com/docs/payments/how-payments-work#token-accounts) [Token Programs](https://solana.com/docs/payments/how-payments-work#token-programs) [Why This Matters](https://solana.com/docs/payments/how-payments-work#why-this-matters) [Token Extensions](https://solana.com/docs/payments/how-payments-work#token-extensions) [Fees](https://solana.com/docs/payments/how-payments-work#fees) [Transactions and Instructions](https://solana.com/docs/payments/how-payments-work#transactions-and-instructions) [Putting It Together](https://solana.com/docs/payments/how-payments-work#putting-it-together) [Next Steps](https://solana.com/docs/payments/how-payments-work#next-steps) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/payments/how-payments-work.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter How Payments Work on Solana | Solana --- # Common JSON Data Structures for Solana RPC Methods | Solana [Solana Documentation](https://solana.com/docs) [Solana RPC Methods](https://solana.com/docs/rpc) [Common JSON Data Structures for Solana RPC Methods](https://solana.com/docs/rpc/json-structures) ================================================================================================== Copy MarkdownOpen Various Solana RPC methods will return more complex responses as structured JSON objects, filled with specific keyed values. The most common of these JSON data structures include: * [transactions](https://solana.com/docs/rpc/json-structures#transactions) * [inner instructions](https://solana.com/docs/rpc/json-structures#inner-instructions) * [token balances](https://solana.com/docs/rpc/json-structures#token-balances) [Transactions](https://solana.com/docs/rpc/json-structures#transactions) ------------------------------------------------------------------------- Transactions are quite different from those on other blockchains. Be sure to review [Anatomy of a Transaction](https://solana.com/docs/core/transactions) to learn about transactions on Solana. ### [JSON](https://solana.com/docs/rpc/json-structures#json) The JSON structure of a transaction is defined as follows: ### Reference * `message: ` - Defines the content of the transaction. * `accountKeys: ` - List of base-58 encoded public keys used by the transaction, including by the instructions and for signatures. The first `message.header.numRequiredSignatures` public keys must sign the transaction. * `header: ` - Details the account types and signatures required by the transaction. * `numRequiredSignatures: ` - The total number of signatures required to make the transaction valid. The signatures must match the first `numRequiredSignatures` of `message.accountKeys`. * `numReadonlySignedAccounts: ` - The last `numReadonlySignedAccounts` of the signed keys are read-only accounts. Programs may process multiple transactions that load read-only accounts within a single PoH entry, but are not permitted to credit or debit lamports or modify account data. Transactions targeting the same read-write account are evaluated sequentially. * `numReadonlyUnsignedAccounts: ` - The last `numReadonlyUnsignedAccounts` of the unsigned keys are read-only accounts. * `recentBlockhash: ` - A base-58 encoded hash of a recent block in the ledger used to prevent transaction duplication and to give transactions lifetimes. * `instructions: ` - List of program instructions that will be executed in sequence and committed in one atomic transaction if all succeed. * `programIdIndex: ` - Index into the `message.accountKeys` array indicating the program account that executes this instruction. * `accounts: ` - List of ordered indices into the `message.accountKeys` array indicating which accounts to pass to the program. * `data: ` - The program input data encoded in a base-58 string. * `addressTableLookups: ` - List of address table lookups used by a transaction to dynamically load addresses from on-chain address lookup tables. Undefined if `maxSupportedTransactionVersion` is not set. * `accountKey: ` - base-58 encoded public key for an address lookup table account. * `writableIndexes: ` - List of indices used to load addresses of writable accounts from a lookup table. * `readonlyIndexes: ` - List of indices used to load addresses of readonly accounts from a lookup table. * `signatures: ` - A list of base-58 encoded signatures applied to the transaction. The list is always of length `message.header.numRequiredSignatures` and not empty. The signature at index `i` corresponds to the public key at index `i` in `message.accountKeys`. The first one is used as the [transaction id](https://solana.com/docs/references/terminology#transaction-id) . ### [JSON Parsed](https://solana.com/docs/rpc/json-structures#json-parsed) The JSON parsed structure of a transaction follows a similar structure to the regular JSON format, with additional parsing of account and instruction information: ### Reference * `message: ` - Defines the content of the transaction. * `accountKeys: ` - List of account information used by the transaction. * `pubkey: ` - The base-58 encoded public key of the account. * `signer: ` - Indicates if the account is a required transaction signer. * `writable: ` - Indicates if the account is writable. * `source: ` - Source of the account (transaction or lookup table). * `recentBlockhash: ` - A base-58 encoded hash of a recent block in the ledger used to prevent transaction duplication and to give transactions lifetimes. * `instructions: ` - List of parsed program instructions. * `program: ` - The name of the program being called. * `programId: ` - The base-58 encoded public key of the program. * `stackHeight: ` - The stack height of the instruction. * `parsed: ` - Program-specific parsed data. * `type: ` - The type of instruction (e.g., "transfer"). * `info: ` - Parsed instruction information specific to the program and instruction type. * `signatures: ` - A list of base-58 encoded signatures applied to the transaction. [Transaction Status Metadata](https://solana.com/docs/rpc/json-structures#transaction-status-metadata) ------------------------------------------------------------------------------------------------------- ### Reference * `err: ` - Error if transaction failed, null if transaction succeeded. [TransactionError definitions](https://github.com/solana-labs/solana/blob/c0c60386544ec9a9ec7119229f37386d9f070523/sdk/src/transaction/error.rs#L13) * `fee: ` - fee this transaction was charged, as u64 integer * `preBalances: ` - array of u64 account balances from before the transaction was processed * `postBalances: ` - array of u64 account balances after the transaction was processed * `innerInstructions: ` - List of [inner instructions](https://solana.com/docs/rpc/json-structures#inner-instructions) or `null` if inner instruction recording was not enabled during this transaction * `preTokenBalances: ` - List of [token balances](https://solana.com/docs/rpc/json-structures#token-balances) from before the transaction was processed or omitted if token balance recording was not yet enabled during this transaction * `postTokenBalances: ` - List of [token balances](https://solana.com/docs/rpc/json-structures#token-balances) from after the transaction was processed or omitted if token balance recording was not yet enabled during this transaction * `logMessages: ` - array of string log messages or `null` if log message recording was not enabled during this transaction * `rewards: ` - transaction-level rewards; an array of JSON objects containing: * `pubkey: ` - The public key, as base-58 encoded string, of the account that received the reward * `lamports: `\- number of reward lamports credited or debited by the account, as a i64 * `postBalance: ` - account balance in lamports after the reward was applied * `rewardType: ` - type of reward: "fee", "rent", "voting", "staking" * `commission: ` - vote account commission when the reward was credited, only present for voting and staking rewards * DEPRECATED: `status: ` - Transaction status * `"Ok": ` - Transaction was successful * `"Err": ` - Transaction failed with TransactionError * `loadedAddresses: ` - Transaction addresses loaded from address lookup tables. Undefined if `maxSupportedTransactionVersion` is not set in request params, or if `jsonParsed` encoding is set in request params. * `writable: ` - Ordered list of base-58 encoded addresses for writable loaded accounts * `readonly: ` - Ordered list of base-58 encoded addresses for readonly loaded accounts * `returnData: ` - the most-recent return data generated by an instruction in the transaction, with the following fields: * `programId: ` - the program that generated the return data, as base-58 encoded Pubkey * `data: <[string, encoding]>` - the return data itself, as base-64 encoded binary data * `computeUnitsConsumed: ` - number of [compute units](https://solana.com/docs/core/fees#compute-budget) consumed by the transaction * `version: <"legacy"|number|undefined>` - Transaction version. Undefined if `maxSupportedTransactionVersion` is not set in request params. * `signatures: ` - present if "signatures" are requested for transaction details; an array of signatures strings, corresponding to the transaction order in the block [Inner Instructions](https://solana.com/docs/rpc/json-structures#inner-instructions) ------------------------------------------------------------------------------------- When an instruction in a transaction makes a [cross-program invocation](https://solana.com/docs/core/cpi) (CPI), the invoked instructions are detailed under `innerInstructions`. * `index: number` – Index of the instruction at `transaction.message.instructions[index]` that made the CPI. * `instructions: array[object]` – List of CPI instructions invoked by the instruction at `index`, encoded as Json or JsonParsed objects. ### [JSON Parsed](https://solana.com/docs/rpc/json-structures#json-parsed-1) * `program: string` – Name of the program the CPI is being made to. * `programId: string` – Program ID of the program the CPI is being made to. * `parsed` – Parser output when the program is recognized: * `type: string` – Instruction name identified by the parser. * `info: object` – Program specific data returned by the parser. * `stackHeight: number` – CPI depth. ### Reference ### [JSON](https://solana.com/docs/rpc/json-structures#json-1) * `programIdIndex: number` – Index into `transaction.message.accountKeys` of the Program ID for the program the CPI is being made to. * `accounts: array[number]` – Indexes into `transaction.message.accountKeys` for the accounts passed to the program the CPI is being made to. * `data: string` – Base58 encoded instruction data passed to the program the CPI is being made to. * `stackHeight: number` – Depth of the CPI call. ### Reference [Token Balances](https://solana.com/docs/rpc/json-structures#token-balances) ----------------------------------------------------------------------------- ### Reference The JSON structure of token balances is defined as a list of objects in the following structure: * `accountIndex: ` - Index of the account in which the token balance is provided for. * `mint: ` - Pubkey of the token's mint. * `owner: ` - Pubkey of token balance's owner. * `programId: ` - Pubkey of the Token program that owns the account. * `uiTokenAmount: ` - * `amount: ` - Raw amount of tokens as a string, ignoring decimals. * `decimals: ` - Number of decimals configured for token's mint. * `uiAmount: ` - Token amount as a float, accounting for decimals. **DEPRECATED** * `uiAmountString: ` - Token amount as a string, accounting for decimals. Is this page helpful? [Previous\ \ Solana RPC Methods](https://solana.com/docs/rpc) [Next\ \ HTTP Methods](https://solana.com/docs/rpc/http) ### Table of Contents [Transactions](https://solana.com/docs/rpc/json-structures#transactions) [JSON](https://solana.com/docs/rpc/json-structures#json) [JSON Parsed](https://solana.com/docs/rpc/json-structures#json-parsed) [Transaction Status Metadata](https://solana.com/docs/rpc/json-structures#transaction-status-metadata) [Inner Instructions](https://solana.com/docs/rpc/json-structures#inner-instructions) [JSON Parsed](https://solana.com/docs/rpc/json-structures#json-parsed-1) [JSON](https://solana.com/docs/rpc/json-structures#json-1) [Token Balances](https://solana.com/docs/rpc/json-structures#token-balances) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/rpc/json-structures.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter Common JSON Data Structures for Solana RPC Methods | Solana --- # Install the dependencies necessary to develop with Solana | Solana [Solana Documentation](https://solana.com/docs) Getting Started[Installation](https://solana.com/docs/intro/installation) [Install Dependencies](https://solana.com/docs/intro/installation/dependencies) ================================================================================ Copy MarkdownOpen A guide to setting up your local Solana development environment. Learn how to install Rust, the Solana CLI, and Anchor Framework on Windows (WSL), Linux, and Mac. Use this guide if you prefer to install each dependency individually, or if the [quick installation](https://solana.com/docs/intro/installation/) fails for any reason. ### [Prerequisites](https://solana.com/docs/intro/installation/dependencies#prerequisites) ### Windows ### Linux ### [Install Rust](https://solana.com/docs/intro/installation/dependencies#install-rust) Developers build Solana programs using the [Rust](https://www.rust-lang.org/) programming language. 1. Install Rust using [rustup](https://www.rust-lang.org/tools/install) by entering the following command in your terminal: Terminal $ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y Copy After a successful installation you will see the following message: ### Successful Rust Install Message 2. Reload your PATH environment variable to include [Cargo's](https://github.com/rust-lang/cargo) bin directory: Terminal $ . "$HOME/.cargo/env" Copy 3. Verify that the installation was successful. Terminal $ rustc --version Copy You will see output like the following: rustc 1.86.0 (05f9846f8 2025-03-31) ### [Install Solana CLI](https://solana.com/docs/intro/installation/dependencies#install-solana-cli) The Solana CLI provides all the tools required to build and deploy Solana programs. 1. Install the Solana CLI tool suite by using the official install command: Terminal $ sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)" Copy You can replace `stable` with the release tag matching the software version of your desired release (i.e. `v2.0.3`), or use one of the three symbolic channel names: `stable`, `beta`, or `edge`. 2. Add a PATH environment variable A first-time installation of the Solana CLI, may prompt you to add a `PATH` environment variable. To do so, close and reopen your terminal or run the following in your shell: export PATH="/Users/test/.local/share/solana/install/active\_release/bin:$PATH" 3. Update your PATH environment variable Windows & LinuxMac If you are using **Linux** or **WSL**, you must add the Solana CLI binary to your PATH so that the command is available in your terminal. To do so, follow the steps below: **a.** Check which shell you are using: Terminal $ echo $SHELL Copy * If the output contains `/bash`, use `.bashrc`. * If the output contains `/zsh`, use `.zshrc`. **b.** Run the appropriate command, based on your shell. For Bash (`bashrc`): Terminal $ echo 'export PATH="$HOME/.local/share/solana/install/active\_release/bin:$PATH"' >> ~/.bashrc Copy $ source ~/.bashrc Copy For Zsh (`zshrc`): Terminal $ echo 'export PATH="$HOME/.local/share/solana/install/active\_release/bin:$PATH"' >> ~/.zshrc Copy $ source ~/.zshrc Copy 4. Restart your terminal or run the following command to refresh the terminal session: Terminal $ source ~/.bashrc # If using Bash Copy $ source ~/.zshrc # If using Zsh Copy 5. Verify that the installation succeeded by checking the Solana CLI version: Terminal $ solana --version Copy You will see output like the following: solana-cli 2.2.12 (src:0315eb6a; feat:1522022101, client:Agave) You can view all available versions on the [Agave Github repo](https://github.com/anza-xyz/agave/releases) . Agave is the validator client from [Anza](https://www.anza.xyz/) , formerly known as Solana Labs validator client. 5. Update the Solana CLI to the latest version, as needed _(Optional)_ Terminal $ agave-install update Copy ### [Install Anchor CLI](https://solana.com/docs/intro/installation/dependencies#install-anchor-cli) [Anchor](https://www.anchor-lang.com/) is a framework for developing Solana programs. The Anchor framework leverages Rust macros to simplify the process of writing Solana programs. #### [Prerequisites](https://solana.com/docs/intro/installation/dependencies#prerequisites-1) The default Anchor project test file (TypeScript) created with the `anchor init` command requires Node.js and Yarn. (The Rust test template is available using `anchor init --test-template rust`) ### Node Installation ### Yarn Installation #### [Installation](https://solana.com/docs/intro/installation/dependencies#installation) You can install the Anchor CLI and tooling in two ways: * Anchor Version Manager (AVM) — Recommended installation method * Without AVM — Install directly from GitHub AVMWithout AVM The Anchor Version Manager (AVM) allows you to install and manage different Anchor versions on your system and easily update Anchor versions in the future. To install Anchor using AVM, follow the steps below: 1. Install AVM with the following command: Terminal $ cargo install --git https://github.com/solana-foundation/anchor avm --force Copy 2. Confirm that AVM installed successfully: Terminal $ avm --version Copy 3. Install Anchor CLI using AVM: To install the latest version: Terminal $ avm install latest Copy $ avm use latest Copy To install a specific version, specify the version number: Terminal $ avm install 0.30.1 Copy $ avm use 0.30.1 Copy When installing the Anchor CLI on Linux or WSL, you may encounter this error: error: could not exec the linker cc = note: Permission denied (os error 13) If you see this error message, follow these steps: 1. Install the dependencies listed in the [Linux](https://solana.com/docs/intro/installation#install-dependencies) section at the top of this page. 2. Retry installing the Anchor CLI. 4. Verify that the installation succeeded, by checking the Anchor CLI version: Terminal $ anchor --version Copy You will see output like the following: anchor-cli 0.31.1 Don't forget to run the `avm use` command to declare the Anchor CLI version to run on your system. * If you installed the `latest` version, run `avm use latest`. * If you installed the version `0.30.1`, run `avm use 0.30.1`. ### [Install Surfpool CLI](https://solana.com/docs/intro/installation/dependencies#install-surfpool-cli) [Surfpool](https://surfpool.run/) is a tool for local development and an improved replacement for `solana-test-validator`. Learn more about Surfpool features in the [Surfpool documentation](https://docs.surfpool.run/) . 1. Install Surfpool with the following command: Terminal $ curl -sL https://run.surfpool.run/ | bash Copy 2. Verify that the installation was successful by checking the Surfpool CLI version: Terminal $ surfpool --version Copy You will see output like the following: surfpool 0.12.0 ### [Set up AI tooling for Solana development](https://solana.com/docs/intro/installation/dependencies#set-up-ai-tooling-for-solana-development) This section details optional AI tooling setup you can use to accelerate your Solana development. | Tool | Description | Link | | --- | --- | --- | | MCP | MCP server that you can connect to with cursor to improve Solana AI assisted development. | [https://mcp.solana.com/](https://mcp.solana.com/) | | LLMs.txt | LLM optimized documentation that you can use to train LLMs on Solana docs. | [https://solana.com/llms.txt](https://solana.com/llms.txt) | Is this page helpful? [Previous\ \ Quick Installation](https://solana.com/docs/intro/installation) [Next\ \ Solana CLI Basics](https://solana.com/docs/intro/installation/solana-cli-basics) ### Table of Contents [Prerequisites](https://solana.com/docs/intro/installation/dependencies#prerequisites) [Install Rust](https://solana.com/docs/intro/installation/dependencies#install-rust) [Install Solana CLI](https://solana.com/docs/intro/installation/dependencies#install-solana-cli) [Install Anchor CLI](https://solana.com/docs/intro/installation/dependencies#install-anchor-cli) [Prerequisites](https://solana.com/docs/intro/installation/dependencies#prerequisites-1) [Installation](https://solana.com/docs/intro/installation/dependencies#installation) [Install Surfpool CLI](https://solana.com/docs/intro/installation/dependencies#install-surfpool-cli) [Set up AI tooling for Solana development](https://solana.com/docs/intro/installation/dependencies#set-up-ai-tooling-for-solana-development) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/intro/installation/dependencies.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter Install the dependencies necessary to develop with Solana | Solana --- # SPL Token Basics | Solana [Solana Documentation](https://solana.com/docs) [Tokens on Solana](https://solana.com/docs/tokens) [SPL Token Basics](https://solana.com/docs/tokens/basics) ========================================================== Copy MarkdownOpen This section covers the basics for interacting with SPL Tokens, focusing on the most commonly used instructions. All examples in this section work identically with both the original Token Program and the Token Extension Program (Token 2022), as they share the same base implementation. Refer to the [Metaplex documentation](https://developers.metaplex.com/token-metadata) for more information on how add metadata to SPL Tokens. The most common instructions you'll see when interacting with SPL Tokens include: [### Create a Token Mint\ \ Learn how to create an SPL Token mint.](https://solana.com/docs/tokens/basics/create-mint) [### Create a Token Account\ \ Learn how to create SPL Token Accounts.](https://solana.com/docs/tokens/basics/create-token-account) [### Mint Tokens\ \ Learn how to mint new units of a token.](https://solana.com/docs/tokens/basics/mint-tokens) [### Transfer Tokens\ \ Learn how to transfer tokens between token accounts.](https://solana.com/docs/tokens/basics/transfer-tokens) [### Approve Delegate\ \ Learn how to approve delegates for a token account.](https://solana.com/docs/tokens/basics/approve-delegate) [### Revoke Delegate\ \ Learn how to revoke the token account delegate.](https://solana.com/docs/tokens/basics/revoke-delegate) [### Set Authority\ \ Learn how to set authority for mints or token accounts.](https://solana.com/docs/tokens/basics/set-authority) [### Burn Tokens\ \ Learn how to burn tokens.](https://solana.com/docs/tokens/basics/burn-tokens) [### Sync Native\ \ Learn how to convert native SOL to wrapped SOL.](https://solana.com/docs/tokens/basics/sync-native) [### Close Token Account\ \ Learn how to close token accounts.](https://solana.com/docs/tokens/basics/close-account) [### Freeze Account\ \ Learn how to freeze token accounts.](https://solana.com/docs/tokens/basics/freeze-account) [### Thaw Account\ \ Learn how to thaw a frozen token account.](https://solana.com/docs/tokens/basics/thaw-account) Is this page helpful? [Previous\ \ Tokens on Solana](https://solana.com/docs/tokens) [Next\ \ Create a Token Mint](https://solana.com/docs/tokens/basics/create-mint) ### Table of Contents No Headings [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/tokens/basics/index.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter SPL Token Basics | Solana --- # @solana/client | Solana [Solana Documentation](https://solana.com/docs) [Frontend](https://solana.com/docs/frontend) [@solana/client](https://solana.com/docs/frontend/client) ========================================================== Copy MarkdownOpen `@solana/client` keeps the runtime surface lean. One store, one RPC stack, and a wallet registry power the different helpers so the same instance can back CLIs, scripts, or full UIs. Actions, watchers, and helpers all share cache, subscriptions, and wallet sessions through that single client. When you are building a purely React experience it is usually faster to start with [`@solana/react-hooks`](https://solana.com/docs/frontend/react-hooks) . The hooks package wraps this same client runtime and exposes ready-made hooks so you only drop to the headless client when you need extra control. [Install](https://solana.com/docs/frontend/client#install) ----------------------------------------------------------- Terminal $ npm install @solana/client Copy Use any package manager; the client runs in browsers, workers, React, Svelte, or server-side runtimes. [Create a client once](https://solana.com/docs/frontend/client#create-a-client-once) ------------------------------------------------------------------------------------- Choose Wallet Standard connectors (auto discovery is the fastest way to start), then create the client. This single object exposes the store, actions, watchers, and helpers. import { autoDiscover, createClient } from "@solana/client"; const client \= createClient({ endpoint: "https://api.devnet.solana.com", websocketEndpoint: "wss://api.devnet.solana.com", walletConnectors: autoDiscover(), }); await client.actions.connectWallet("wallet-standard:phantom"); const balance \= await client.actions.fetchBalance("Fke...address"); console.log(balance.lamports?.toString()); The client store tracks cluster config, subscriptions, pending transactions, and wallet sessions. You can provide your own Zustand store if you need persistence or multi-tab coordination. [Wallet orchestration](https://solana.com/docs/frontend/client#wallet-orchestration) ------------------------------------------------------------------------------------- Connectors encapsulate Wallet Standard metadata plus connect/disconnect logic. Register the built-in `phantom()`, `solflare()`, `backpack()`, or `autoDiscover()` helpers, or wrap custom providers with `createWalletStandardConnector`. All wallet actions (connect, disconnect, sign, send) flow through the client registry so every consumer stays in sync. [Actions, watchers, and helpers](https://solana.com/docs/frontend/client#actions-watchers-and-helpers) ------------------------------------------------------------------------------------------------------- * **Actions** wrap common RPC reads and writes while updating the store (e.g., `fetchAccount`, `requestAirdrop`, `setCluster`). * **Watchers** multiplex websocket subscriptions, stream updates into the store, and give you abort handles for cleanup. * **Helpers** expose higher-level flows such as SOL transfers, SPL token helpers, signature polling, and transaction pools. const abortWatcher \= client.watchers.watchBalance( { address: "Fke...address" }, (lamports) \=> { console.log("live balance", lamports.toString()); }, ); // Later when the component unmounts or the flow ends abortWatcher.abort(); [Transaction helper pattern](https://solana.com/docs/frontend/client#transaction-helper-pattern) ------------------------------------------------------------------------------------------------- The transaction helper owns blockhash refresh, fee payer resolution, and signing. You can prepare, inspect, and send with whatever UX you prefer. const prepared \= await client.helpers.transaction.prepare({ authority: client.store.getState().wallet.session!, instructions: \[instructionA, instructionB\], }); await client.helpers.transaction.simulate(prepared, { commitment: "processed" }); const signature \= await client.helpers.transaction.send(prepared); console.log("submitted", signature.toString()); Use `prepareAndSend` for a pre-built flow (simulation plus logging) or call `sign` / `toWire` to collect signatures manually before relaying the wire format yourself. [Common patterns for Solana devs](https://solana.com/docs/frontend/client#common-patterns-for-solana-devs) ----------------------------------------------------------------------------------------------------------- * **Headless state machines**: Run the client inside API routes, scripts, or workers to reuse the same wallet + RPC orchestration logic that powers your UI. * **Realtime dashboards**: Combine watchers (balances, accounts, signatures) with your preferred UI library; the client handles websocket fan-out and cache invalidation. * **Custom stores**: Inject your own Zustand store to hydrate from IndexedDB/localStorage, mirror state to server sessions, or coordinate between browser tabs. * **Bridge to React hooks**: Pass a configured client instance to `@solana/react-hooks` when you want ergonomic hooks on top of the same runtime. * **Testability**: The single client interface can be mocked in unit tests, making it easy to simulate RPC responses or wallet sessions without a browser wallet present. Is this page helpful? [Previous\ \ Frontend](https://solana.com/docs/frontend) [Next\ \ @solana/react-hooks](https://solana.com/docs/frontend/react-hooks) ### Table of Contents [Install](https://solana.com/docs/frontend/client#install) [Create a client once](https://solana.com/docs/frontend/client#create-a-client-once) [Wallet orchestration](https://solana.com/docs/frontend/client#wallet-orchestration) [Actions, watchers, and helpers](https://solana.com/docs/frontend/client#actions-watchers-and-helpers) [Transaction helper pattern](https://solana.com/docs/frontend/client#transaction-helper-pattern) [Common patterns for Solana devs](https://solana.com/docs/frontend/client#common-patterns-for-solana-devs) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/frontend/client.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter --- # JavaScript/TypeScript SDK for Solana | Solana [Solana Documentation](https://solana.com/docs) Solana SDKsOfficial SDKs [JavaScript/TypeScript SDK for Solana](https://solana.com/docs/clients/official/javascript) ============================================================================================ Copy MarkdownOpen [Solana Client](https://solana.com/docs/clients/official/javascript#solana-client) ----------------------------------------------------------------------------------- `@solana/client` is the headless Solana runtime that bundles RPC, wallets, transactions, and subscriptions in one store. | Package | Description | GitHub | | --- | --- | --- | | @solana/client | Headless client runtime | [Source](https://github.com/solana-foundation/framework-kit/tree/main/packages/client) | * [Guide: @solana/client overview](https://solana.com/docs/frontend/client) [Solana React Hooks](https://solana.com/docs/clients/official/javascript#solana-react-hooks) --------------------------------------------------------------------------------------------- `@solana/react-hooks` layers a React provider and hooks on top of `@solana/client`, reusing the same runtime and cache. | Package | Description | GitHub | | --- | --- | --- | | @solana/react-hooks | React provider + hooks for UIs | [Source](https://github.com/solana-foundation/framework-kit/tree/main/packages/react-hooks) | * [Guide: @solana/react-hooks](https://solana.com/docs/frontend/react-hooks) [Solana Kit](https://solana.com/docs/clients/official/javascript#solana-kit) ----------------------------------------------------------------------------- `@solana/kit` is the recommended TypeScript SDK for building on Solana. | Package | Description | GitHub | | --- | --- | --- | | @solana/kit | Core SDK | [Source](https://github.com/anza-xyz/kit) | | @solana-program/system | Interact with System program | [Source](https://github.com/solana-program/system/tree/main/clients/js) | | @solana-program/token | Interact with Token program | [Source](https://github.com/solana-program/token/tree/main/clients/js) | | @solana-program/token-2022 | Interact with Token-2022 program | [Source](https://github.com/solana-program/token-2022/tree/main/clients/js) | | @solana-program/memo | Interact with Memo program | [Source](https://github.com/solana-program/memo/tree/main/clients/js) | | @solana-program/compute-budget | Interact with Compute Budget program | [Source](https://github.com/solana-program/compute-budget/tree/main/clients/js) | * [Official Kit Documentation](https://www.solanakit.com/) * [Tutorial: Next.js + React Hooks](https://solana.com/docs/frontend/nextjs-solana) [Solana Web3.js](https://solana.com/docs/clients/official/javascript#solana-web3js) ------------------------------------------------------------------------------------ `@solana/web3.js` is the legacy TypeScript SDK for Solana. | Package | Description | GitHub | | --- | --- | --- | | @solana/web3.js | Core SDK | [Source](https://github.com/solana-foundation/solana-web3.js) | | @solana/spl-token | Interact with Token, Token-2022, and Associated Token programs | [Source](https://github.com/solana-program/token-2022/tree/main/clients/js-legacy) | | @solana/spl-memo | Interact with Memo program | [Source](https://github.com/solana-program/memo/tree/main/clients/js-legacy) | * [Example: Connect a wallet with Next.js](https://solana.com/developers/cookbook/wallets/connect-wallet-react) Is this page helpful? [Previous\ \ Rust SDK](https://solana.com/docs/clients/official/rust) [Next\ \ Python SDK](https://solana.com/docs/clients/community/python) ### Table of Contents [Solana Client](https://solana.com/docs/clients/official/javascript#solana-client) [Solana React Hooks](https://solana.com/docs/clients/official/javascript#solana-react-hooks) [Solana Kit](https://solana.com/docs/clients/official/javascript#solana-kit) [Solana Web3.js](https://solana.com/docs/clients/official/javascript#solana-web3js) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/clients/official/javascript.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter --- # Reading from Network | Solana [Solana Documentation](https://solana.com/docs) Getting Started[Quick Start](https://solana.com/docs/intro/quick-start) [Reading from Network](https://solana.com/docs/intro/quick-start/reading-from-network) ======================================================================================= Copy MarkdownOpen Read data from the Solana network by fetching different accounts. This section will help you understand the structure of Solana [accounts](https://solana.com/docs/core/accounts) . Each Solana account has a unique [address](https://solana.com/docs/core/accounts#account-address) that is used to locate its corresponding on-chain data. Accounts contain either [state data or an executable program](https://solana.com/docs/core/accounts#types-of-accounts) . [Fetch a wallet account](https://solana.com/docs/intro/quick-start/reading-from-network#fetch-a-wallet-account) ---------------------------------------------------------------------------------------------------------------- A wallet is an account owned by the [System Program](https://solana.com/docs/core/programs#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. Fetch account 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 account const 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)); Console RunClick to execute the code. Fetch account 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 account const 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)); Console RunClick to execute the code. When you fetch a wallet account, the response includes the fields shown in the example output on the right. Example output { "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). Example output { "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`. Example output { "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](https://solana.com/docs/references/terminology#lamport) . Example output { "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`. Example output { "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.) Example output { "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](https://solana.com/docs/core/accounts#account-structure) itself, but is included in the response. In this example, the `space` field is 0 because the `data` field contains 0 bytes of data. Example output { "data": { "type": "Buffer", "data": \[\] }, "executable": false, "lamports": 1000000000, "owner": "11111111111111111111111111111111", "rentEpoch": 0, "space": 0 } When you fetch a wallet account, the response includes the fields shown in the example output on the right. The `data` field contains the account's data stored as bytes. For wallet accounts, this field is empty (0 bytes). The `executable` field indicates whether the account's `data` field contains executable program code. For wallet accounts this field is `false`. The `lamports` field contains the account's SOL balance, in [lamports](https://solana.com/docs/references/terminology#lamport) . The `owner` field shows the program that owns the account. For wallets, the owner is always the System Program, with the address `11111111111111111111111111111111`. The `rentEpoch` field is a legacy field from a deprecated rent mechanism. (This field is included for backward compatibility.) The `space` field shows the number of bytes contained in the `data` field. This is not a field in the [Account type](https://solana.com/docs/core/accounts#account-structure) itself, but is included in the response. In this example, the `space` field is 0 because the `data` field contains 0 bytes of data. Example output { "data": { "type": "Buffer", "data": \[\] }, "executable": false, "lamports": 1000000000, "owner": "11111111111111111111111111111111", "rentEpoch": 0, "space": 0 } [Fetch the Token Program](https://solana.com/docs/intro/quick-start/reading-from-network#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](https://github.com/solana-program/token/tree/main/program) . You can view this program account on the [Solana Explorer](https://explorer.solana.com/address/TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA) . Fetch program account import { Connection, PublicKey } from "@solana/web3.js"; const connection \= new Connection( "https://api.mainnet.solana.com", "confirmed" ); const address \= new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"); const accountInfo \= await connection.getAccountInfo(address); console.log( Console RunClick to execute the code. Fetch program account import { Connection, PublicKey } from "@solana/web3.js"; const connection \= new Connection( "https://api.mainnet.solana.com", "confirmed" ); const address \= new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"); const accountInfo \= await connection.getAccountInfo(address); console.log( Console RunClick to execute the code. The Token Program is an executable program account. Programs have the same underlying fields as all [accounts](https://solana.com/docs/core/accounts#account-structure) , but with key differences. Token program account { "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. Token program account { "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. Token program account { "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](https://solana.com/docs/core/programs#loader-programs) . In this example, the `owner` is the BPFLoader2 program. Token program account { "data": { "type": "Buffer", "data": \[127, "...truncated, total bytes: 134080...", 0\] }, "executable": true, "lamports": 4522329612, "owner": "BPFLoader2111111111111111111111111111111111", "rentEpoch": 18446744073709552000, "space": 134080 } The Token Program is an executable program account. Programs have the same underlying fields as all [accounts](https://solana.com/docs/core/accounts#account-structure) , but with key differences. The `executable` field is set to `true`, which indicates that the account's `data` field contains executable code. The `data` field stores the program's executable code. Every program account is owned by its [loader program](https://solana.com/docs/core/programs#loader-programs) . In this example, the `owner` is the BPFLoader2 program. Token program account { "data": { "type": "Buffer", "data": \[127, "...truncated, total bytes: 134080...", 0\] }, "executable": true, "lamports": 4522329612, "owner": "BPFLoader2111111111111111111111111111111111", "rentEpoch": 18446744073709552000, "space": 134080 } [Fetch a mint account](https://solana.com/docs/intro/quick-start/reading-from-network#fetch-a-mint-account) ------------------------------------------------------------------------------------------------------------ A [mint account](https://github.com/solana-program/token/blob/program%40v8.0.0/program/src/state.rs#L16-L30) 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. Fetch program account import { Connection, PublicKey } from "@solana/web3.js"; const connection \= new Connection( "https://api.mainnet.solana.com", "confirmed" ); const address \= new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"); const accountInfo \= await connection.getAccountInfo(address); console.log( Console RunClick to execute the code. Fetch program account import { Connection, PublicKey } from "@solana/web3.js"; const connection \= new Connection( "https://api.mainnet.solana.com", "confirmed" ); const address \= new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"); const accountInfo \= await connection.getAccountInfo(address); console.log( Console RunClick to execute the code. 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. Mint account { "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. Mint account { "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](https://solana.com/docs/intro/quick-start/reading-from-network#deserialize-mint-account) . Mint account { "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](https://solana.com/docs/references/terminology#token-program) . This means that its `data` field can only be modified by the Token Program' instructions. Mint Account { "data": { "type": "Buffer", "data": \[1, "...truncated, total bytes: 82...", 103\] }, "executable": false, "lamports": 407438077149, "owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "rentEpoch": 18446744073709552000, "space": 82 } 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. 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. 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](https://solana.com/docs/intro/quick-start/reading-from-network#deserialize-mint-account) . The mint account is owned by the [Token Program](https://solana.com/docs/references/terminology#token-program) . This means that its `data` field can only be modified by the Token Program' instructions. Mint account { "data": { "type": "Buffer", "data": \[1, "...truncated, total bytes: 82...", 103\] }, "executable": false, "lamports": 407438077149, "owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "rentEpoch": 18446744073709552000, "space": 82 } [Deserialize mint account](https://solana.com/docs/intro/quick-start/reading-from-network#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](https://github.com/solana-program/token/blob/program%40v8.0.0/program/src/state.rs#L16-L30) data type defined by the Token Program. Deserialize mint account data import { PublicKey, Connection } from "@solana/web3.js"; import { getMint } from "@solana/spl-token"; const connection \= new Connection( "https://api.mainnet.solana.com", "confirmed" ); const address \= new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"); const mintData \= await getMint(connection, address, "confirmed"); console.log( Console RunClick to execute the code. Deserialize mint account data import { PublicKey, Connection } from "@solana/web3.js"; import { getMint } from "@solana/spl-token"; const connection \= new Connection( "https://api.mainnet.solana.com", "confirmed" ); const address \= new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"); const mintData \= await getMint(connection, address, "confirmed"); console.log( Console RunClick to execute the code. Mint account type 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, /// 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 initialized pub is\_initialized: bool, /// Optional authority to freeze token accounts. pub freeze\_authority: COption, } The `getMint()` function deserializes a mint account's `data` field into the Mint account type. Mint account { "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](https://explorer.solana.com/address/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v?cluster=mainnet-beta) data on the Solana Explorer. Deserialized mint data { "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. Deserialized mint data { "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. Deserialized mint data { "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`. Deserialized mint data { "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. Deserialized mint data { "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. Deserialized mint data { "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. Deserialized mint data { "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](https://solana.com/docs/tokens/extensions) (Token2022). Deserialized mint data { "address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "mintAuthority": "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG", "supply": "8985397351591790", "decimals": 6, "isInitialized": true, "freezeAuthority": "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar", "tlvData": { "type": "Buffer", "data": \[\] } } The `getMint()` function deserializes a mint account's `data` field into the Mint account type. Mint account { "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](https://explorer.solana.com/address/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v?cluster=mainnet-beta) data on the Solana Explorer. The `address` field contains the mint account's address. The `mintAuthority` field shows the only account that can create new units of the token. 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`. The `decimals` field shows the number of decimal places for the token. The `isInitialized` field indicates whether the mint account has been initialized. This field is a security check used in the Token Program. The `freezeAuthority` field shows the account with authority to freeze token accounts. A frozen token account cannot transfer or burn the token it contains. 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](https://solana.com/docs/tokens/extensions) (Token2022). Deserialized mint data { "address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "mintAuthority": "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG", "supply": "8985397351591790", "decimals": 6, "isInitialized": true, "freezeAuthority": "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar", "tlvData": { "type": "Buffer", "data": \[\] } } Is this page helpful? [Previous\ \ Quick Start](https://solana.com/docs/intro/quick-start) [Next\ \ Writing to the Network](https://solana.com/docs/intro/quick-start/writing-to-network) ### Table of Contents [Fetch a wallet account](https://solana.com/docs/intro/quick-start/reading-from-network#fetch-a-wallet-account) [Fetch the Token Program](https://solana.com/docs/intro/quick-start/reading-from-network#fetch-the-token-program) [Fetch a mint account](https://solana.com/docs/intro/quick-start/reading-from-network#fetch-a-mint-account) [Deserialize mint account](https://solana.com/docs/intro/quick-start/reading-from-network#deserialize-mint-account) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/intro/quick-start/reading-from-network.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter --- # Solana RPC HTTP Methods | Solana [Solana Documentation](https://solana.com/docs) [Solana RPC Methods](https://solana.com/docs/rpc) [Solana RPC HTTP Methods](https://solana.com/docs/rpc/http) ============================================================ Copy MarkdownOpen Solana nodes accept HTTP requests using the [JSON-RPC 2.0](https://www.jsonrpc.org/specification) specification. > For JavaScript applications, use the [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) > library as a convenient interface for the RPC methods to interact with a Solana node. For an PubSub connection to a Solana node, use the [Websocket API](https://solana.com/docs/rpc/websocket/) > . [RPC HTTP Endpoint](https://solana.com/docs/rpc/http#rpc-http-endpoint) ------------------------------------------------------------------------ Default port: `8899` * [http://localhost:8899](http://localhost:8899/) * [http://192.168.1.88:8899](http://192.168.1.88:8899/) [Request Formatting](https://solana.com/docs/rpc/http#request-formatting) -------------------------------------------------------------------------- To make a JSON-RPC request, send an HTTP POST request with a `Content-Type: application/json` header. The JSON request data should contain 4 fields: * `jsonrpc: ` - set to `"2.0"` * `id: ` - a unique identifier for the request, generated by the client. Typically a string or number, though null is technically allowed but not advised * `method: ` - a string containing the method to be invoked * `params: ` - a JSON array of ordered parameter values Example using curl: curl https://api.devnet.solana.com \-s -X POST \-H "Content-Type: application/json" \-d ' { "jsonrpc": "2.0", "id": 1, "method": "getBalance", "params": \[\ \ "83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri"\ \ \] } ' The response output will be a JSON object with the following fields: * `jsonrpc: ` - matching the request specification * `id: ` - matching the request identifier * `result: ` - requested data or success confirmation Requests can be sent in batches by sending an array of JSON-RPC request objects as the data for a single POST. ### [Example Request](https://solana.com/docs/rpc/http#example-request) The commitment parameter should be included as the last element in the `params` array: curl https://api.devnet.solana.com \-s -X POST \-H "Content-Type: application/json" \-d ' { "jsonrpc": "2.0", "id": 1, "method": "getBalance", "params": \[\ \ "83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri",\ \ {\ \ "commitment": "finalized"\ \ }\ \ \] } ' [Definitions](https://solana.com/docs/rpc/http#definitions) ------------------------------------------------------------ * Hash: A SHA-256 hash of a chunk of data. * Pubkey: The public key of a Ed25519 key-pair. * Transaction: A list of Solana instructions signed by a client keypair to authorize those actions. * Signature: An Ed25519 signature of transaction's payload data including instructions. This can be used to identify transactions. [Health Check](https://solana.com/docs/rpc/http#health-check) -------------------------------------------------------------- Although not a JSON RPC API, a `GET /health` at the RPC HTTP Endpoint provides a health-check mechanism for use by load balancers or other network infrastructure. This request will always return a HTTP 200 OK response with a body of "ok", "behind" or "unknown": * `ok`: The node is within `HEALTH_CHECK_SLOT_DISTANCE` slots from the latest cluster confirmed slot * `behind { distance }`: The node is behind `distance` slots from the latest cluster confirmed slot where `distance > HEALTH_CHECK_SLOT_DISTANCE` * `unknown`: The node is unable to determine where it stands in relation to the cluster Is this page helpful? [Previous\ \ Data Structures as JSON](https://solana.com/docs/rpc/json-structures) [Next\ \ getAccountInfo](https://solana.com/docs/rpc/http/getaccountinfo) ### Table of Contents [RPC HTTP Endpoint](https://solana.com/docs/rpc/http#rpc-http-endpoint) [Request Formatting](https://solana.com/docs/rpc/http#request-formatting) [Example Request](https://solana.com/docs/rpc/http#example-request) [Definitions](https://solana.com/docs/rpc/http#definitions) [Health Check](https://solana.com/docs/rpc/http#health-check) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/rpc/http/index.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter Solana RPC HTTP Methods | Solana --- # Interacting with Solana | Solana [Payments](https://solana.com/docs) [Interacting with Solana](https://solana.com/docs/payments/interacting-with-solana) ==================================================================================== Copy MarkdownOpen Before building payment flows, you need to connect to Solana and understand how to query network data. This guide covers the basics: establishing a connection and using the RPC methods you'll need for payments using the [@solana/kit](https://www.npmjs.com/package/@solana/kit) TypeScript SDK and [Solana CLI](https://solana.com/docs/intro/installation) . Additionally, we will cover the basics of using the [Solana Explorer](https://explorer.solana.com/) to manually verify payments, inspect accounts, and debug issues. [Connecting to Solana](https://solana.com/docs/payments/interacting-with-solana#connecting-to-solana) ------------------------------------------------------------------------------------------------------ Solana's RPC API is the primary way to programmatically interact with the network. Your RPC URL is effectively an API key to the network. Do not use public RPC for production The public endpoints (`api.mainnet-beta.solana.com`, `api.devnet.solana.com`) are rate-limited, have no SLA, and are unsuitable for production payment flows. Use an [RPC provider](https://solana.com/rpc) to secure a private RPC endpoint for production deployments. For development and testing, you can use rate-limited public endpoints. Create an RPC client to interact with the network: Kit CLI import { createSolanaRpc, createSolanaRpcSubscriptions } from "@solana/kit"; const rpc \= createSolanaRpc("https://api.mainnet-beta.solana.com"); const rpcSubscriptions \= createSolanaRpcSubscriptions( "wss://api.mainnet-beta.solana.com" ); For development, use devnet (`https://api.devnet.solana.com`) or a local validator like [Surfpool](https://solana.com/docs/intro/installation/surfpool-cli-basics) . [Common RPC Methods](https://solana.com/docs/payments/interacting-with-solana#common-rpc-methods) -------------------------------------------------------------------------------------------------- Solana's [JSON-RPC API](https://solana.com/docs/rpc) exposes methods to query the network. Here are the ones you'll use most for payment flows. ### [Getting Account Info](https://solana.com/docs/payments/interacting-with-solana#getting-account-info) All accounts on Solana are addressable by their public key. Use the [`getAccountInfo`](https://solana.com/docs/rpc/http/getaccountinfo) RPC method to fetch information about any account. The `getAccountInfo` method returns an `AccountInfo` object, which contains the account's public key, SOL balance, data, and some other metadata. The `data` field is a base64 encoded string of the account's data. You can encode it to bytes using the `getBase64Codec` method from the `@solana/kit` package and then decode it to a readable object using the expected codec (if known) for the account's data (e.g., `getTokenCodec` for token accounts). Kit CLI const accountInfo \= await rpc .getAccountInfo(address("7EcDhSYGxXyscszYEp35KHN8vvw3svAuLKTzXwCFLtV"), { encoding: "base64" }) .send(); const dataBytes \= getBase64Codec().encode(accountInfo.value.data); const parsedTokenData \= getTokenCodec().decode(dataBytes); console.log(parsedTokenData); ### [Getting Token Balances](https://solana.com/docs/payments/interacting-with-solana#getting-token-balances) Check a token account's balance using the [`getTokenAccountBalance`](https://solana.com/docs/rpc/http/gettokenaccountbalance) RPC method: Kit CLI const balance \= await rpc.getTokenAccountBalance(tokenAccountAddress).send(); console.log(balance.value.uiAmount); // Human-readable (e.g., 100.50) console.log(balance.value.amount); // Base units (e.g., "100500000") ### [Building Transactions](https://solana.com/docs/payments/interacting-with-solana#building-transactions) Every transaction needs a recent blockhash to ensure it is valid (and not stale). Fetch one before creating a payment transaction using the [`getLatestBlockhash`](https://solana.com/docs/rpc/http/getlatestblockhash) RPC method: Kit CLI const { value: latestBlockhash } \= await rpc.getLatestBlockhash().send(); > Blockhashes expire after ~60 seconds. Fetch a fresh one immediately before signing and sending. ### [Checking Transaction Status](https://solana.com/docs/payments/interacting-with-solana#checking-transaction-status) Verify a transaction settled using the [`getSignatureStatuses`](https://solana.com/docs/rpc/http/getsignaturestatuses) RPC method: Kit CLI const status \= await rpc.getSignatureStatuses(\[signature\]).send(); const result \= status.value\[0\]; // result.confirmationStatus: "processed" | "confirmed" | "finalized" ### [Getting Transaction Details](https://solana.com/docs/payments/interacting-with-solana#getting-transaction-details) Fetch the full details of a confirmed transaction using the [`getTransaction`](https://solana.com/docs/rpc/http/gettransaction) RPC method: Kit CLI const transaction \= await rpc .getTransaction(signature, { maxSupportedTransactionVersion: 0 }) .send(); ### [Transaction History](https://solana.com/docs/payments/interacting-with-solana#transaction-history) Get recent transactions for an address using the [`getSignaturesForAddress`](https://solana.com/docs/rpc/http/getsignaturesforaddress) RPC method: Kit CLI const signatures \= await rpc .getSignaturesForAddress(walletAddress, { limit: 10 }) .send(); > For comprehensive payment monitoring, see [Accept Payments](https://solana.com/docs/payments/accept-payments) > which covers webhooks and real-time transaction detection. [Exploring Public Data](https://solana.com/docs/payments/interacting-with-solana#exploring-public-data) -------------------------------------------------------------------------------------------------------- Solana's public ledger means every transaction, token account, and mint is fully auditable. Block explorers let you manually verify payments, inspect accounts, and debug issues without writing code. **What you can look up:** * Verify a payment settled * Inspect token account balances * Debug failed transactions * Look up mint details (supply, decimals, authority) **Common explorers:** [Solana Explorer](https://explorer.solana.com/) , [SolanaFM](https://solana.fm/) , [Solscan](https://solscan.io/) , [Orb](https://www.orbmarkets.io/) **Example links:** * [USDC Token Mint](https://explorer.solana.com/address/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v) — Supply, markets, holders, and transactions for USDC * [USDC Token Transfer](https://explorer.solana.com/tx/3d2mQChCbqM5iogAN5PZw7KGZuVtQq3LbwU8hk55u4iUvYH1XJ7SQVQpWwoZj43MtthBqGBoqGBe9fn4Bo1VznjG) — Details of a USDC payment transaction * [USDG Token Account](https://explorer.solana.com/address/7v45FoihixmfocS3LbANUrEGZQKEJ7QQUg8K9jtZd3St) — A user's USDG balance and transaction history Is this page helpful? [Previous\ \ How Payments Work on Solana](https://solana.com/docs/payments/how-payments-work) [Next\ \ Send Payments](https://solana.com/docs/payments/send-payments) ### Table of Contents [Connecting to Solana](https://solana.com/docs/payments/interacting-with-solana#connecting-to-solana) [Common RPC Methods](https://solana.com/docs/payments/interacting-with-solana#common-rpc-methods) [Getting Account Info](https://solana.com/docs/payments/interacting-with-solana#getting-account-info) [Getting Token Balances](https://solana.com/docs/payments/interacting-with-solana#getting-token-balances) [Building Transactions](https://solana.com/docs/payments/interacting-with-solana#building-transactions) [Checking Transaction Status](https://solana.com/docs/payments/interacting-with-solana#checking-transaction-status) [Getting Transaction Details](https://solana.com/docs/payments/interacting-with-solana#getting-transaction-details) [Transaction History](https://solana.com/docs/payments/interacting-with-solana#transaction-history) [Exploring Public Data](https://solana.com/docs/payments/interacting-with-solana#exploring-public-data) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/payments/interacting-with-solana.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter Interacting with Solana | Solana --- # Introductory commands for getting started on the Solana CLI | Solana [Solana Documentation](https://solana.com/docs) Getting Started[Installation](https://solana.com/docs/intro/installation) [Solana CLI Basics](https://solana.com/docs/intro/installation/solana-cli-basics) ================================================================================== Copy MarkdownOpen This section provides some common commands and examples to help you get you started using the Solana CLI. [Solana config](https://solana.com/docs/intro/installation/solana-cli-basics#solana-config) -------------------------------------------------------------------------------------------- Your Solana config specifies the following variables: * **Config file**: The path to your config file * **RPC URL & Websocket URL**: The Solana cluster to which the CLI makes requests * **Keypair path**: The path to the default Solana wallet (keypair) used to pay transaction fees and deploy programs. By default, this file is stored at `~/.config/solana/id.json`. To see your current configuration settings, enter the follow command in your terminal. Terminal $ solana config get Copy A successful command will return output similar to the following: Example output Config File: /Users/test/.config/solana/cli/config.yml RPC URL: https://api.mainnet-beta.solana.com WebSocket URL: wss://api.mainnet-beta.solana.com/ (computed) Keypair Path: /Users/test/.config/solana/id.json Commitment: confirmed You can change the Solana CLI cluster with the following commands: Full commandsShort commands Terminal $ solana config set --url mainnet-beta Copy $ solana config set --url devnet Copy $ solana config set --url localhost Copy $ solana config set --url testnet Copy [Create a wallet](https://solana.com/docs/intro/installation/solana-cli-basics#create-a-wallet) ------------------------------------------------------------------------------------------------ Before you can send a transactions using the Solana CLI, you need a Solana wallet funded with SOL. To generate a keypair at the default keypair path, run the following command: Terminal $ solana-keygen new Copy A successful command will return output similar to the following: Example output Generating a new keypair For added security, enter a BIP39 passphrase NOTE! This passphrase improves security of the recovery seed phrase NOT the keypair file itself, which is stored as insecure plain text BIP39 Passphrase (empty for none): Wrote new keypair to /Users/test/.config/solana/id.json \=========================================================================== pubkey: 8dBTPrjnkXyuQK3KDt9wrZBfizEZijmmUQXVHpFbVwGT \=========================================================================== Save this seed phrase and your BIP39 passphrase to recover your new keypair: cream bleak tortoise ocean nasty game gift forget fancy salon mimic amazing \=========================================================================== This command will not override an existing account at the default location, unless you use the `--force` flag. To view your wallet's address (public key), run: Terminal $ solana address Copy [Airdrop SOL](https://solana.com/docs/intro/installation/solana-cli-basics#airdrop-sol) ---------------------------------------------------------------------------------------- Request an airdrop of SOL to your wallet to pay for transactions and program deployments. 1. Set your cluster to Devnet: Terminal $ solana config set -ud Copy 2. Request an airdrop of Devnet SOL: Terminal $ solana airdrop 2 Copy Devnet airdrops limit requests to 5 SOL per request. If you hit rate limits or encounter errors, try using the [Web Faucet](https://faucet.solana.com/) instead. To check your wallet's SOL balance, run the following command: Terminal $ solana balance Copy Is this page helpful? [Previous\ \ Install Dependencies](https://solana.com/docs/intro/installation/dependencies) [Next\ \ Anchor CLI Basics](https://solana.com/docs/intro/installation/anchor-cli-basics) ### Table of Contents [Solana config](https://solana.com/docs/intro/installation/solana-cli-basics#solana-config) [Create a wallet](https://solana.com/docs/intro/installation/solana-cli-basics#create-a-wallet) [Airdrop SOL](https://solana.com/docs/intro/installation/solana-cli-basics#airdrop-sol) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/intro/installation/solana-cli-basics.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter Introductory commands for getting started on the Solana CLI | Solana --- # Extensions | Solana [Solana Documentation](https://solana.com/docs) [Tokens on Solana](https://solana.com/docs/tokens) [Extensions](https://solana.com/docs/tokens/extensions) ======================================================== Copy MarkdownOpen [What are Token Extensions?](https://solana.com/docs/tokens/extensions#what-are-token-extensions) -------------------------------------------------------------------------------------------------- The Token Extensions Program (Token 2022) provides more features through extra instructions referred to as extensions. Extensions are optional features you can add to a token mint or token account. You can find the implementation of these extension instructions in the Token Extensions Program [source code](https://github.com/solana-program/token-2022/tree/main/program/src/extension) . Each extension adds specific state that's generally initialized during mint or token account creation. When initializing either account, you can enable specific extensions simultaneously for different functionality. Most extensions can't be added after an account is initialized. This is an important consideration when designing your token, as you'll need to plan ahead for which features you want your token to support. Integration guides for each extension are available in the [Token Extensions developer documentation](https://solana.com/developers/guides/token-extensions/getting-started) . Some extensions are incompatible with each other and you can't enable them simultaneously on the same token mint or token account. For example, you can't combine the `NonTransferable` extension with the `TransferFeeConfig` extension, since they have conflicting behaviors. The Token Extensions Program defines an [`ExtensionType`](https://github.com/solana-program/token-2022/blob/efd0c957fefbd79882d77df5fb2dac88c001249c/program/src/extension/mod.rs#L1059) enum that lists all available extensions you can add to a token mint or token account. Each variant represents a different extension with unique functionality. The `ExtensionType` enum is defined as follows: Token Extensions /// Extensions that can be applied to mints or accounts. Mint extensions must /// only be applied to mint accounts, and account extensions must only be /// applied to token holding accounts. #\[repr(u16)\] #\[cfg\_attr(feature \= "serde-traits", derive(Serialize, Deserialize))\] #\[cfg\_attr(feature \= "serde-traits", serde(rename\_all \= "camelCase"))\] #\[derive(Clone, Copy, Debug, PartialEq, TryFromPrimitive, IntoPrimitive)\] pub enum ExtensionType { /// Used as padding if the account size would otherwise be 355, same as a /// multisig Uninitialized, /// Includes transfer fee rate info and accompanying authorities to withdraw /// and set the fee TransferFeeConfig, /// Includes withheld transfer fees TransferFeeAmount, /// Includes an optional mint close authority MintCloseAuthority, /// Auditor configuration for confidential transfers ConfidentialTransferMint, /// State for confidential transfers ConfidentialTransferAccount, /// Specifies the default Account::state for new Accounts DefaultAccountState, /// Indicates that the Account owner authority cannot be changed ImmutableOwner, /// Require inbound transfers to have memo MemoTransfer, /// Indicates that the tokens from this mint can't be transferred NonTransferable, /// Tokens accrue interest over time, InterestBearingConfig, /// Locks privileged token operations from happening via CPI CpiGuard, /// Includes an optional permanent delegate PermanentDelegate, /// Indicates that the tokens in this account belong to a non-transferable /// mint NonTransferableAccount, /// Mint requires a CPI to a program implementing the "transfer hook" /// interface TransferHook, /// Indicates that the tokens in this account belong to a mint with a /// transfer hook TransferHookAccount, /// Includes encrypted withheld fees and the encryption public that they are /// encrypted under ConfidentialTransferFeeConfig, /// Includes confidential withheld transfer fees ConfidentialTransferFeeAmount, /// Mint contains a pointer to another account (or the same account) that /// holds metadata MetadataPointer, /// Mint contains token-metadata TokenMetadata, /// Mint contains a pointer to another account (or the same account) that /// holds group configurations GroupPointer, /// Mint contains token group configurations TokenGroup, /// Mint contains a pointer to another account (or the same account) that /// holds group member configurations GroupMemberPointer, /// Mint contains token group member configurations TokenGroupMember, /// Mint allowing the minting and burning of confidential tokens ConfidentialMintBurn, /// Tokens whose UI amount is scaled by a given amount ScaledUiAmount, /// Tokens where minting / burning / transferring can be paused Pausable, /// Indicates that the account belongs to a pausable mint PausableAccount, /// Test variable-length mint extension #\[cfg(test)\] VariableLenMintTest \= u16::MAX \- 2, /// Padding extension used to make an account exactly Multisig::LEN, used /// for testing #\[cfg(test)\] AccountPaddingTest, /// Padding extension used to make a mint exactly Multisig::LEN, used for /// testing #\[cfg(test)\] MintPaddingTest, } Each extension adds specialized functionality by including extra state to a mint or token account. All extension specific state is stored in the [`tlv_data`](https://github.com/solana-program/token-2022/blob/efd0c957fefbd79882d77df5fb2dac88c001249c/program/src/extension/mod.rs#L546) field, which follows the base account data type. You must further deserialize the `tlv_data` (containing extension state) according to the specific extension types enabled for that account. Token Extensions /// Encapsulates immutable base state data (mint or account) with possible /// extensions, where the base state is Pod for zero-copy serde. #\[derive(Debug, PartialEq)\] pub struct PodStateWithExtensions<'data, S: BaseState + Pod\> { /// Unpacked base data pub base: &'data S, /// Slice of data containing all TLV data, deserialized on demand tlv\_data: &'data \[u8\], } Is this page helpful? [Previous\ \ Thaw Account](https://solana.com/docs/tokens/basics/thaw-account) [Next\ \ Scaled UI Amount](https://solana.com/docs/tokens/extensions/scaled-ui-amount) ### Table of Contents [What are Token Extensions?](https://solana.com/docs/tokens/extensions#what-are-token-extensions) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/tokens/extensions/index.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter Extensions | Solana --- # Writing to the Network | Solana [Solana Documentation](https://solana.com/docs) Getting Started[Quick Start](https://solana.com/docs/intro/quick-start) [Writing to the Network](https://solana.com/docs/intro/quick-start/writing-to-network) ======================================================================================= Copy MarkdownOpen In the previous section, you learned how to read data from the Solana network. Now you'll learn how to write data to it. Writing to the Solana network involves sending transactions that contain one or more instruction. Programs define the business logic for what each [instruction](https://solana.com/docs/core/instructions) does. When you submit a [transaction](https://solana.com/docs/core/transactions) , the Solana runtime executes each instruction in sequence and atomically. The examples in this section show how to build and send transactions to invoke Solana programs, they include: 1. Transferring SOL between accounts 2. Creating a new token [Transfer SOL](https://solana.com/docs/intro/quick-start/writing-to-network#transfer-sol) ------------------------------------------------------------------------------------------ The example below transfers SOL between two accounts. Each account has an owner program, which is the only program that can deduct the account's SOL balance. All wallet accounts are owned by the System Program. To transfer SOL, you must invoke the System Program's [transfer](https://github.com/anza-xyz/agave/blob/v2.1.11/programs/system/src/system_processor.rs#L183-L213) instruction. Transfer SOL import { LAMPORTS\_PER\_SOL, SystemProgram, Transaction, sendAndConfirmTransaction, Keypair, Connection } from "@solana/web3.js"; const connection \= new Connection("http://localhost:8899", "confirmed"); const sender \= new Keypair(); const receiver \= new Keypair(); const signature \= await connection.requestAirdrop( sender.publicKey, LAMPORTS\_PER\_SOL ); await connection.confirmTransaction(signature, "confirmed"); const transferInstruction \= SystemProgram.transfer({ fromPubkey: sender.publicKey, toPubkey: receiver.publicKey, lamports: 0.01 \* LAMPORTS\_PER\_SOL }); const transaction \= new Transaction().add(transferInstruction); const transactionSignature \= await sendAndConfirmTransaction( connection, transaction, \[sender\] ); console.log("Transaction Signature:", \`${transactionSignature}\`); const senderBalance \= await connection.getBalance(sender.publicKey); const receiverBalance \= await connection.getBalance(receiver.publicKey); console.log("Sender Balance:", \`${senderBalance}\`); console.log("Receiver Balance:", \`${receiverBalance}\`); Console RunClick to execute the code. Transfer SOL import { LAMPORTS\_PER\_SOL, SystemProgram, Transaction, sendAndConfirmTransaction, Keypair, Connection } from "@solana/web3.js"; const connection \= new Connection("http://localhost:8899", "confirmed"); const sender \= new Keypair(); const receiver \= new Keypair(); const signature \= await connection.requestAirdrop( sender.publicKey, LAMPORTS\_PER\_SOL ); await connection.confirmTransaction(signature, "confirmed"); const transferInstruction \= SystemProgram.transfer({ fromPubkey: sender.publicKey, toPubkey: receiver.publicKey, lamports: 0.01 \* LAMPORTS\_PER\_SOL }); const transaction \= new Transaction().add(transferInstruction); const transactionSignature \= await sendAndConfirmTransaction( connection, transaction, \[sender\] ); console.log("Transaction Signature:", \`${transactionSignature}\`); const senderBalance \= await connection.getBalance(sender.publicKey); const receiverBalance \= await connection.getBalance(receiver.publicKey); console.log("Sender Balance:", \`${senderBalance}\`); console.log("Receiver Balance:", \`${receiverBalance}\`); Console RunClick to execute the code. Create a `Connection` to handle sending transactions and fetching account data. In this example, we're connecting to the local test validator which runs on `localhost:8899`. Connection const connection \= new Connection("http://localhost:8899", "confirmed"); Generate new [keypairs](https://solana.com/docs/core/accounts#public-key) to use as the sender and receiver accounts. Generate keypairs const sender \= new Keypair(); const receiver \= new Keypair(); Add SOL to the sender account. On networks other than mainnet, you can use the `requestAirdrop` method to get SOL for testing. Airdrop const signature \= await connection.requestAirdrop( sender.publicKey, LAMPORTS\_PER\_SOL ); await connection.confirmTransaction(signature, "confirmed"); The `SystemProgram.transfer()` method creates an instruction that transfers SOL from the `fromPubkey` account to the `toPubkey` account for the specified number of `lamports`. Transfer instruction const transferInstruction \= SystemProgram.transfer({ fromPubkey: sender.publicKey, toPubkey: receiver.publicKey, lamports: 0.01 \* LAMPORTS\_PER\_SOL }); Create a transaction and add the instruction to the transaction. In this example, we're creating a transaction with a single instruction. However, you can add multiple instructions to a transaction. Transaction const transaction \= new Transaction().add(transferInstruction); Sign and send the transaction to the network. The sender keypair is required in the signers array to authorize the transfer of SOL from their account. Send transaction const transactionSignature \= await sendAndConfirmTransaction( connection, transaction, \[sender\] ); The transaction signature is a unique identifier that can be used to look up the transaction on Solana Explorer. Create a `Connection` to handle sending transactions and fetching account data. In this example, we're connecting to the local test validator which runs on `localhost:8899`. Connection const connection \= new Connection("http://localhost:8899", "confirmed"); Generate new [keypairs](https://solana.com/docs/core/accounts#public-key) to use as the sender and receiver accounts. Generate keypairs const sender \= new Keypair(); const receiver \= new Keypair(); Add SOL to the sender account. On networks other than mainnet, you can use the `requestAirdrop` method to get SOL for testing. Airdrop const signature \= await connection.requestAirdrop( sender.publicKey, LAMPORTS\_PER\_SOL ); await connection.confirmTransaction(signature, "confirmed"); The `SystemProgram.transfer()` method creates an instruction that transfers SOL from the `fromPubkey` account to the `toPubkey` account for the specified number of `lamports`. Transfer instruction const transferInstruction \= SystemProgram.transfer({ fromPubkey: sender.publicKey, toPubkey: receiver.publicKey, lamports: 0.01 \* LAMPORTS\_PER\_SOL }); Create a transaction and add the instruction to the transaction. In this example, we're creating a transaction with a single instruction. However, you can add multiple instructions to a transaction. Transaction const transaction \= new Transaction().add(transferInstruction); Sign and send the transaction to the network. The sender keypair is required in the signers array to authorize the transfer of SOL from their account. Send transaction const transactionSignature \= await sendAndConfirmTransaction( connection, transaction, \[sender\] ); The transaction signature is a unique identifier that can be used to look up the transaction on Solana Explorer. Transfer SOL import { LAMPORTS\_PER\_SOL, SystemProgram, Transaction, sendAndConfirmTransaction, Keypair, Connection } from "@solana/web3.js"; const connection \= new Connection("http://localhost:8899", "confirmed"); [Create a token](https://solana.com/docs/intro/quick-start/writing-to-network#create-a-token) ---------------------------------------------------------------------------------------------- The example below creates a new token on Solana using the Token Extensions Program. This requires two instructions: 1. Invoke the System Program to create a new account. 2. Invoke the Token Extensions Program to initialize that account as a Mint. Create mint account import { Connection, Keypair, SystemProgram, Transaction, sendAndConfirmTransaction, LAMPORTS\_PER\_SOL } from "@solana/web3.js"; import { MINT\_SIZE, TOKEN\_2022\_PROGRAM\_ID, createInitializeMint2Instruction, getMinimumBalanceForRentExemptMint, getMint } from "@solana/spl-token"; const connection \= new Connection("http://localhost:8899", "confirmed"); const wallet \= new Keypair(); // Fund the wallet with SOL const signature \= await connection.requestAirdrop( wallet.publicKey, LAMPORTS\_PER\_SOL ); await connection.confirmTransaction(signature, "confirmed"); // Generate keypair to use as address of mint account const mint \= new Keypair(); // Calculate lamports required for rent exemption const rentExemptionLamports \= await getMinimumBalanceForRentExemptMint(connection); // Instruction to create new account with space for new mint account const createAccountInstruction \= SystemProgram.createAccount({ fromPubkey: wallet.publicKey, newAccountPubkey: mint.publicKey, space: MINT\_SIZE, lamports: rentExemptionLamports, programId: TOKEN\_2022\_PROGRAM\_ID }); // Instruction to initialize mint account const initializeMintInstruction \= createInitializeMint2Instruction( mint.publicKey, 2, // decimals wallet.publicKey, // mint authority wallet.publicKey, // freeze authority TOKEN\_2022\_PROGRAM\_ID ); // Build transaction with instructions to create new account and initialize mint account const transaction \= new Transaction().add( createAccountInstruction, initializeMintInstruction ); const transactionSignature \= await sendAndConfirmTransaction( connection, transaction, \[\ \ wallet, // payer\ \ mint // mint address keypair\ \ \] ); console.log("Transaction Signature:", \`${transactionSignature}\`); const mintData \= await getMint( connection, mint.publicKey, "confirmed", TOKEN\_2022\_PROGRAM\_ID ); console.log( ); Console RunClick to execute the code. Create mint account import { Connection, Keypair, SystemProgram, Transaction, sendAndConfirmTransaction, LAMPORTS\_PER\_SOL } from "@solana/web3.js"; import { MINT\_SIZE, TOKEN\_2022\_PROGRAM\_ID, createInitializeMint2Instruction, getMinimumBalanceForRentExemptMint, getMint } from "@solana/spl-token"; const connection \= new Connection("http://localhost:8899", "confirmed"); const wallet \= new Keypair(); // Fund the wallet with SOL const signature \= await connection.requestAirdrop( wallet.publicKey, LAMPORTS\_PER\_SOL ); await connection.confirmTransaction(signature, "confirmed"); // Generate keypair to use as address of mint account const mint \= new Keypair(); // Calculate lamports required for rent exemption const rentExemptionLamports \= await getMinimumBalanceForRentExemptMint(connection); // Instruction to create new account with space for new mint account const createAccountInstruction \= SystemProgram.createAccount({ fromPubkey: wallet.publicKey, newAccountPubkey: mint.publicKey, space: MINT\_SIZE, lamports: rentExemptionLamports, programId: TOKEN\_2022\_PROGRAM\_ID }); // Instruction to initialize mint account const initializeMintInstruction \= createInitializeMint2Instruction( mint.publicKey, 2, // decimals wallet.publicKey, // mint authority wallet.publicKey, // freeze authority TOKEN\_2022\_PROGRAM\_ID ); // Build transaction with instructions to create new account and initialize mint account const transaction \= new Transaction().add( createAccountInstruction, initializeMintInstruction ); const transactionSignature \= await sendAndConfirmTransaction( connection, transaction, \[\ \ wallet, // payer\ \ mint // mint address keypair\ \ \] ); console.log("Transaction Signature:", \`${transactionSignature}\`); const mintData \= await getMint( connection, mint.publicKey, "confirmed", TOKEN\_2022\_PROGRAM\_ID ); console.log( ); Console RunClick to execute the code. Creating a token requires using both the `@solana/web3.js` and `@solana/spl-token` libraries. The code in the example below will: * Create a connection * Generate a keypair to pay for the transaction * Request an airdrop to fund the keypair Connection & wallet setup const connection \= new Connection("http://localhost:8899", "confirmed"); const wallet \= new Keypair(); const signature \= await connection.requestAirdrop( wallet.publicKey, LAMPORTS\_PER\_SOL ); await connection.confirmTransaction(signature, "confirmed"); Generate a keypair for the mint account. The public key will be used as the mint account's address. Mint keypair const mint \= new Keypair(); Calculate the minimum lamports required for a mint account. The `getMinimumBalanceForRentExemptMint` function calculates how many lamport must be allocated for the data on a mint account. Rent exemption const rentExemptionLamports \= await getMinimumBalanceForRentExemptMint(connection); The first instruction invokes the System Program's `createAccount` instruction to: 1. Allocate the number of bytes needed to store the mint data. 2. Transfer lamports from the wallet to fund the new account. 3. Assign ownership of the account to the [Token Extensions program](https://solana.com/docs/tokens/extensions) . Create account instruction const createAccountInstruction \= SystemProgram.createAccount({ fromPubkey: wallet.publicKey, newAccountPubkey: mint.publicKey, space: MINT\_SIZE, lamports: rentExemptionLamports, programId: TOKEN\_2022\_PROGRAM\_ID }); The second instruction invokes the Token Extensions Program's `createInitializeMint2Instruction` instruction to initialize the mint account with the following data: * 2 decimals * Wallet as both mint authority and freeze authority Initialize mint instruction const initializeMintInstruction \= createInitializeMint2Instruction( mint.publicKey, 2, wallet.publicKey, wallet.publicKey, TOKEN\_2022\_PROGRAM\_ID ); Add both instructions to a single transaction. This ensures that account creation and initialization happen atomically. (Either both instructions succeed, or neither does.) This approach is common when building complex Solana transactions, as it guarantees that all instructions execute together. Transaction const transaction \= new Transaction().add( createAccountInstruction, initializeMintInstruction ); Sign and send the transaction. Two signatures are required: * The wallet account signs as the payer for [transaction fees](https://solana.com/docs/core/fees) and account creation * The mint account signs to authorize the use of its address for the new account Send transaction const transactionSignature \= await sendAndConfirmTransaction( connection, transaction, \[\ \ wallet,\ \ mint\ \ \] ); The transaction signature returned can be used to inspect the transaction on Solana Explorer. Creating a token requires using both the `@solana/web3.js` and `@solana/spl-token` libraries. The code in the example below will: * Create a connection * Generate a keypair to pay for the transaction * Request an airdrop to fund the keypair Connection & wallet setup const connection \= new Connection("http://localhost:8899", "confirmed"); const wallet \= new Keypair(); const signature \= await connection.requestAirdrop( wallet.publicKey, LAMPORTS\_PER\_SOL ); await connection.confirmTransaction(signature, "confirmed"); Generate a keypair for the mint account. The public key will be used as the mint account's address. Mint keypair const mint \= new Keypair(); Calculate the minimum lamports required for a mint account. The `getMinimumBalanceForRentExemptMint` function calculates how many lamport must be allocated for the data on a mint account. Rent exemption const rentExemptionLamports \= await getMinimumBalanceForRentExemptMint(connection); The first instruction invokes the System Program's `createAccount` instruction to: 1. Allocate the number of bytes needed to store the mint data. 2. Transfer lamports from the wallet to fund the new account. 3. Assign ownership of the account to the [Token Extensions program](https://solana.com/docs/tokens/extensions) . Create account instruction const createAccountInstruction \= SystemProgram.createAccount({ fromPubkey: wallet.publicKey, newAccountPubkey: mint.publicKey, space: MINT\_SIZE, lamports: rentExemptionLamports, programId: TOKEN\_2022\_PROGRAM\_ID }); The second instruction invokes the Token Extensions Program's `createInitializeMint2Instruction` instruction to initialize the mint account with the following data: * 2 decimals * Wallet as both mint authority and freeze authority Initialize mint instruction const initializeMintInstruction \= createInitializeMint2Instruction( mint.publicKey, 2, wallet.publicKey, wallet.publicKey, TOKEN\_2022\_PROGRAM\_ID ); Add both instructions to a single transaction. This ensures that account creation and initialization happen atomically. (Either both instructions succeed, or neither does.) This approach is common when building complex Solana transactions, as it guarantees that all instructions execute together. Transaction const transaction \= new Transaction().add( createAccountInstruction, initializeMintInstruction ); Sign and send the transaction. Two signatures are required: * The wallet account signs as the payer for [transaction fees](https://solana.com/docs/core/fees) and account creation * The mint account signs to authorize the use of its address for the new account Send transaction const transactionSignature \= await sendAndConfirmTransaction( connection, transaction, \[\ \ wallet,\ \ mint\ \ \] ); The transaction signature returned can be used to inspect the transaction on Solana Explorer. Create mint account import { Connection, Keypair, SystemProgram, Transaction, sendAndConfirmTransaction, LAMPORTS\_PER\_SOL } from "@solana/web3.js"; import { MINT\_SIZE, TOKEN\_2022\_PROGRAM\_ID, createInitializeMint2Instruction, getMinimumBalanceForRentExemptMint, getMint } from "@solana/spl-token"; const connection \= new Connection("http://localhost:8899", "confirmed"); const wallet \= new Keypair(); const signature \= await connection.requestAirdrop( wallet.publicKey, LAMPORTS\_PER\_SOL ); await connection.confirmTransaction(signature, "confirmed"); Is this page helpful? [Previous\ \ Reading from Network](https://solana.com/docs/intro/quick-start/reading-from-network) [Next\ \ Deploy a Program](https://solana.com/docs/intro/quick-start/deploying-programs) ### Table of Contents [Transfer SOL](https://solana.com/docs/intro/quick-start/writing-to-network#transfer-sol) [Create a token](https://solana.com/docs/intro/quick-start/writing-to-network#create-a-token) [Edit Page](https://github.com/solana-foundation/solana-com/blob/main/apps/docs/content/docs/en/intro/quick-start/writing-to-network.mdx) Ask AI Managed by [](https://solana.com/) © 2026 Solana Foundation. All rights reserved. [](https://solana.com/youtube) [](https://solana.com/twitter) [](https://solana.com/discord) [](https://solana.com/reddit) [](https://solana.com/github) [](https://solana.com/telegram) en Solana * [Grants](https://solana.org/grants) * [Media Kit](https://solana.com/branding) * [Careers](https://jobs.solana.com/) * [Disclaimer](https://solana.com/tos) * [Privacy Policy](https://solana.com/privacy-policy) Get connected * [Blog](https://solana.com/news) * Newsletter Writing to the Network | Solana --- # @solana/react-hooks | Solana [Solana Documentation](https://solana.com/docs) [Frontend](https://solana.com/docs/frontend) [@solana/react-hooks](https://solana.com/docs/frontend/react-hooks) ==================================================================== Copy MarkdownOpen `@solana/react-hooks` layers a React provider, hooks, and suspense friendly query helpers on top of `@solana/client`. You still configure a single client, but the hooks expose wallet state, balances, transactions, and program queries without wiring stores or subscriptions by hand. [Install](https://solana.com/docs/frontend/react-hooks#install) ---------------------------------------------------------------- Terminal $ npm install @solana/client @solana/react-hooks Copy Both packages are required because the hooks reuse the client runtime to manage wallets, RPC, and caches. [Wrap your tree once](https://solana.com/docs/frontend/react-hooks#wrap-your-tree-once) ---------------------------------------------------------------------------------------- Create the client, optionally pick wallet connectors, then wrap your React tree with `SolanaProvider`. Every hook reads from the shared client instance. "use client"; import { autoDiscover, createClient } from "@solana/client"; import { SolanaProvider } from "@solana/react-hooks"; const client \= createClient({ endpoint: "https://api.devnet.solana.com", websocketEndpoint: "wss://api.devnet.solana.com", walletConnectors: autoDiscover(), }); export function Providers({ children }: { children: React.ReactNode }) { return {children}; } [Hooks mirror the client runtime](https://solana.com/docs/frontend/react-hooks#hooks-mirror-the-client-runtime) ---------------------------------------------------------------------------------------------------------------- * **Wallet + connectors**: `useWallet`, `useWalletConnection`, `useConnectWallet`, and `useDisconnectWallet` expose the same registry that powers the client. * **Balance + account watchers**: `useBalance`, `useAccount`, `useSolBalance`, and `useProgramAccounts` stream updates from the underlying watchers and share cache with actions. * **Transactions + SPL helpers**: `useSolTransfer`, `useSplToken`, `useTransactionPool`, and `useSendTransaction` lean on the client's helper suite so hooks inherit blockhash refresh, fee payer resolution, and logging. function WalletPanel() { const { connectors, connect, disconnect, wallet, status } \= useWalletConnection(); const balance \= useBalance(wallet?.account.address); if (status \=== "connected") { return ( {wallet?.account.address.toString()} Lamports: {balance.lamports?.toString() ?? "loading…"}