← スキル一覧に戻る
solana
Ghostspeak / GhostSpeak
⭐ 2🍴 3📅 2026年1月13日
AI Agent Commerce Protocol on Solana - enabling autonomous agents to trade services and exchange value on Solana blockchain with sub-second finality
SKILL.md
# Expert Solana Development Skill
Comprehensive, expert-level guide for Solana blockchain development. Current as of December 2025.
## When to Use This Skill
Consult this skill and its reference documents when:
- Building Solana applications (web, mobile, backend)
- Writing or auditing Solana smart contracts (programs)
- Integrating DeFi protocols (Jupiter, Raydium, Pump.fun)
- Creating or managing NFTs and tokens
- Building AI agents that interact with Solana
- Optimizing transactions for speed and cost
- Understanding MEV and transaction ordering
## Reference Documents
This skill includes detailed reference documents in `/references/`:
| Document | Purpose |
|----------|---------|
| `solana-kit-gill.md` | @solana/kit v2 API, Gill SDK, React hooks |
| `solana-agent-kit.md` | AI agent development, plugin system |
| `defi-integration.md` | Jupiter, Pump.fun, Raydium, Helius |
| `nft-token-extensions.md` | Metaplex, Bubblegum, Token-2022 |
| `mobile-development.md` | Solana App Kit, wallet adapters |
| `anchor-programs.md` | Smart contract development |
| `testing-security.md` | LiteSVM, security patterns |
| `transaction-optimization.md` | Priority fees, Jito bundles, MEV |
---
## Technology Stack (December 2025)
### Current Standards
| Category | Tool | Version | Status |
|----------|------|---------|--------|
| Client SDK | @solana/kit | 2.x | **Current Standard** |
| High-Level SDK | Gill | Latest | **Recommended** |
| Legacy SDK | @solana/web3.js | 1.x | Maintenance only |
| Smart Contracts | Anchor | 0.32.1 | **Industry Standard** |
| Client Generation | Codama | 1.1.x | **Standard Tooling** |
| AI Agents | Solana Agent Kit | V2 | Plugin architecture |
| Mobile | Solana App Kit | Latest | React Native |
| NFTs | Metaplex Core | Latest | Next-gen standard |
| cNFTs | Bubblegum v2 | Latest | Compressed NFTs |
| Tokens | Token-2022 | Current | Extensions enabled |
| DeFi Aggregator | Jupiter V6 | Current | 30+ DEXes |
| Infrastructure | Helius | Current | DAS API, RPC |
| MEV | Jito | Current | 95%+ stake coverage |
| Testing | LiteSVM | Latest | Replaces Bankrun |
### Solana Runtime
- **Validator Client**: Agave (formerly Solana Labs) / Jito-Solana / Firedancer
- **Solana CLI**: 3.0.x
- **Compute Budget**: 1.4M CU per transaction, 48M CU per block
- **Transaction Size**: 1,232 bytes (IPv6 MTU)
- **Account Limit**: ~64 accounts per transaction (use ALTs for more)
---
## Quick Start Patterns
### TypeScript/JavaScript Application
```bash
# Recommended: Gill SDK (simpler API over @solana/kit)
pnpm add gill @gillsdk/react
# Direct @solana/kit usage
pnpm add @solana/kit
# Generate program clients
pnpm add -D @codama/nodes-from-anchor @codama/renderers-js
npx codama init
npx codama run js
```
### Smart Contract Development
```bash
# Install Solana toolchain (all dependencies)
curl --proto '=https' --tlsv1.2 -sSfL https://solana-install.solana.workers.dev | bash
# Verify installation
solana --version # 3.0.x
anchor --version # 0.32.1
# Create new Anchor program
anchor init my_program
cd my_program
anchor build
anchor test
```
### Mobile Application
```bash
# Scaffold React Native app with all integrations
npx start-solana-app
# Manual setup
npx create-expo-app my-app --template blank-typescript
cd my-app
npm install @solana/web3.js react-native-get-random-values
```
### AI Agent
```bash
pnpm add solana-agent-kit
pnpm add @solana-agent-kit/plugin-token
pnpm add @solana-agent-kit/plugin-defi
pnpm add @solana-agent-kit/plugin-nft
```
---
## Core Concepts
### Account Model
Solana uses an account-based model where everything is an account:
```
Account Structure:
├── lamports (u64) - Balance in lamports (1 SOL = 1e9 lamports)
├── data (Vec<u8>) - Arbitrary data (up to 10MB)
├── owner (Pubkey) - Program that owns this account
├── executable (bool) - Whether this is a program
└── rent_epoch (u64) - Epoch when rent was last paid
```
**Key Rules:**
1. Only the owner program can modify an account's data
2. Only the System Program can change owner or allocate lamports
3. Programs are stateless - all state lives in accounts
4. Accounts must be rent-exempt (hold minimum balance) or pay rent
### Program Derived Addresses (PDAs)
PDAs are deterministic addresses derived from seeds and a program ID:
```typescript
import { getProgramDerivedAddress, getAddressEncoder } from '@solana/kit';
const [pda, bump] = await getProgramDerivedAddress({
programAddress: PROGRAM_ID,
seeds: [
Buffer.from('vault'),
getAddressEncoder().encode(userAddress),
],
});
```
**PDA Properties:**
- Off the Ed25519 curve (no private key exists)
- Can only be signed by the deriving program via CPI
- Deterministic - same seeds always produce same address
- Bump seed ensures address is off curve
### Cross-Program Invocation (CPI)
Programs can call other programs:
```rust
// Anchor CPI
use anchor_lang::prelude::*;
use anchor_spl::token::{self, Transfer};
pub fn transfer_tokens(ctx: Context<TransferCtx>, amount: u64) -> Result<()> {
let cpi_accounts = Transfer {
from: ctx.accounts.source.to_account_info(),
to: ctx.accounts.destination.to_account_info(),
authority: ctx.accounts.authority.to_account_info(),
};
let cpi_program = ctx.accounts.token_program.to_account_info();
let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);
token::transfer(cpi_ctx, amount)?;
Ok(())
}
```
---
## Transaction Architecture
### Versioned Transactions
Solana supports two transaction versions:
| Version | Features | Use Case |
|---------|----------|----------|
| Legacy | Original format | Simple transactions |
| V0 | Address Lookup Tables | Complex DeFi, 64+ accounts |
### Address Lookup Tables (ALTs)
ALTs compress account addresses from 32 bytes to 1 byte index:
```typescript
// Without ALT: 64 accounts = 2048 bytes (exceeds 1232 byte limit)
// With ALT: 64 accounts = 64 bytes + ALT reference
```
**When to Use ALTs:**
- Transactions with 20+ accounts
- Complex DeFi operations (Jupiter swaps)
- Batch operations
- Any transaction approaching size limit
### Priority Fees
Priority fees determine transaction ordering within a block:
```typescript
import {
getSetComputeUnitLimitInstruction,
getSetComputeUnitPriceInstruction,
} from '@solana-program/compute-budget';
// Set compute unit limit (estimate actual usage)
const cuLimitIx = getSetComputeUnitLimitInstruction({ units: 200_000 });
// Set priority fee (microlamports per CU)
const cuPriceIx = getSetComputeUnitPriceInstruction({
microLamports: 10_000n // 0.00001 SOL per 1M CU
});
// Add as first instructions
transaction.prepend(cuLimitIx, cuPriceIx);
```
**Fee Estimation:**
```typescript
// Helius Priority Fee API
const feeEstimate = await helius.getPriorityFeeEstimate({
accountKeys: ['JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4'],
options: { recommended: true },
});
```
### Jito Bundles
For MEV protection and atomic multi-transaction execution:
```typescript
// Bundle: Up to 5 transactions executed atomically
// - All succeed or all fail
// - Sequential execution guaranteed
// - Requires tip to Jito validators
const bundle = [
transaction1, // Setup
transaction2, // Main operation
transaction3, // Cleanup + tip
];
// Tip must be in last transaction
const tipIx = SystemProgram.transfer({
fromPubkey: payer,
toPubkey: JITO_TIP_ACCOUNT,
lamports: 10_000, // 0.00001 SOL minimum
});
```
**When to Use Jito Bundles:**
- MEV-sensitive operations (large swaps)
- Multi-transaction atomic operations
- Operations exceeding 1.4M CU limit
- Guaranteed ordering requirements
---
## SDK Quick Reference
### @solana/kit (web3.js v2)
```typescript
import {
createSolanaRpc,
createSolanaRpcSubscriptions,
generateKeyPairSigner,
createTransactionMessage,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
appendTransactionMessageInstruction,
signTransactionMessageWithSigners,
pipe,
address,
lamports,
} from '@solana/kit';
// RPC connection
const rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');
// Generate signer
const signer = await generateKeyPairSigner();
// Build transaction with pipe
const tx = pipe(
createTransactionMessage({ version: 0 }),
(m) => setTransactionMessageFeePayerSigner(signer, m),
(m) => setTransactionMessageLifetimeUsingBlockhash(blockhash, m),
(m) => appendTransactionMessageInstruction(instruction, m),
);
// Sign
const signedTx = await signTransactionMessageWithSigners(tx);
```
### Gill SDK
```typescript
import { createSolanaClient, createTransaction } from 'gill';
import { loadKeypairSignerFromFile } from 'gill/node';
// Simplified client
const { rpc, sendAndConfirmTransaction } = createSolanaClient({
urlOrMoniker: 'mainnet', // or 'devnet', custom URL
});
// Load keypair from Solana CLI
const signer = await loadKeypairSignerFromFile();
// Create transaction with compute budget
const transaction = createTransaction({
version: 'legacy',
feePayer: signer,
instructions: [/* ... */],
latestBlockhash,
computeUnitLimit: 200_000,
computeUnitPrice: 1_000,
});
// Sign and send
const signedTx = await signTransactionMessageWithSigners(transaction);
const signature = await sendAndConfirmTransaction(signedTx);
```
---
## Smart Contract Patterns
### Basic Anchor Program
```rust
use anchor_lang::prelude::*;
declare_id!("YourProgramId11111111111111111111111111111");
#[program]
pub mod my_program {
use super::*;
pub fn initialize(ctx: Context<Initialize>, data: u64) -> Result<()> {
let account = &mut ctx.accounts.my_account;
account.data = data;
account.authority = ctx.accounts.authority.key();
account.bump = ctx.bumps.my_account;
Ok(())
}
pub fn update(ctx: Context<Update>, new_data: u64) -> Result<()> {
let account = &mut ctx.accounts.my_account;
account.data = new_data;
Ok(())
}
}
#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(
init,
payer = authority,
space = 8 + MyAccount::INIT_SPACE,
seeds = [b"my-account", authority.key().as_ref()],
bump
)]
pub my_account: Account<'info, MyAccount>,
#[account(mut)]
pub authority: Signer<'info>,
pub system_program: Program<'info, System>,
}
#[derive(Accounts)]
pub struct Update<'info> {
#[account(
mut,
seeds = [b"my-account", authority.key().as_ref()],
bump = my_account.bump,
has_one = authority
)]
pub my_account: Account<'info, MyAccount>,
pub authority: Signer<'info>,
}
#[account]
#[derive(InitSpace)]
pub struct MyAccount {
pub data: u64,
pub authority: Pubkey,
pub bump: u8,
}
```
### Account Constraints Reference
```rust
#[account(init, payer = x, space = N)] // Initialize new account
#[account(mut)] // Mark as mutable
#[account(has_one = authority)] // Verify field matches
#[account(seeds = [...], bump)] // PDA derivation
#[account(seeds = [...], bump = x.bump)] // Use stored bump
#[account(constraint = x > 0)] // Custom constraint
#[account(close = authority)] // Close account, refund rent
#[account(realloc = N, payer = x)] // Resize account
```
---
## Security Checklist
### Critical Vulnerabilities
1. **Missing Owner Check**
```rust
// BAD: No owner verification
pub user_account: AccountInfo<'info>,
// GOOD: Verify owner
#[account(owner = expected_program)]
pub user_account: Account<'info, UserData>,
```
2. **Missing Signer Check**
```rust
// BAD: No signer verification
pub authority: AccountInfo<'info>,
// GOOD: Require signature
pub authority: Signer<'info>,
```
3. **Arbitrary CPI**
```rust
// BAD: Unverified program
pub external_program: AccountInfo<'info>,
// GOOD: Verify program ID
#[account(address = expected_program_id)]
pub external_program: Program<'info, ExpectedProgram>,
```
4. **Integer Overflow**
```rust
// BAD: Unchecked arithmetic
let result = a + b;
// GOOD: Checked arithmetic
let result = a.checked_add(b).ok_or(ErrorCode::Overflow)?;
```
5. **Reinitialization Attack**
```rust
// BAD: Can be reinitialized
#[account(init_if_needed, ...)]
// GOOD: Explicit initialization check
#[account(init, ...)] // Only works if account doesn't exist
```
### Security Best Practices
- **Always use Anchor** for automatic security checks
- **Validate all accounts** - owner, address, data type
- **Use checked math** for all arithmetic
- **Verify signer relationships** before state changes
- **Close accounts properly** to prevent resurrection
- **Audit CPI targets** - verify program IDs
- **Test with LiteSVM** for edge cases
- **Get professional audits** before mainnet
---
## Testing with LiteSVM
```typescript
// TypeScript
import { LiteSVM } from 'litesvm';
import { Keypair, Transaction, SystemProgram } from '@solana/web3.js';
test('transfer SOL', () => {
const svm = new LiteSVM();
const payer = new Keypair();
// Airdrop
svm.airdrop(payer.publicKey, BigInt(1e9));
// Build transaction
const tx = new Transaction();
tx.add(SystemProgram.transfer({
fromPubkey: payer.publicKey,
toPubkey: receiver,
lamports: 1_000_000n,
}));
tx.recentBlockhash = svm.latestBlockhash();
tx.sign(payer);
// Execute
svm.sendTransaction(tx);
// Assert
const balance = svm.getBalance(receiver);
expect(balance).toBe(1_000_000n);
});
```
```rust
// Rust
use litesvm::LiteSVM;
use solana_keypair::Keypair;
use solana_signer::Signer;
#[test]
fn test_program() {
let mut svm = LiteSVM::new();
// Load program
svm.add_program(program_id, "target/deploy/my_program.so");
// Setup accounts
let payer = Keypair::new();
svm.airdrop(&payer.pubkey(), 10_000_000_000).unwrap();
// Build and send transaction
let tx = Transaction::new_signed_with_payer(
&[instruction],
Some(&payer.pubkey()),
&[&payer],
svm.latest_blockhash(),
);
let result = svm.send_transaction(tx);
assert!(result.is_ok());
}
```
---
## DeFi Integration Patterns
### Jupiter Swap
```typescript
const JUPITER_API = 'https://api.jup.ag/swap/v1';
// Get quote
const quote = await fetch(
`${JUPITER_API}/quote?` +
`inputMint=${SOL_MINT}&` +
`outputMint=${USDC_MINT}&` +
`amount=${lamports}&` +
`slippageBps=50`
).then(r => r.json());
// Get swap transaction
const { swapTransaction } = await fetch(`${JUPITER_API}/swap`, {
method: 'POST',
body: JSON.stringify({
quoteResponse: quote,
userPublicKey: wallet.publicKey.toString(),
dynamicComputeUnitLimit: true,
prioritizationFeeLamports: 'auto',
}),
}).then(r => r.json());
// Execute
const tx = VersionedTransaction.deserialize(
Buffer.from(swapTransaction, 'base64')
);
tx.sign([wallet]);
await connection.sendTransaction(tx);
```
### Pump.fun Integration
```typescript
// Check if token is on bonding curve or migrated
const status = await fetch(
`https://frontend-api.pump.fun/coins/${mint}`
).then(r => r.json());
if (!status.raydium_pool) {
// Still on bonding curve - use Pump.fun
await buyOnPumpFun(mint, solAmount);
} else {
// Migrated - use Jupiter
await jupiterSwap(SOL_MINT, mint, solAmount);
}
```
---
## Infrastructure Setup
### Helius SDK
```typescript
import { createHelius } from 'helius-sdk';
const helius = createHelius({ apiKey: 'YOUR_KEY' });
// DAS API - Get all assets
const assets = await helius.getAssetsByOwner({
ownerAddress: wallet,
page: 1,
limit: 1000,
});
// Priority fee estimation
const fee = await helius.getPriorityFeeEstimate({
accountKeys: [PROGRAM_ID],
options: { recommended: true },
});
// Enhanced transactions
const parsed = await helius.enhanced.getTransactions({
signatures: [signature],
});
```
### Production RPC Configuration
```typescript
// Rate limiting and retry logic
const connection = {
rpcUrl: 'https://mainnet.helius-rpc.com/?api-key=KEY',
async sendWithRetry(tx, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const sig = await this.send(tx);
await this.confirm(sig);
return sig;
} catch (e) {
if (i === maxRetries - 1) throw e;
await sleep(1000 * (i + 1)); // Exponential backoff
}
}
}
};
```
---
## Key Constants
```typescript
// Lamports
const LAMPORTS_PER_SOL = 1_000_000_000n;
// Compute
const MAX_COMPUTE_UNITS = 1_400_000;
const DEFAULT_COMPUTE_UNITS = 200_000;
// Transaction
const MAX_TRANSACTION_SIZE = 1232; // bytes
const MAX_ACCOUNTS_PER_TX = 64; // with ALTs
// Rent
const RENT_PER_BYTE_YEAR = 3480; // lamports
const RENT_EXEMPT_MINIMUM = 890880; // for 0-byte account
// Token decimals
const SOL_DECIMALS = 9;
const USDC_DECIMALS = 6;
const USDT_DECIMALS = 6;
```
---
## Common Errors and Solutions
| Error | Cause | Solution |
|-------|-------|----------|
| `BlockhashNotFound` | Blockhash expired | Fetch new blockhash, retry |
| `InsufficientFunds` | Not enough SOL | Check balance, add funds |
| `AccountNotFound` | Account doesn't exist | Initialize account first |
| `OwnerMismatch` | Wrong program owner | Verify account ownership |
| `ProgramFailed` | CU exceeded / logic error | Increase CU limit, check logs |
| `TransactionTooLarge` | >1232 bytes | Use versioned tx + ALTs |
---
## Environment Variables
```bash
# Required
RPC_URL=https://mainnet.helius-rpc.com/?api-key=YOUR_KEY
PRIVATE_KEY=your_base58_private_key
# Optional
HELIUS_API_KEY=your_helius_key
JUPITER_API_KEY=your_jupiter_key
JITO_AUTH_KEY=your_jito_key
```
---
## Additional Resources
- [Solana Docs](https://solana.com/docs)
- [Anchor Docs](https://anchor-lang.com/docs)
- [Helius Docs](https://docs.helius.dev)
- [Jupiter Docs](https://dev.jup.ag)
- [Metaplex Docs](https://developers.metaplex.com)
- [Gill Docs](https://gill.site/docs)
- [LiteSVM Docs](https://litesvm.github.io/litesvm/)