Download the PHP package sandermuller/solana-php-sdk without Composer

On this page you can find all versions of the php package sandermuller/solana-php-sdk. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package solana-php-sdk

solana-php-sdk

Latest Version on Packagist GitHub Tests Action Status Total Downloads

A PHP SDK for the Solana blockchain. Read accounts, sign and submit transactions, watch the chain over WebSockets, and call any Anchor program — all from PHP.

Status: open source under MIT. Works on PHP 8.3 / 8.4 with Laravel 11 / 12 / 13.


What you get

Layer What it does Class
Keys & signatures Generate keypairs, sign messages, verify Ed25519 signatures Keypair, PublicKey
Raw JSON-RPC One method: call($method, $params) — pass anything Solana defines Services\SolanaRpcClient
Typed JSON-RPC ~50 typed methods covering ~90 % of the HTTP-RPC spec Connection
WebSocket PubSub Account / signature / slot / logs / program / vote / block subscriptions Services\SolanaPubSubClient
Transactions Legacy + V0 (versioned) transactions, Address Lookup Tables Transaction, VersionedTransaction, MessageV0
Programs System, SPL Token, Token-2022, ComputeBudget, AddressLookupTable, Stake, Vote, Memo, Metaplex, DID-Sol, SNS Programs\*
Send & confirm Priority-fee estimator + sendAndConfirmTransaction helper with blockhash-expiry detection Util\PriorityFee, Connection::sendAndConfirmTransaction
Pluggable RPC transports Multi-endpoint fallback / round-robin / exponential-backoff retry Rpc\FallbackTransport, Rpc\RoundRobinTransport, Rpc\RetryTransport
Structured sendTransaction errors Decoded TransactionError + InstructionError enums, program logs, units consumed Exceptions\SendTransactionError, Errors\TransactionErrorDecoder
Auto compute-budget + priority fee Simulate → derive CU limit → inject setComputeUnitLimit + setComputeUnitPrice on build Fees\AutoComputeBudget, Fees\PriorityFeeStrategy, TransactionBuilder::withAutoComputeBudget
In-memory RPC stub + Pest macros InMemoryRpcStub::script([...]) swaps the RPC client; toBeConfirmed / toHaveCustomCode / toBeInstructionError expectations — works in any test runner, Laravel not required Testing\InMemoryRpcStub, Testing\PestExpectations
Laravel facade + queue job + artisan commands Lives in the sister wrapper sandermuller/laravel-solana-sdk: Solana::fake(), ConfirmTransactionJob::dispatch($sig, $lvbh), env-driven config, 7 artisan commands (balance, account, transaction, …) (wrapper)
PDA / ATA helpers One-line Pda::find + Ata::derive (Token-2022 aware via Ata::derive2022) Util\Pda, Util\Ata
Anchor Parse any Anchor IDL at runtime → typed TransactionInstruction builders Anchor\AnchorIdl

Who this is for


Install

The package self-registers SanderMuller\SolanaPhpSdk\ServiceProvider via Laravel's package discovery. Standalone PHP doesn't need anything extra — see "Outside Laravel" below.

Requirements: PHP 8.3+ with ext-sodium enabled (every mainstream PHP distro ships it). Composer pulls in paragonie/sodium_compat as a polyfill backup.

Building a Laravel app? Install the sister wrapper instead — it adds the Solana facade, ConfirmTransactionJob, env-driven config, and 7 artisan commands (balance, account, transaction, fees, health, …) on top of this SDK:

Repo: https://github.com/SanderMuller/laravel-solana-sdk. You get this SDK as a transitive dep — no need to require both.


5-minute quickstart

We'll go from zero to a signed-and-broadcast SOL transfer on devnet.

1. Generate (or load) a keypair

Store the secret bytes somewhere safe if you want to reuse this wallet:

2. Get some devnet SOL

3. Check your balance

4. Send SOL to someone

Click the URL — your transaction is on-chain.

Sign from a KMS / HSM / hardware wallet

