npm package: @solsdk/relay_sdk
Description: Pumpfun SDK — create, buy, sell tokens with support for Jito bundles and multiple relayer integrations. Rebuilt and fixed pumpdotfun-sdk.
Author: @solsdk
Latest version: 1.5.6

<h3 align="center">@solsdk/relay_sdk</h3>
<p align="center">
  <b>TypeScript SDK for seamless token trading and relay integration</b><br/>
  Create · Buy · Sell · Relay · Jito Bundles
</p>
<p align="center">
  <a href="https://www.npmjs.com/package/@solsdk/relay_sdk"><img alt="npm" src="https://img.shields.io/npm/v/@solsdk/relay_sdk?color=cb3837&logo=npm"></a>
  <a href="LICENSE"><img alt="MIT" src="https://img.shields.io/badge/license-MIT-blue.svg"></a>
</p>

> Modern, robust, and production-ready SDK for PumpFun token trading and relay operations on Solana.  
> ✅ Reliable buy/sell/create flows  
> ✅ Support for the latest event formats  
> ✅ Jito and multiple relay integrations (Astra, Slot, NodeOne, NextBlock)  
> ✅ Works on **devnet** and **mainnet-beta**  
> ✅ ESM & CJS builds for maximum compatibility

## ✨ Features

| Module                | Highlights                                                                                       |
| --------------------- | ------------------------------------------------------------------------------------------------ |
| **`PumpFunSDK`**      | Main SDK class. Wraps Anchor `Program` & `Connection` and initializes all submodules.           |
| **`TradeModule`**     | `createAndBuy`, `buy`, `sell`, transaction builders, slippage helpers                            |
| **`TokenModule`**     | Token metadata creation, ATA management, bonding curve and global account access                 |
| **`PdaModule`**       | PDA helpers: global, event-authority, bonding-curve, metadata, and more                          |
| **`EventModule`**     | Typed Anchor event listeners with automatic deserialization                                      |
| **`JitoModule`**      | Submit Jito bundles for `buyJito`/`sellJito`. Requires `jitoUrl` and `authKeypair` in options   |
| **`AstraModule`**     | Sends `buy`/`sell` transactions via Astra relays. Includes tip transfers and `ping()`           |
| **`SlotModule`**      | Optimized for Slot relays with `buy()`, `sell()` and `ping()`                                   |
| **`NextBlockModule`** | Optimized for NextBlock relays with `buy()`, `sell()` and `ping()`                              |
| **`NodeOneModule`**   | Optimized for NodeOne relays with `buy()`, `sell()` and `ping()`                                |
| **Helper exports**    | `BondingCurveAccount`, `GlobalAccount`, slippage calculators, constants and types                |

> **Note:** Use `ping()` on relay modules (e.g., `sdk.slot.ping()`) periodically to keep upstream relay connections alive.

---

## 📦 Installation

```bash
npm install @solsdk/relay_sdk
```

---

## 🔨 Quick Start

Replace DEVNET_RPC with your preferred Solana RPC endpoint.

