Comparing glam with surfpool

Author

@0xinit

Stars

53

Repository

0xinit/cryptoskills

skills/glam/SKILL.md

GLAM Protocol Skill

GLAM provides programmable investment infrastructure on Solana: vaults with access control, DeFi integrations, and tokenization.

Quick Start

# Install CLI
npm install -g @glamsystems/glam-cli

# Configure (~/.config/glam/config.json)
cat > ~/.config/glam/config.json << 'EOF'
{
  "keypair_path": "~/.config/solana/id.json",
  "json_rpc_url": "https://api.mainnet-beta.solana.com"
}
EOF

# Create vault, set active, enable integrations, verify
glam-cli vault create ./vault-template.json
glam-cli vault set <VAULT_STATE_PUBKEY>
glam-cli integration enable JupiterSwap KaminoLend
glam-cli vault view

Critical: Integration Enablement

You MUST enable integrations BEFORE using them. This is the most common error.

Available: JupiterSwap, DriftProtocol, KaminoLend, KaminoVaults, KaminoFarms, DriftVaults, SplToken, CCTP, GlamMint, Marinade (staging), StakePool (staging), SanctumSingle (staging), SanctumMulti (staging), StakeProgram (staging).

Staging integrations require --bypass-warning.


Workflows

Tokenized Vault Setup

glam-cli vault create ./tokenized-vault-template.json
glam-cli vault set <VAULT_STATE_PUBKEY>
glam-cli integration enable JupiterSwap DriftProtocol KaminoLend
glam-cli manage price                          # Set initial NAV price
glam-cli jupiter set-max-slippage 100          # Configure swap policy

# Optional: delegate trading permissions (protocol-scoped)
glam-cli delegate grant <TRADER_PUBKEY> SwapAny --protocol JupiterSwap
glam-cli delegate grant <TRADER_PUBKEY> Deposit Withdraw CreateModifyOrders CancelOrders --protocol DriftProtocol

# Optional: set timelock (24 hours)
glam-cli timelock set 86400

Drift Trading

glam-cli integration enable DriftProtocol
glam-cli drift-protocol init-user              # Required once
glam-cli drift-protocol deposit 0 1000         # Deposit USDC collateral
glam-cli drift-protocol perp long 0 1 0        # Open position

Kamino Lending

glam-cli integration enable KaminoLend
glam-cli kamino-lend init                      # Required once
glam-cli kamino-lend deposit \
  7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF \
  EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v \
  1000

Decision Tree

GoalIntegrationCommand
Swap tokensJupiterSwapjupiter swap
Lend for yieldKaminoLendkamino-lend deposit
Stake SOL (liquid)Marinade (staging)marinade --bypass-warning stake
Stake SOL (LST)StakePool / SanctumSingle / SanctumMulti (staging)lst --bypass-warning stake <pool> <amount>
Stake SOL (native)StakeProgram (staging)stake --bypass-warning list / deactivate / withdraw
Kamino vaultsKaminoVaultskamino-vaults deposit
Drift vaultsDriftVaultsdrift-vaults deposit
Trade perpsDriftProtocoldrift-protocol init-userdepositperp
Trade spotDriftProtocoldrift-protocol init-userdepositspot
Tokenized vaultvault createmanage price → investors invest subscribe
Manage share tokensSDK only: client.mint.* (freeze, issue, burn, forceTransfer)
Bridge USDCCCTPcctp bridge-usdc <amount> <domain> <dest> (0=ETH, 1=AVAX, 2=OP, 3=ARB, 6=BASE, 7=POLYGON)
Timelocktimelock set <seconds>

Common Errors

ErrorSolution
"Signer is not authorized"Check vault view for owner; grant delegate if needed
"Integration not enabled"integration enable <NAME>
"Asset not in allowlist"vault allowlist-asset <MINT>
"User not initialized"drift-protocol init-user or kamino-lend init
"No route found"Try smaller amount; check token liquidity
"Slippage exceeded"Increase --slippage-bps or reduce amount
"Insufficient collateral"drift-protocol deposit more
"Account is frozen"SDK: client.mint.setTokenAccountsStates()
"Missing jupiter_api_key"Add jupiter_api_key to config.json