For hosts that cannot expose secret bytes to PHP (KMS-backed keys, Ledger devices, remote signing services), implement Contracts\MessageSigner:

For the in-process case, wrap a Keypair in Signing\InMemoryMessageSigner to get the same interface.

Sketch: HashiCorp Vault Transit
Sketch: Ledger hardware wallet

The Ledger Solana app expects a base58-derivation-path-prefixed APDU. Wrap any USB/HID transport (e.g. via a sidecar process bridged over stdio) and implement signMessage() as a single INS_SIGN_MESSAGE APDU round-trip.

Sanitize-safe builder

Most transaction failures across Solana SDKs hit the same opaque error: "Transaction failed to sanitize accounts offsets correctly". The fluent TransactionBuilder catches the causes locally so you never see that message:

build() throws UnsanitizedTransactionException if the fee payer is missing, the blockhash is missing, an instruction marks an account isSigner with no matching keypair, or two instructions disagree on whether the same account is a signer. Every detected reason is surfaced at once on $exception->reasons.

One-shot send-and-confirm

Most apps want both steps in one call, with blockhash-expiry built in:

The helper fetches getLatestBlockhash, signs, sends, and polls getSignatureStatuses until the commitment is reached or the blockhash expires — no manual retry loop.


Core concepts (the 90-second glossary)

Term Plain English
Lamport Smallest unit of SOL. 1 SOL = 1 000 000 000 (10⁹) lamports.
Pubkey / address 32 bytes, base58-encoded. Identifies a wallet, token mint, program, anything.
Keypair Pubkey + 64-byte Ed25519 secret. Sign things with the secret. Never log it.
Blockhash Recent slot hash that anchors a transaction in time. Expires in ~60–90 s. The SDK fetches one for you if you don't supply one.
Instruction One call to a program: program id + ordered accounts + opaque data bytes.
Transaction One or more instructions, signed by one or more keypairs, submitted atomically.
Commitment How sure you are the network agrees: processed (fastest, can roll back) → confirmedfinalized (irreversible).
RPC The HTTP JSON-RPC endpoint at https://api.mainnet-beta.solana.com (or devnet/testnet). Call getBalance, sendTransaction, etc.
PubSub The matching WebSocket endpoint at wss://api.mainnet-beta.solana.com. Subscribe and get pushed events.
Program Solana's word for a smart contract. Has a fixed pubkey.
SPL Token The token standard. Every fungible / NFT token is an account owned by the SPL Token program.
Anchor A Rust framework most Solana programs are written in. Ships an "IDL" JSON describing its instructions — point this SDK at one and you can call any Anchor program.

Common recipes

Read an account

Legacy $connection->getAccountInfo(...) still returns the raw RPC array.

Read multiple accounts at once

List the SPL Token accounts owned by a wallet

Paginate a large program scan

For programs with too many accounts to fetch in a single getProgramAccounts round-trip, partition the scan by account dataSize. The generator emits a ProgramAccount per row across one RPC call per bucket:

Scan a program for accounts matching a filter

GpaFilter::memcmp() accepts a PublicKey, Buffer, or raw base58 string — the most common drift point across Solana SDKs (offset / encoding swap) is locked in the builder.

Look up recent signatures for an address

Watch a signature land (WebSocket)

Survive socket drops

Long-running consumers (indexers, queue workers) can opt in to transparent reconnect — the client respawns the socket, replays every active subscription, and resumes yielding notifications without the caller noticing the gap:

Backoff is exponential with full jitter (baseDelayMs * 2^attempt, randomly shrunk to avoid thundering-herd on a cluster outage). Subscription ids change across the reconnect — the new id ships inside each notification's subscription field, so don't key per-id state on the integer if you enable this.

Add a memo to a transaction

The Memo program writes raw UTF-8 bytes into the transaction log so off-chain indexers can correlate transactions with application data. signers is optional — list any public keys that must be verified as transaction signers (Memo v2 behaviour).