```ts
import { Connection, Keypair, PublicKey, LAMPORTS_PER_SOL } from "@solana/web3.js";
import { AnchorProvider, Wallet } from "@coral-xyz/anchor";
import { getAssociatedTokenAddress, getAccount } from "@solana/spl-token";
import { PumpFunSDK, DEFAULT_DECIMALS } from "@solsdk/relay_sdk";

const DEVNET_RPC = "https://api.devnet.solana.com";
const SLIPPAGE_BPS = 100n;
const PRIORITY_FEE = { unitLimit: 250_000, unitPrice: 250_000 };

const secret = JSON.parse(process.env.WALLET!);
const wallet = Keypair.fromSecretKey(Uint8Array.from(secret));

async function printSOL(conn: Connection, pk: PublicKey, label = "") {
  const sol = (await conn.getBalance(pk)) / LAMPORTS_PER_SOL;
  console.log(`${label} SOL:`, sol.toFixed(4));
}

async function getSPLBalance(connection: Connection, mint: PublicKey, owner: PublicKey): Promise<number> {
  try {
    const ata = await getAssociatedTokenAddress(mint, owner);
    const account = await getAccount(connection, ata);
    return Number(account.amount);
  } catch {
    return 0;
  }
}

async function main() {
  const connection = new Connection(DEVNET_RPC, "confirmed");
  const provider = new AnchorProvider(connection, new Wallet(wallet), {
    commitment: "confirmed",
  });
  const sdk = new PumpFunSDK(provider);
  const mint = Keypair.generate();

  await printSOL(connection, wallet.publicKey, "user");

  const img = await import("node:fs/promises").then((fs) =>
    fs.readFile("example/images/test.png")
  );
  const blob = new Blob([img], { type: "image/png" });
  await sdk.trade.createAndBuy(
    wallet,
    mint,
    { name: "DEV-TEST", symbol: "DVT", description: "Devnet demo", file: blob },
    BigInt(0.0001 * LAMPORTS_PER_SOL),
    SLIPPAGE_BPS,
    PRIORITY_FEE
  );
  console.log(
    "Token link →",
    `https://pump.fun/${mint.publicKey}?cluster=devnet`
  );

  await sdk.trade.buy(
    wallet,
    mint.publicKey,
    BigInt(0.0002 * LAMPORTS_PER_SOL),
    SLIPPAGE_BPS,
    PRIORITY_FEE
  );

  const bal = await getSPLBalance(connection, mint.publicKey, wallet.publicKey);
  console.log("Token balance:", bal / 10 ** DEFAULT_DECIMALS);

  await sdk.trade.sell(
    wallet,
    mint.publicKey,
    BigInt(bal),
    SLIPPAGE_BPS,
    PRIORITY_FEE
  );
  await printSOL(connection, wallet.publicKey, "user after sell");
}

main().catch(console.error);
```

---

## 🚀 Advanced Usage

### 🧠 Buy with **Jito**

```ts
import { PumpFunSDK } from "@solsdk/relay_sdk";

const sdk = new PumpFunSDK(provider, {
  jitoUrl: "ny.mainnet.block-engine.jito.wtf",
  authKeypair: wallet,
});

// Jito tip in lamports (0.0005 SOL)
const jitoTip = 500_000;

await sdk.jito!.buyJito(
  wallet,
  mint.publicKey,
  BigInt(0.0002 * LAMPORTS_PER_SOL),
  SLIPPAGE_BPS,
  jitoTip,
  PRIORITY_FEE,
  "confirmed"
);
```

### 💰 Sell with **Jito**

```ts
// Get token balance first
const tokenBalance = await getSPLBalance(connection, mint.publicKey, wallet.publicKey);

await sdk.jito!.sellJito(
  wallet,
  mint.publicKey,
  BigInt(tokenBalance),
  SLIPPAGE_BPS,
  jitoTip,
  PRIORITY_FEE,
  "confirmed"
);
```

---

### 🛰️ Buy with **Slot**, **NodeOne**, **Astra**, or **NextBlock**

> These modules use upstream relayers for ultra-fast transaction submission.  
> They support periodic `ping()` to keep HTTPS connections alive and reduce TLS overhead.

```ts
import { PumpFunSDK, Region } from "@solsdk/relay_sdk";

const sdk = new PumpFunSDK(provider, {
  providerRegion: Region.Frankfurt,
  slotKey: "your-api-key", // or astraKey / nextBlockKey / nodeOneKey
});

// Keep connection alive
await sdk.slot!.ping();

// Tip in lamports (0.0005 SOL)
const tip = 500_000;

// Buy tokens
const signature = await sdk.slot!.buy(
  wallet,
  mint.publicKey,
  BigInt(0.0002 * LAMPORTS_PER_SOL),
  SLIPPAGE_BPS,
  tip,
  PRIORITY_FEE,
  "confirmed"
);
console.log("Buy transaction:", signature);
```

### 💸 Sell with relay modules

```ts
// Get token balance
const tokenBalance = await getSPLBalance(connection, mint.publicKey, wallet.publicKey);