See troubleshooting for detailed solutions.


Common Mints

TokenAddress
SOLSo11111111111111111111111111111111111111112
USDCEPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
USDTEs9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB
mSOLmSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So
jitoSOLJ1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn

SDK Quick Start

import {
  GlamClient,
  WSOL,
  USDC,
  getProgramAndBitflagByProtocolName,
} from "@glamsystems/glam-sdk";
import { BN } from "@coral-xyz/anchor";

const client = new GlamClient({ wallet });

// Create vault
const { vaultPda } = await client.vault.create({
  name: "My Vault",
  assets: [WSOL, USDC],
});

// Enable Jupiter integration
const perms = getProgramAndBitflagByProtocolName();
const [program, bitflag] = perms["JupiterSwap"];
await client.access.enableProtocols(vaultPda, program, parseInt(bitflag, 2));

// Swap
await client.jupiterSwap.swap(vaultPda, {
  inputMint: USDC,
  outputMint: WSOL,
  amount: new BN(100_000_000),
  slippageBps: 50,
});

Reference

Author

@0xinit

Stars

53

Repository

0xinit/cryptoskills

skills/surfpool/SKILL.md

Surfpool - Solana Development Environment

The definitive guide for Surfpool - where developers start their Solana journey. A drop-in replacement for solana-test-validator that enables local program simulation using Mainnet accounts fetched just-in-time.

What is Surfpool?

Surfpool is a comprehensive development environment that combines local-first testing with real Mainnet data access:

  • Mainnet Forking - Clone accounts, programs, and token balances from Mainnet instantly
  • Cheatcodes - Special RPC methods for time travel, balance manipulation, and state control
  • Infrastructure as Code - Reproducible, auditable deployments using txtx DSL
  • Surfpool Studio - Embedded dashboard with transaction inspection and profiling
  • Universal Faucet - Get SOL, USDC, USDT, BONK from a single interface

Key Benefits

FeatureDescription
Instant BootNo 2TB snapshots, runs on Raspberry Pi
Lazy ForkingCopy-on-read strategy pulls mainnet data as needed
Full CompatibilityWorks with solana-cli, Anchor, wallets, explorers
Zero ConfigAuto-detects Anchor projects and deploys programs

Statistics

  • 460+ GitHub stars
  • 100+ forks
  • Apache 2.0 license
  • Current version: v1.0.0

Installation

Automated Installer (Recommended)

curl -sL https://run.surfpool.run/ | bash

Homebrew (macOS)

brew install txtx/taps/surfpool

From Source

git clone https://github.com/txtx/surfpool.git
cd surfpool
cargo surfpool-install

Docker

docker pull surfpool/surfpool
docker run -p 8899:8899 -p 18488:18488 surfpool/surfpool

Quick Start

Start Local Network

# Start with default configuration
surfpool start

# Start with custom RPC source
surfpool start -u https://api.mainnet-beta.solana.com

# Start without terminal UI
surfpool start --no-tui

# Start with debug logging
surfpool start --debug

Access Points

ServiceURLDescription
RPC Endpointhttp://127.0.0.1:8899Standard Solana RPC
WebSocketws://127.0.0.1:8900Real-time subscriptions
Surfpool Studiohttp://127.0.0.1:18488Web dashboard

CLI Commands

surfpool start

Start the local Surfnet network.

surfpool start [OPTIONS]

Options:

