← Back to list
💰

solana-rpc Checked

Direct Solana blockchain interaction via JSON-RPC — account lookups, token balances, transaction …
💰 Finance & Trading skills By agiprolabs Version v1.0.0 Added 2026-09-20 Updated 2026-10-21 Source ↗
7.5Overall rating
2Views
6Downloads
366Stars

Installation

🤖 Install via AI

Copy the prompt below and send it to your AI assistant (e.g. Claude Code) — it will follow the instructions and install automatically.

Install the "solana-rpc" skill by following the instructions at https://skill123.me/install/solana-rpc.
⌨️ Command line install

Run in your terminal — downloads and installs to ~/.claude/skills/.

curl -fsSL https://skill123.me/install/solana-rpc.sh | bash
📦 Download ZIP

Download the zip and extract it into your skills directory (e.g. ~/.claude/skills/), then restart your session.

⬇ Download v1.0.0 · 17 KB
📊 Static rating
7.5/10
Trigger
7.0
Structure
8.5
Workflow
5.5
Content
8.5
Engineering
7.5
Security
9.0

Six-dimension rubric with reviewer rationale.

View scorecard ↓
🛡 Dynamic test
—

Not live-tested yet — this skill is rated on static analysis only.

About this skill

Direct Solana blockchain interaction via JSON-RPC — account lookups, token balances, transaction submission, and program queries

Solana RPC — Direct Blockchain Interaction

The Solana JSON-RPC API provides direct read/write access to the blockchain. Use it for account state queries, token balance lookups, transaction building and submission, and program account enumeration. This is the low-level foundation when higher-level APIs (Birdeye, Helius, SolanaTracker) don't have the data you need.

Documentation

Direct Solana blockchain interaction via JSON-RPC — account lookups, token balances, transaction submission, and program queries

Solana RPC — Direct Blockchain Interaction

The Solana JSON-RPC API provides direct read/write access to the blockchain. Use it for account state queries, token balance lookups, transaction building and submission, and program account enumeration. This is the low-level foundation when higher-level APIs (Birdeye, Helius, SolanaTracker) don't have the data you need.

Quick Start


import httpx

RPC = os.getenv("SOLANA_RPC_URL", "https://api.mainnet-beta.solana.com")

def rpc_call(method: str, params: list = None) -> dict:
    resp = httpx.post(RPC, json={
        "jsonrpc": "2.0", "id": 1,
        "method": method, "params": params or [],
    }, timeout=30.0)
    return resp.json()

# Get SOL balance
result = rpc_call("getBalance", ["WALLET_PUBKEY"])
sol_balance = result["result"]["value"] / 1e9

# Get latest blockhash
result = rpc_call("getLatestBlockhash")
blockhash = result["result"]["value"]["blockhash"]

RPC Providers

| Provider | Free Tier | Paid | Notes |

|----------|-----------|------|-------|

| Helius | 50K credits/day | $49+/mo | Enhanced RPCs, DAS API |

| QuickNode | Limited | $49+/mo | Multi-chain, WebSocket |

| Triton | No free tier | ~$300+/mo | Yellowstone gRPC bundled |

| Shyft | Limited | $49+/mo | Yellowstone gRPC bundled |

| Alchemy | 300M CU/mo | Scaling | Good free tier |

| Public (mainnet-beta) | Free | — | Rate limited, unreliable |

**Recommendation**: Use Helius or QuickNode for development. Never use public RPC for production trading.

Core Read Methods

### Account & Balance


# SOL balance (in lamports, divide by 1e9 for SOL)
getBalance(pubkey, {commitment: "confirmed"})

# Full account info (data, owner, lamports, executable)
getAccountInfo(pubkey, {encoding: "jsonParsed"})

# Multiple accounts in one call
getMultipleAccounts([pubkey1, pubkey2], {encoding: "jsonParsed"})

### Token Accounts


# All SPL token accounts owned by a wallet
getTokenAccountsByOwner(wallet_pubkey, {
    "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
}, {"encoding": "jsonParsed"})

# Token balance for a specific token account
getTokenAccountBalance(token_account_pubkey)

# Largest token accounts (top holders)
getTokenLargestAccounts(mint_pubkey)

# Total supply of a token
getTokenSupply(mint_pubkey)

### Transaction Data


# Get parsed transaction by signature
getTransaction(signature, {
    "encoding": "jsonParsed",
    "maxSupportedTransactionVersion": 0,
})

# Recent transaction signatures for an address
getSignaturesForAddress(pubkey, {
    "limit": 20,
    "before": "optional_signature",  # pagination cursor
})

# Transaction status
getSignatureStatuses([sig1, sig2])

### Block & Slot


# Current slot
getSlot({commitment: "confirmed"})
View full documentation

Block data

getBlock(slot, {

"encoding": "jsonParsed",

"transactionDetails": "full",

"maxSupportedTransactionVersion": 0,

})

Latest blockhash (needed for tx building)

getLatestBlockhash({commitment: "confirmed"})