// Sell all tokens
const sellSignature = await sdk.slot!.sell(
  wallet,
  mint.publicKey,
  BigInt(tokenBalance),
  SLIPPAGE_BPS,
  tip,
  PRIORITY_FEE,
  "confirmed"
);
console.log("Sell transaction:", sellSignature);
```

> `AstraModule`, `NodeOneModule`, and `NextBlockModule` follow the same interface: `buy()`, `sell()`, `ping()`  
> Transactions are signed locally and relayed via HTTPS POST (base64-encoded) for speed.

---

## 🧩 What Does `ping()` Do?

Relay modules like `SlotModule`, `AstraModule`, `NodeOneModule`, and `NextBlockModule` implement `ping()`.

Calling `ping()` periodically:

- Prevents connection idle timeouts
- Keeps the relay ready for low-latency submission

```ts
await sdk.astra!.ping();
await sdk.slot!.ping();
```

---

## 🌐 Supported Relay Regions

Each relay provider supports a set of regions for optimal latency. Below are the currently supported regions per provider:

```text
Slot       📍 Frankfurt • New York • Tokyo • Amsterdam • Los Angeles
Astra      📍 Frankfurt • New York • Tokyo • Amsterdam
NodeOne    📍 New York • Tokyo • Amsterdam • Frankfurt
NextBlock  📍 Tokyo • Frankfurt • New York
```

### 🔧 Available Regions

```ts
import { Region } from "@solsdk/relay_sdk";

// Available regions
Region.Frankfurt  // "fra"
Region.NY         // "ny" 
Region.Tokyo      // "tokyo"
Region.Amsterdam  // "ams"
Region.LosAngeles // "la"
```

> Specify `providerRegion` in SDK options to select the regional relay.

---

## 📚 Detailed API Reference

### 🏗️ SDK Initialization

```ts
import { Connection, Keypair } from "@solana/web3.js";
import { AnchorProvider, Wallet } from "@coral-xyz/anchor";
import { PumpFunSDK, Region, PumpOptions } from "@solsdk/relay_sdk";

const connection = new Connection("https://api.mainnet-beta.solana.com");
const wallet = Keypair.fromSecretKey(/* your secret key */);
const provider = new AnchorProvider(connection, new Wallet(wallet), {
  commitment: "confirmed",
});

// Basic initialization
const sdk = new PumpFunSDK(provider);

// With options
const options: PumpOptions = {
  jitoUrl: "ny.mainnet.block-engine.jito.wtf",
  authKeypair: wallet,
  providerRegion: Region.NY,
  astraKey: "your-astra-key",
  slotKey: "your-slot-key",
  nextBlockKey: "your-nextblock-key",
  nodeOneKey: "your-nodeone-key",
  shouldKeepAlive: true
};
const sdkWithOptions = new PumpFunSDK(provider, options);
```

### 🔄 TradeModule Methods

#### `createAndBuy()`
Creates a new token and immediately buys it.

```ts
import { CreateTokenMetadata, PriorityFee } from "@solsdk/relay_sdk";

const mint = Keypair.generate();
const metadata: CreateTokenMetadata = {
  name: "My Token",
  symbol: "MTK",
  description: "A test token",
  file: blob, // Image file as Blob
  twitter: "@mytoken", // optional
  telegram: "t.me/mytoken", // optional
  website: "https://mytoken.com" // optional
};

const priorityFee: PriorityFee = {
  unitLimit: 250_000,
  unitPrice: 250_000
};

const result = await sdk.trade.createAndBuy(
  wallet,                              // creator keypair
  mint,                               // mint keypair
  metadata,                           // token metadata
  BigInt(0.01 * LAMPORTS_PER_SOL),   // buy amount in lamports
  100n,                               // slippage in basis points (1%)
  priorityFee,                        // priority fees
  "confirmed",                        // commitment (optional)
  "confirmed"                         // finality (optional)
);