OptionDefaultDescription
-m, --manifest-file-path./Surfpool.tomlPath to manifest file
-p, --port8899RPC port
-o, --host127.0.0.1Host address
-s, --slot-time400Slot time in ms
-u, --rpc-urlhttps://api.mainnet-beta.solana.comSource RPC URL
--no-tui-Disable terminal UI
--debug-Enable debug logs
--no-deploy-Disable auto deployments
-r, --runbookdeploymentRunbooks to execute
-a, --airdrop-Pubkeys to airdrop
-q, --airdrop-amount10000000000000Airdrop amount (lamports)
-k, --airdrop-keypair-path-Keypair path for airdrop
--no-explorer-Disable explorer

Example Usage

# Start with airdrop to specific address
surfpool start -a YOUR_PUBKEY -q 100000000000

# Start with custom slot time (faster blocks)
surfpool start -s 100

# Start with specific runbook
surfpool start -r deployment -r setup

Surfpool.toml Configuration

Create a Surfpool.toml in your project root:

[network]
slot_time = 400
epoch_duration = 432000
rpc_url = "https://api.mainnet-beta.solana.com"

[behavior]
# Fork from mainnet genesis
genesis = false
# Fork from specific point
point_fork = true

[accounts]
# Pre-clone specific accounts
clone = [
  "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",  # Token Program
  "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", # ATA Program
]

[programs]
# Auto-deploy local programs
deploy = ["./target/deploy/my_program.so"]

[airdrop]
# Default airdrop recipients
addresses = ["YOUR_PUBKEY"]
amount = 10000000000000  # 10,000 SOL

Cheatcodes

Surfpool provides special RPC methods for advanced state manipulation during testing.

Account Manipulation

surfnet_setAccount

Set arbitrary account data:

await connection.send("surfnet_setAccount", [
  {
    pubkey: "AccountPubkey...",
    lamports: 1000000000,
    data: "base64EncodedData",
    owner: "OwnerPubkey...",
    executable: false,
  },
]);

surfnet_setTokenAccount

Create or modify token accounts:

await connection.send("surfnet_setTokenAccount", [
  {
    owner: "OwnerPubkey...",
    mint: "MintPubkey...",
    tokenProgram: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
    update: {
      amount: "1000000000",
      delegate: null,
      state: "initialized",
    },
  },
]);

surfnet_cloneProgramAccount

Clone a program from mainnet:

await connection.send("surfnet_cloneProgramAccount", [
  {
    source: "SourceProgramPubkey...",
    destination: "DestinationPubkey...",
  },
]);

surfnet_resetAccount

Reset account to mainnet state:

await connection.send("surfnet_resetAccount", [
  {
    pubkey: "AccountPubkey...",
    includeOwnedAccounts: true,
  },
]);

Time Control

surfnet_timeTravel

Advance network time:

await connection.send("surfnet_timeTravel", [
  {
    epoch: 100,
    slot: 50000,
    timestamp: 1700000000,
  },
]);

surfnet_pauseClock / surfnet_resumeClock

Control block production:

// Pause
await connection.send("surfnet_pauseClock", []);

// Resume
await connection.send("surfnet_resumeClock", []);

surfnet_advanceClock

Advance clock incrementally:

await connection.send("surfnet_advanceClock", [
  { slots: 100 },
]);

Transaction Profiling

surfnet_profileTransaction

Profile transaction execution:

const result = await connection.send("surfnet_profileTransaction", [
  {
    transaction: "base64EncodedTx",
    tag: "my-test-tag",
  },
]);

console.log("Compute units:", result.computeUnits);
console.log("Account changes:", result.accountChanges);

surfnet_getProfileResults

Get profiling results by tag:

const results = await connection.send("surfnet_getProfileResults", [
  { tag: "my-test-tag" },
]);

Network Control

surfnet_resetNetwork

Reset entire network to initial state:

await connection.send("surfnet_resetNetwork", []);

surfnet_getClock

Get current network time:

const clock = await connection.send("surfnet_getClock", []);
console.log("Slot:", clock.slot);
console.log("Epoch:", clock.epoch);
console.log("Timestamp:", clock.timestamp);

Surfpool Studio

