Docs

Installation

How to add the PerpCity Rust SDK to your project.

Prerequisites

  • Rust 1.85+ (2024 edition)
  • A wallet private key
  • Access to a Base chain RPC endpoint
  • Tokio async runtime

Add as a Dependency

Add to your Cargo.toml:

[dependencies]
perpcity-sdk = "0.1"
alloy = "1"
tokio = { version = "1", features = ["full"] }

Environment Configuration

Create a .env file in your project root:

RPC_URL=https://your-rpc-endpoint.example/v2/YOUR_KEY
PRIVATE_KEY=0xYOUR_PRIVATE_KEY
PERP_MANAGER_ADDRESS=0xPERP_MANAGER
USDC_ADDRESS=0xUSDC

Never commit your .env file to version control. Add it to .gitignore to protect your private key.

Basic Setup

use alloy::primitives::Address;
use alloy::signers::local::PrivateKeySigner;
use perpcity_sdk::{PerpClient, Deployments};
use perpcity_sdk::transport::{TransportConfig, Strategy};

#[tokio::main]
async fn main() -> perpcity_sdk::Result<()> {
    let rpc_url = std::env::var("RPC_URL").expect("RPC_URL required");
    let private_key = std::env::var("PRIVATE_KEY").expect("PRIVATE_KEY required");
    let perp_manager = std::env::var("PERP_MANAGER_ADDRESS").expect("PERP_MANAGER_ADDRESS required");
    let usdc = std::env::var("USDC_ADDRESS").expect("USDC_ADDRESS required");

    let signer: PrivateKeySigner = private_key.parse()?;

    let transport = TransportConfig::new(vec![rpc_url])
        .strategy(Strategy::LatencyBased)
        .build()?;

    let deployments = Deployments {
        perp_manager: perp_manager.parse::<Address>()?,
        usdc: usdc.parse::<Address>()?,
        ..Default::default()
    };

    let mut client = PerpClient::new_base_mainnet(transport, signer, deployments)?;

    // Required: initialize nonce and gas before trading
    client.sync_nonce().await?;
    client.refresh_gas().await?;
    client.ensure_approval(None).await?;

    // Verify connection
    let perp_id: B256 = "0xYOUR_PERP_ID".parse()?;
    let config = client.get_perp_config(perp_id).await?;
    println!("Mark price: {:.2}", config.mark);

    Ok(())
}

Always call sync_nonce(), refresh_gas(), and ensure_approval() before your first transaction. These initialize the lock-free nonce tracker, gas cache, and USDC spending approval.

Multi-Endpoint Transport

For production HFT setups, configure multiple RPC endpoints with failover:

let transport = TransportConfig::new(vec![
    "https://primary-rpc.com".into(),
    "https://fallback-rpc.com".into(),
    "https://backup-rpc.com".into(),
])
.strategy(Strategy::LatencyBased)       // Route to fastest endpoint
.request_timeout(Duration::from_secs(2))
.build()?;

Available strategies:

StrategyDescription
RoundRobinCycle through endpoints sequentially
LatencyBasedRoute to the lowest-latency healthy endpoint (default)
Hedged { fan_out }Fan out to N endpoints, take the fastest response

Release Profile

For production builds, add to your Cargo.toml:

[profile.release]
lto = "fat"
codegen-units = 1
panic = "abort"
strip = "symbols"

Build Commands

cargo build                # Debug build
cargo build --release      # Optimized release build
cargo test                 # Run tests
cargo run --example quickstart  # Run quickstart example

Next Steps

  • Browse the API Reference for all types, functions, and HFT infrastructure
  • Check the examples for full trading workflows