if (result.success) {
  console.log("Transaction signature:", result.signature);
} else {
  console.error("Error:", result.error);
}
```

#### `buy()`
Buys an existing token.

```ts
const result = await sdk.trade.buy(
  wallet,                              // buyer keypair
  mintPublicKey,                      // token mint address
  BigInt(0.01 * LAMPORTS_PER_SOL),   // buy amount in lamports
  100n,                               // slippage in basis points
  priorityFee                         // priority fees
);
```

#### `sell()`
Sells tokens.

```ts
const tokenBalance = BigInt(1000000); // token amount to sell

const result = await sdk.trade.sell(
  wallet,                              // seller keypair
  mintPublicKey,                      // token mint address
  tokenBalance,                       // token amount to sell
  100n,                               // slippage in basis points
  priorityFee                         // priority fees
);
```

#### Transaction Builders
For advanced users who want to build transactions manually:

```ts
// Get buy instructions
const buyTx = await sdk.trade.getBuyInstructionsBySolAmount(
  wallet.publicKey,
  mintPublicKey,
  BigInt(0.01 * LAMPORTS_PER_SOL),
  100n,
  "confirmed"
);

// Get sell instructions
const sellTx = await sdk.trade.getSellInstructionsByTokenAmount(
  wallet.publicKey,
  mintPublicKey,
  tokenBalance,
  100n,
  "confirmed"
);

// Get create instructions
const createTx = await sdk.trade.getCreateInstructions(
  wallet.publicKey,
  "Token Name",
  "SYMBOL",
  "metadata-uri",
  mint
);
```

### 🪙 TokenModule Methods

#### Token Metadata Creation
```ts
const metadata = await sdk.token.createTokenMetadata({
  name: "My Token",
  symbol: "MTK",
  description: "A test token",
  file: imageBlob
});
```

#### Account Management
```ts
// Create ATA if needed
const ata = await sdk.token.createAssociatedTokenAccountIfNeeded(
  wallet.publicKey,  // payer
  wallet.publicKey,  // owner
  mintPublicKey,     // mint
  transaction,       // transaction to add instructions to
  "confirmed"        // commitment
);
```

#### Bonding Curve Information
```ts
// Get bonding curve account
const bondingCurve = await sdk.token.getBondingCurveAccount(
  mintPublicKey,
  "confirmed"
);

if (bondingCurve) {
  console.log("Virtual SOL reserves:", bondingCurve.virtualSolReserves);
  console.log("Virtual token reserves:", bondingCurve.virtualTokenReserves);
  console.log("Real SOL reserves:", bondingCurve.realSolReserves);
  console.log("Real token reserves:", bondingCurve.realTokenReserves);
  console.log("Market cap SOL:", bondingCurve.getMarketCapSOL());
  
  // Calculate prices
  const buyPrice = bondingCurve.getBuyPrice(BigInt(1000000)); // for 1M tokens
  const sellPrice = bondingCurve.getSellPrice(BigInt(1000000), 100n); // with 1% fee
}

// Get global account
const globalAccount = await sdk.token.getGlobalAccount();
console.log("Global account:", globalAccount);
```

### 📡 EventModule - Real-time Events

```ts
import { PumpFunEventType } from "@solsdk/relay_sdk";

// Listen to create events
const createListener = sdk.events.addEventListener(
  "createEvent",
  (event, slot, signature) => {
    console.log("New token created:", {
      mint: event.mint,
      name: event.name,
      symbol: event.symbol,
      uri: event.uri,
      slot,
      signature
    });
  }
);

// Listen to trade events
const tradeListener = sdk.events.addEventListener(
  "tradeEvent",
  (event, slot, signature) => {
    console.log("Trade executed:", {
      mint: event.mint,
      user: event.user,
      isBuy: event.isBuy,
      tokenAmount: event.tokenAmount,
      solAmount: event.solAmount,
      slot,
      signature
    });
  }
);