Access the web dashboard at http://127.0.0.1:18488 for:

  • Transaction Inspector - View transaction details with byte-level diffs
  • Account Browser - Explore account state and history
  • Compute Profiler - Analyze compute unit usage per instruction
  • Universal Faucet - Request SOL and tokens
  • Network Status - Monitor slots, epochs, and block production

Infrastructure as Code

Surfpool integrates txtx DSL for reproducible deployments.

Runbook Structure

# deployment.tx

// Define signers
signer "deployer" "svm::secret_key" {
  secret_key = env.DEPLOYER_KEY
}

// Deploy program
action "deploy_program" "svm::deploy_program" {
  program_path = "./target/deploy/my_program.so"
  signer = signer.deployer
}

// Initialize program
action "initialize" "svm::send_transaction" {
  transaction {
    instruction {
      program_id = action.deploy_program.program_id
      data = encode_instruction("initialize", {})
    }
  }
  signers = [signer.deployer]
}

Running Runbooks

# Run specific runbook
surfpool start -r deployment

# Run in unsupervised mode
surfpool start -r deployment --unsupervised

Scenarios and Fixtures

Scenarios

Define account state sequences for testing:

await connection.send("surfnet_registerScenario", [
  {
    name: "high-volume-trading",
    slots: [
      {
        slot: 100,
        accounts: {
          "PoolPubkey...": { lamports: 1000000000000 },
        },
      },
      {
        slot: 200,
        accounts: {
          "PoolPubkey...": { lamports: 500000000000 },
        },
      },
    ],
  },
]);

Fixtures

Export transaction fixtures for reproducible tests:

const fixture = await connection.send("surfnet_exportSnapshot", [
  {
    transaction: "txSignature...",
    format: "json",
  },
]);

// Save fixture for CI/CD
fs.writeFileSync("fixtures/my-test.json", JSON.stringify(fixture));

Integration with Anchor

Surfpool auto-detects Anchor projects and handles deployment:

# In an Anchor project directory
surfpool start
# Programs in target/deploy/ are automatically deployed

Testing with Anchor

import * as anchor from "@coral-xyz/anchor";

describe("My Program", () => {
  // Use local Surfnet
  const provider = anchor.AnchorProvider.local("http://127.0.0.1:8899");
  anchor.setProvider(provider);

  it("works with mainnet state", async () => {
    // Your tests automatically have access to mainnet accounts
  });
});

Best Practices

1. Use Cheatcodes for Setup

// Set up test state before each test
beforeEach(async () => {
  await connection.send("surfnet_resetNetwork", []);
  await connection.send("surfnet_setTokenAccount", [...]);
});

2. Profile Critical Paths

// Tag transactions for profiling
const result = await connection.send("surfnet_profileTransaction", [
  { transaction: tx, tag: "swap-operation" },
]);

expect(result.computeUnits).toBeLessThan(200000);

3. Use Scenarios for Edge Cases

// Test with specific mainnet conditions
await connection.send("surfnet_registerScenario", [
  { name: "low-liquidity", slots: [...] },
]);

4. Export Fixtures for CI

// Create reproducible test fixtures
const fixture = await connection.send("surfnet_exportSnapshot", [...]);

Resources

Official Links

Community

Tutorials

Skill Structure

surfpool/
├── SKILL.md                    # This file
├── resources/
│   ├── cheatcodes.md           # Complete cheatcodes reference
│   ├── cli-reference.md        # CLI commands reference
│   └── github-repos.md         # Repository links
├── examples/
│   ├── basic/
│   │   └── getting-started.ts  # Basic setup example
│   ├── cheatcodes/
│   │   └── state-manipulation.ts # Cheatcode examples
│   └── iac/
│       └── deployment.tx       # Infrastructure as Code example
├── templates/
│   ├── Surfpool.toml           # Configuration template
│   └── test-setup.ts           # Test setup template
└── docs/
    └── troubleshooting.md      # Common issues

AI Skill Finder

Ask me what skills you need

What are you building?

Tell me what you're working on and I'll find the best agent skills for you.