Pay the priority fee the network is currently asking

Samples getRecentPrioritizationFees and returns the requested percentile in micro-lamports per compute unit. Returns 0 when the network is idle — no fee is necessary in that regime.

Token-2022 mint extensions

Memo-transfer (require a Memo instruction in every incoming transfer):

Send a Token-2022 transfer

Token-2022 inherits every core discriminator from legacy SPL Token — the program-id is the only difference. The ATA address differs between the two programs even for the same (owner, mint) pair, so derive it through $program->getAssociatedTokenAddressSync() rather than reusing a legacy-Token ATA.

Build a v0 transaction with an Address Lookup Table

Use the resulting lookupTableAddress as an AddressLookupTableAccount when compiling a MessageV0.

Verify an Ed25519 signature

Call an Anchor program from its IDL

Supported IDL types: every primitive in the Anchor 0.30 spec (u8..u64, i8..i64, f32/f64, bool, string, bytes, pubkey) plus vec<T>, array<T, N>, and option<T>. User-defined struct types raise a clear validation error so you pre-encode them.


Using with Laravel

This SDK works inside a Laravel app out of the box via auto-discovery — Connection resolves straight from the container. For the full Laravel-flavoured experience (facade, queue job, env-driven config, artisan commands), install the wrapper instead:

What the wrapper adds Why it's separate from this SDK
Solana facade with 62 typed @method declarations Laravel-only contract; framework-agnostic SDK shouldn't ship Facade subclasses
ConfirmTransactionJob (Queueable, Dispatchable) Laravel Queue contracts; events (TransactionConfirmed / TransactionExpired) stay here in the SDK
Env-driven config + php artisan vendor:publish Laravel config publishing
7 artisan commands: solana:balance, solana:account, solana:transaction, solana:fees, solana:health, solana:airdrop, solana:tokens Laravel Console contracts
Pre-wired Solana::fake() for tests One-liner over this SDK's InMemoryRpcStub

Repo: https://github.com/SanderMuller/laravel-solana-sdk. The wrapper requires this SDK as a transitive dep — install just the wrapper, not both.


Outside Laravel

The SDK doesn't require a Laravel app. Use the bootstrap helper:

The config file lives at config/solana-php-sdk.php once you publish it (php artisan vendor:publish --tag=solana-php-sdk-config inside Laravel, or copy the package's default) and defines the network and SPL Token program id.


Reference — every typed RPC method on Connection

Click to expand **Cluster / node info** — `getSlot`, `getTransactionCount`, `getFirstAvailableBlock`, `getGenesisHash`, `getHealth`, `getVersion`, `getIdentity`, `getClusterNodes`, `getEpochInfo`, `getEpochSchedule`, `getHighestSnapshotSlot`, `minimumLedgerSlot`, `getMaxRetransmitSlot`, `getMaxShredInsertSlot`, `getSlotLeader`, `getSlotLeaders`. **Blocks / slots** — `getBlockHeight`, `getBlock`, `getBlocks`, `getBlocksWithLimit`, `getBlockTime`, `getBlockCommitment`, `getBlockProduction`, `getLeaderSchedule`, `isBlockhashValid`, `getLatestBlockhash`, `getFeeForMessage`, `getRecentPrioritizationFees`, `getRecentPerformanceSamples`. **Accounts** — `getAccountInfo`, `getBalance`, `getMultipleAccounts`, `getProgramAccounts`, `getMinimumBalanceForRentExemption`, `getLargestAccounts`. **Transactions / signatures** — `getTransaction`, `sendTransaction`, `sendRawTransaction`, `sendVersionedTransaction`, `simulateTransaction`, `getSignaturesForAddress`, `getSignatureStatuses`, `confirmTransaction`, `requestAirdrop`. **Tokens** — `getTokenAccountBalance`, `getTokenSupply`, `getTokenAccountsByOwner`, `getTokenAccountsByDelegate`, `getTokenLargestAccounts`. **Stake / vote / supply** — `getSupply`, `getVoteAccounts`, `getInflationGovernor`, `getInflationRate`, `getInflationReward`, `getStakeMinimumDelegation`, `getStakeActivation`. Any method not yet wrapped is reachable via `SolanaRpcClient::call($method, $params)`.

Reference — PubSub subscriptions

SolanaPubSubClient covers every documented WebSocket method: accountSubscribe, signatureSubscribe, slotSubscribe, rootSubscribe, logsSubscribe, programSubscribe, voteSubscribe, blockSubscribe. Use the generic subscribe(method, params) for anything else.

The constructor accepts a clientFactory: Closure(): WebSocket\Client so tests can inject a scripted-reply double instead of opening a real socket.


Troubleshooting

Account not found when reading a fresh wallet. Solana doesn't allocate storage until the first deposit. Airdrop / transfer something in first, or catch AccountNotFoundException.

Transaction simulation failed: Blockhash not found. The blockhash you attached has expired (~60–90 s). Call getLatestBlockhash() again and rebuild the transaction.

Transaction signature verification failed. You signed with the wrong keypair, or modified the transaction after signing. Re-sign after every mutation. Confirm feePayer matches your first signer.

SolanaPubSubClient blocks forever in listen(). Pass maxEvents: to stop after N events, or wrap the loop in a deadline and call close().

PublicKey::verify() returning false even with the right key. Solana signatures are over the raw message bytes, not a hash. Pass the exact bytes you signed, with no JSON-encoding or string interpolation in between.

Airdrop ignored. Devnet rate-limits per IP and per recipient. Wait a few minutes or use a faucet website.


Examples

Runnable scripts under examples/:

Each script is standalone — composer install then php examples/quickstart-transfer.php.


Comparison to other Solana clients

Capability this SDK attestto/solana-php-sdk Solnet (.NET) @solana/kit (TS)
Typed RPC method coverage ~90 % basic full full
WebSocket PubSub ✅ full
Anchor IDL runtime builder partial
V0 / ALT transactions
SNS (name service) community community
Static analysis posture PHPStan max + bleeding edge + strict none

Compared to the canonical Solana SDKs across all languages

This SDK is built against the recurring pain points operators hit in @solana/web3.js, @solana/kit, solana-py / solders, solana-go, and solana-sdk / anchor-client. The matrix below is the short version; see the rationale beneath it.

Capability this SDK @solana/kit (TS) @solana/web3.js (TS) solana-py + solders solana-go solana-sdk + anchor-client (Rust)
Pluggable RPC transports (fallback / round-robin / retry) partial
Structured SendTransactionError (decoded InstructionError, logs, units) partial partial
Auto compute-unit limit + priority-fee injection on build
Sanitize-safe transaction builder ✅ (type-level)
KMS / HSM / hardware-wallet signer abstraction community community
Queue-based confirmation + lifecycle events ✅ (via wrapper)
In-process test fakes + assertion helpers ✅ (Pest macros in SDK; Solana::fake() in wrapper) partial partial partial
Token-2022 extensions partial partial partial partial

What we built against


Roadmap

Tracked separately as GitHub issues; the high-level next steps are:

Where to ask for help


Development

Contributing

Issues and PRs welcome. Please run composer qa before opening a PR.

License

MIT — see LICENSE.


All versions of solana-php-sdk with dependencies

PHP Build Version
Package Version
Requires php Version ^8.3
ext-sodium Version *
illuminate/collections Version ^11.31 || ^12.0 || ^13.0
illuminate/container Version ^11.31 || ^12.0 || ^13.0
illuminate/http Version ^11.31 || ^12.0 || ^13.0
illuminate/support Version ^11.31 || ^12.0 || ^13.0
paragonie/sodium_compat Version ^2.1
phrity/websocket Version ^3.5
stephenhill/base58 Version ^1.1
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package sandermuller/solana-php-sdk contains the following files

Loading the files please wait ...