// Remove listeners when done
sdk.events.removeEventListener(createListener);
sdk.events.removeEventListener(tradeListener);
```

### 🧮 Slippage Helpers

```ts
import { calculateWithSlippageBuy, calculateWithSlippageSell } from "@solsdk/relay_sdk";

// Calculate max cost for buy with slippage
const maxCost = calculateWithSlippageBuy(
  BigInt(0.01 * LAMPORTS_PER_SOL), // base amount
  100n                              // 1% slippage
);

// Calculate min output for sell with slippage
const minOutput = calculateWithSlippageSell(
  BigInt(1000000), // token amount
  100n             // 1% slippage
);
```

### 🔗 Constants and Types

```ts
import {
  DEFAULT_DECIMALS,
  DEFAULT_COMMITMENT,
  DEFAULT_FINALITY,
  MPL_TOKEN_METADATA_PROGRAM_ID,
  GLOBAL_ACCOUNT_SEED,
  BONDING_CURVE_SEED,
  TransactionResult,
  CreateTokenMetadata,
  PriorityFee,
  JitoResult
} from "@solsdk/relay_sdk";

console.log("Default decimals:", DEFAULT_DECIMALS); // 6
console.log("Default commitment:", DEFAULT_COMMITMENT); // "confirmed"
```

---

## 🎯 Common Use Cases

### 🚀 Launch and Buy a New Token

```ts
import { Connection, Keypair, LAMPORTS_PER_SOL } from "@solana/web3.js";
import { AnchorProvider, Wallet } from "@coral-xyz/anchor";
import { PumpFunSDK } from "@solsdk/relay_sdk";

async function launchToken() {
  const connection = new Connection("https://api.mainnet-beta.solana.com");
  const wallet = Keypair.fromSecretKey(/* your secret key */);
  const provider = new AnchorProvider(connection, new Wallet(wallet));
  const sdk = new PumpFunSDK(provider);
  
  const mint = Keypair.generate();
  
  // Read image file
  const imageBuffer = await fs.readFile("./token-image.png");
  const imageBlob = new Blob([imageBuffer], { type: "image/png" });
  
  const result = await sdk.trade.createAndBuy(
    wallet,
    mint,
    {
      name: "My Awesome Token",
      symbol: "MAT",
      description: "The next big thing in crypto!",
      file: imageBlob,
      twitter: "@myawesometoken",
      website: "https://myawesometoken.com"
    },
    BigInt(0.1 * LAMPORTS_PER_SOL), // Buy 0.1 SOL worth
    500n, // 5% slippage
    { unitLimit: 300_000, unitPrice: 300_000 }
  );
  
  if (result.success) {
    console.log("🎉 Token launched successfully!");
    console.log("Mint:", mint.publicKey.toString());
    console.log("Transaction:", result.signature);
    console.log("PumpFun URL:", `https://pump.fun/${mint.publicKey}`);
  } else {
    console.error("❌ Launch failed:", result.error);
  }
}
```

### 📈 Trading Bot Example

```ts
import { PublicKey } from "@solana/web3.js";
import { PumpFunSDK, Region } from "@solsdk/relay_sdk";

class TradingBot {
  private sdk: PumpFunSDK;
  private wallet: Keypair;
  
  constructor(sdk: PumpFunSDK, wallet: Keypair) {
    this.sdk = sdk;
    this.wallet = wallet;
  }
  
  async buyToken(mint: PublicKey, solAmount: number, maxSlippage: number = 5) {
    try {
      // Use Slot relay for fast execution
      const signature = await this.sdk.slot!.buy(
        this.wallet,
        mint,
        BigInt(solAmount * LAMPORTS_PER_SOL),
        BigInt(maxSlippage * 100), // Convert to basis points
        1_000_000, // 0.001 SOL tip
        { unitLimit: 400_000, unitPrice: 400_000 }
      );
      
      console.log(`✅ Bought ${solAmount} SOL worth of ${mint}`);
      console.log(`Transaction: ${signature}`);
      return signature;
    } catch (error) {
      console.error(`❌ Buy failed:`, error);
      throw error;
    }
  }
  