Slot leader schedule

getLeaderSchedule()



### Program Accounts

All accounts owned by a program (with filters)

getProgramAccounts(program_pubkey, {

"encoding": "jsonParsed",

"filters": [

{"dataSize": 165}, # Filter by account data size

{"memcmp": { # Filter by data content

"offset": 32,

"bytes": "base58_encoded_value",

}},

],

})



**Warning**: `getProgramAccounts` without filters can return millions of results and timeout. Always use `dataSize` and/or `memcmp` filters.

### Priority Fees

Recent priority fee estimates

getRecentPrioritizationFees([account_pubkey])

Returns array of { slot, prioritizationFee } for recent slots

Minimum rent for account

getMinimumBalanceForRentExemption(data_length)



## Write Methods

### Send Transaction

Send a signed, serialized transaction

sendTransaction(base64_tx, {

"encoding": "base64",

"skipPreflight": False,

"preflightCommitment": "confirmed",

"maxRetries": 3,

})

Simulate before sending

simulateTransaction(base64_tx, {

"encoding": "base64",

"sigVerify": False,

"commitment": "confirmed",

})



### Transaction Confirmation

import time

def confirm_transaction(rpc_url: str, signature: str, timeout: float = 30.0) -> bool:

"""Poll for transaction confirmation."""

start = time.time()

while time.time() - start < timeout:

result = rpc_call("getSignatureStatuses", [[signature]])

statuses = result.get("result", {}).get("value", [None])

if statuses[0] is not None:

status = statuses[0]

if status.get("err"):

return False

if status.get("confirmationStatus") in ("confirmed", "finalized"):

return True

time.sleep(0.5)

return False



## Commitment Levels

| Level | Description | Use When |
|-------|-------------|----------|
| `processed` | Single node confirmation | Speed over safety |
| `confirmed` | Supermajority (2/3+) | **Default for trading** |
| `finalized` | Maximum supermajority + 31 slots | Critical operations |

Always specify commitment explicitly. Default varies by provider.

## Common Patterns

### Get All Token Holdings for a Wallet

def get_wallet_tokens(wallet: str) -> list[dict]:

"""Get all SPL token holdings with metadata."""

result = rpc_call("getTokenAccountsByOwner", [

wallet,

{"programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"},

{"encoding": "jsonParsed"},

])

tokens = []

for acct in result["result"]["value"]:

info = acct["account"]["data"]["parsed"]["info"]

tokens.append({

"mint": info["mint"],

"amount": int(info["tokenAmount"]["amount"]),

"decimals": info["tokenAmount"]["decimals"],

"ui_amount": info["tokenAmount"]["uiAmount"],

})

return [t for t in tokens if t["amount"] > 0]



### Get Top Holders of a Token

def get_top_holders(mint: str) -> list[dict]:

"""Get the 20 largest holders of a token."""

result = rpc_call("getTokenLargestAccounts", [mint])

supply_result = rpc_call("getTokenSupply", [mint])

total_supply = int(supply_result["result"]["value"]["amount"])

holders = []

for acct in result["result"]["value"]:

amount = int(acct["amount"])

holders.append({

"address": acct["address"],

"amount": amount,

"decimals": acct["decimals"],

"ui_amount": acct["uiAmount"],

"percentage": amount / total_supply * 100 if total_supply > 0 else 0,

})

return holders



### Batch RPC Calls

def rpc_batch(calls: list[tuple[str, list]]) -> list[dict]:

"""Execute multiple RPC calls in a single HTTP request."""

payload = [

{"jsonrpc": "2.0", "id": i, "method": method, "params": params}

for i, (method, params) in enumerate(calls)

]

resp = httpx.post(RPC, json=payload, timeout=30.0)

results = resp.json()

results.sort(key=lambda r: r["id"])

return [r.get("result") for r in results]



## Key Program IDs

| Program | ID |
|---------|-----|
| System | `11111111111111111111111111111111` |
| SPL Token | `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA` |
| Token-2022 | `TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb` |
| Associated Token | `ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL` |
| Raydium AMM | `675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8` |
| Raydium CLMM | `CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK` |
| Orca Whirlpool | `whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc` |
| Meteora DLMM | `LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo` |
| PumpFun | `6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P` |
| Jupiter v6 | `JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4` |
| Compute Budget | `ComputeBudget111111111111111111111111111111` |

## When to Use Direct RPC vs Higher-Level APIs

| Need | Use |
|--

Score breakdown

Trigger
7.0
Trigger 7/10 — Well-structured reference with precise RPC method groupings and safety notes such as simulate-before-send and mandatory getProgramAccounts filters; however the frontmatter description lacks explicit when-not boundaries and the file is primarily reference/code snippets rather than a gated step-by-step workflow.
Structure
8.5
Structure 8.5/10
Workflow
5.5
Workflow 5.5/10
Content
8.5
Content 8.5/10
Engineering
7.5
Engineering 7.5/10
Security
9.0
Security 9/10