  async sellAllTokens(mint: PublicKey, maxSlippage: number = 5) {
    try {
      // Get current token balance
      const balance = await getSPLBalance(
        this.sdk.connection,
        mint,
        this.wallet.publicKey
      );
      
      if (balance === 0) {
        console.log("No tokens to sell");
        return;
      }
      
      const signature = await this.sdk.slot!.sell(
        this.wallet,
        mint,
        BigInt(balance),
        BigInt(maxSlippage * 100),
        1_000_000, // 0.001 SOL tip
        { unitLimit: 400_000, unitPrice: 400_000 }
      );
      
      console.log(`✅ Sold all ${balance} tokens of ${mint}`);
      console.log(`Transaction: ${signature}`);
      return signature;
    } catch (error) {
      console.error(`❌ Sell failed:`, error);
      throw error;
    }
  }
  
  async getTokenPrice(mint: PublicKey): Promise<{ buyPrice: bigint; sellPrice: bigint } | null> {
    const bondingCurve = await this.sdk.token.getBondingCurveAccount(mint);
    if (!bondingCurve) return null;
    
    const oneToken = BigInt(10 ** 6); // 1 token with 6 decimals
    const buyPrice = bondingCurve.getBuyPrice(oneToken);
    const sellPrice = bondingCurve.getSellPrice(oneToken, 100n); // 1% fee
    
    return { buyPrice, sellPrice };
  }
}

// Usage
const bot = new TradingBot(sdk, wallet);
const mintAddress = new PublicKey("...");

// Buy 0.01 SOL worth with 3% slippage
await bot.buyToken(mintAddress, 0.01, 3);

// Check price
const prices = await bot.getTokenPrice(mintAddress);
if (prices) {
  console.log(`Buy price: ${prices.buyPrice} lamports per token`);
  console.log(`Sell price: ${prices.sellPrice} lamports per token`);
}

// Sell all tokens with 5% slippage
await bot.sellAllTokens(mintAddress, 5);
```

### 🔔 Event Monitoring

```ts
class TokenMonitor {
  private sdk: PumpFunSDK;
  
  constructor(sdk: PumpFunSDK) {
    this.sdk = sdk;
  }
  
  startMonitoring() {
    // Monitor new token launches
    this.sdk.events.addEventListener("createEvent", (event, slot, signature) => {
      console.log(`🆕 New token created:`);
      console.log(`  Name: ${event.name}`);
      console.log(`  Symbol: ${event.symbol}`);
      console.log(`  Mint: ${event.mint}`);
      console.log(`  Creator: ${event.user}`);
      console.log(`  Slot: ${slot}`);
      console.log(`  TX: ${signature}`);
      
      // You could implement auto-buy logic here
      this.evaluateNewToken(event);
    });
    
    // Monitor trades
    this.sdk.events.addEventListener("tradeEvent", (event, slot, signature) => {
      const action = event.isBuy ? "BUY" : "SELL";
      const solAmount = Number(event.solAmount) / LAMPORTS_PER_SOL;
      const tokenAmount = Number(event.tokenAmount) / (10 ** 6);
      
      console.log(`💰 ${action}: ${tokenAmount.toFixed(2)} tokens for ${solAmount.toFixed(4)} SOL`);
      console.log(`  Mint: ${event.mint}`);
      console.log(`  User: ${event.user}`);
      
      // Implement trading signals based on volume/activity
      this.analyzeTradeActivity(event);
    });
    
    console.log("🔍 Token monitoring started...");
  }
  
  private async evaluateNewToken(createEvent: any) {
    // Example: Auto-buy tokens with specific criteria
    const tokenName = createEvent.name.toLowerCase();
    
    if (tokenName.includes("ai") || tokenName.includes("meme")) {
      console.log(`🎯 Interesting token detected: ${createEvent.name}`);
      // Implement your auto-buy logic here
    }
  }
  
  private analyzeTradeActivity(tradeEvent: any) {
    // Example: Track high-volume trades
    const solAmount = Number(tradeEvent.solAmount) / LAMPORTS_PER_SOL;
    
    if (solAmount > 1.0) { // Trades over 1 SOL
      console.log(`🐋 Large trade detected: ${solAmount.toFixed(4)} SOL`);
      // Implement whale tracking logic
    }
  }
}

// Usage
const monitor = new TokenMonitor(sdk);
monitor.startMonitoring();
```

### ⚡ High-Performance Trading with Multiple Relays

```ts
class MultiRelayTrader {
  private sdk: PumpFunSDK;
  
  constructor() {
    // Initialize SDK with multiple relay options
    this.sdk = new PumpFunSDK(provider, {
      providerRegion: Region.NY,
      slotKey: "your-slot-key",
      astraKey: "your-astra-key",
      nodeOneKey: "your-nodeone-key",
      jitoUrl: "ny.mainnet.block-engine.jito.wtf",
      authKeypair: wallet
    });
  }
  
  async fastBuy(mint: PublicKey, solAmount: bigint, strategy: 'slot' | 'astra' | 'jito' = 'slot') {
    const slippage = 300n; // 3%
    const tip = 2_000_000; // 0.002 SOL tip
    const priorityFee = { unitLimit: 500_000, unitPrice: 500_000 };
    
    try {
      switch (strategy) {
        case 'slot':
          return await this.sdk.slot!.buy(
            wallet, mint, solAmount, slippage, tip, priorityFee
          );
          
        case 'astra':
          return await this.sdk.astra!.buy(
            wallet, mint, solAmount, slippage, tip, priorityFee
          );
          
        case 'jito':
          const result = await this.sdk.jito!.buyJito(
            wallet, mint, solAmount, slippage, tip, priorityFee
          );
          return result.success ? 'jito-bundle-submitted' : null;
          
        default:
          throw new Error(`Unknown strategy: ${strategy}`);
      }
    } catch (error) {
      console.error(`${strategy} buy failed:`, error);
      throw error;
    }
  }
  
  async raceToMarket(mint: PublicKey, solAmount: bigint) {
    // Try multiple relays simultaneously and use the fastest
    const promises = [
      this.fastBuy(mint, solAmount, 'slot').catch(e => ({ error: e, relay: 'slot' })),
      this.fastBuy(mint, solAmount, 'astra').catch(e => ({ error: e, relay: 'astra' })),
    ];
    
    const result = await Promise.race(promises);
    
    if (typeof result === 'string') {
      console.log(`✅ Trade executed via fastest relay: ${result}`);
      return result;
    } else {
      console.error(`❌ All relays failed`);
      throw new Error('All relay attempts failed');
    }
  }
}
```

---

## 🛡️ Why Choose @solsdk/relay_sdk?

- **Actively maintained**: Regular updates and fast issue resolution
- **Strict TypeScript types**: No `any`, no type assertions, maximum safety
- **Best practices**: KISS, DRY, SOLID, and more
- **Production ready**: Used in real-world trading bots and dApps
- **Comprehensive tests**: Ensuring reliability and stability
- **Open source**: MIT license, transparent development

---

## ⚠️ Disclaimer

This software is provided **“as is,”** without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and non-infringement.  
In no event shall the authors or copyright holders be liable for any claim, damages, or other liability—whether in an action of contract, tort, or otherwise—arising from, out of, or in connection with the software or the use or other dealings in the software.

> Use at your own risk.  
> The authors take no responsibility for any harm or damage caused by the use of this software.  
> Users are responsible for ensuring the suitability and safety of this software for their specific use cases.

By using this software, **you acknowledge that you have read, understood, and agree to this disclaimer.**