Prerequisites
- A LaserSell API key (get one here).
- A Solana keypair file (JSON array of bytes).
- Node.js 18+ (for the TypeScript example) or the runtime for your preferred language.
Using AI to code? Add the LaserSell MCP server to your editor so your AI assistant can search LaserSell documentation in real time. Works with Claude Code, Claude Desktop, Cursor, and Windsurf.
Example 1: Build, Sign, and Send a Sell Transaction
This example calls the LaserSell API to build an unsigned sell transaction, signs it locally, and submits through Helius Sender.import { readFile } from "node:fs/promises";
import { Keypair } from "@solana/web3.js";
import {
ExitApiClient,
sendTransaction,
sendTargetHeliusSender,
signUnsignedTx,
type BuildSellTxRequest,
} from "@lasersell/lasersell-sdk";
const apiKey = process.env.LASERSELL_API_KEY!;
const keypairPath = "./keypair.json";
// Load keypair
const raw = await readFile(keypairPath, "utf8");
const keypair = Keypair.fromSecretKey(
Uint8Array.from(JSON.parse(raw))
);
// Build unsigned tx
const client = ExitApiClient.withApiKey(apiKey);
const request: BuildSellTxRequest = {
mint: "So11111111111111111111111111111111111111112",
user_pubkey: keypair.publicKey.toBase58(),
amount_tokens: 1_000_000,
slippage_bps: 2_000,
output: "SOL",
};
const unsignedTxB64 = await client.buildSellTxB64(request);
// Sign locally
const signedTx = signUnsignedTx(unsignedTxB64, keypair);
// Submit
const signature = await sendTransaction(
sendTargetHeliusSender(),
signedTx
);
console.log("Signature:", signature);
import asyncio, json
from pathlib import Path
from solders.keypair import Keypair
from lasersell_sdk.exit_api import ExitApiClient, BuildSellTxRequest, SellOutput
from lasersell_sdk.tx import SendTargetHeliusSender, send_transaction, sign_unsigned_tx
async def main():
api_key = "YOUR_API_KEY"
keypair_bytes = json.loads(Path("./keypair.json").read_text())
signer = Keypair.from_bytes(bytes(keypair_bytes))
client = ExitApiClient.with_api_key(api_key)
request = BuildSellTxRequest(
mint="So11111111111111111111111111111111111111112",
user_pubkey=str(signer.pubkey()),
amount_tokens=1_000_000,
slippage_bps=2_000,
output=SellOutput.SOL,
)
unsigned_tx_b64 = await client.build_sell_tx_b64(request)
signed_tx = sign_unsigned_tx(unsigned_tx_b64, signer)
signature = await send_transaction(SendTargetHeliusSender(), signed_tx)
print("Signature:", signature)
asyncio.run(main())
use lasersell_sdk::exit_api::{ExitApiClient, BuildSellTxRequest};
use lasersell_sdk::tx::{SendTarget, sign_unsigned_tx, send_transaction};
use solana_sdk::signature::read_keypair_file;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let api_key = std::env::var("LASERSELL_API_KEY")?;
let keypair = read_keypair_file("./keypair.json")?;
let http = reqwest::Client::new();
let client = ExitApiClient::with_api_key(&api_key);
let request = BuildSellTxRequest {
mint: "So11111111111111111111111111111111111111112".into(),
user_pubkey: keypair.pubkey().to_string(),
amount_tokens: 1_000_000,
output: SellOutput::Sol,
slippage_bps: 2_000,
..Default::default()
};
let unsigned_tx_b64 = client.build_sell_tx_b64(&request).await?;
let signed_tx = sign_unsigned_tx(&unsigned_tx_b64, &keypair)?;
let signature = send_transaction(&http, &SendTarget::HeliusSender, &signed_tx).await?;
println!("Signature: {signature}");
Ok(())
}
package main
import (
"context"
"fmt"
"log"
"github.com/gagliardetto/solana-go"
lasersell "github.com/lasersell/lasersell-sdk/go"
)
func main() {
ctx := context.Background()
apiKey := "YOUR_API_KEY"
privateKey, err := solana.PrivateKeyFromSolanaKeygenFile("./keypair.json")
if err != nil {
log.Fatal(err)
}
client := lasersell.NewExitAPIClientWithAPIKey(apiKey)
resp, err := client.BuildSellTx(ctx, lasersell.BuildSellTxRequest{
Mint: "So11111111111111111111111111111111111111112",
UserPubkey: privateKey.PublicKey().String(),
AmountTokens: 1_000_000,
Output: lasersell.SellOutputSOL,
SlippageBps: 2_000,
})
if err != nil {
log.Fatal(err)
}
signedTx, err := lasersell.SignUnsignedTx(resp.Tx, privateKey)
if err != nil {
log.Fatal(err)
}
sig, err := lasersell.SendTransaction(ctx, nil, lasersell.SendTargetHeliusSender(), signedTx)
if err != nil {
log.Fatal(err)
}
fmt.Println("Signature:", sig)
}
func intPtr(v int) *int { return &v }
func strPtr(v string) *string { return &v }
Example 2: Auto Sell with the Exit Intelligence Stream
Connect the Exit Intelligence Stream to monitor wallets and automatically execute exits when your strategy thresholds are reached.Connect the stream before you buy. The stream detects positions by watching for on chain token arrivals. If you call
/v1/buy before the stream is connected and configured, the position will not be tracked. Always start the stream first, then submit your buy transaction.import { readFile } from "node:fs/promises";
import { Keypair } from "@solana/web3.js";
import {
StreamClient,
StreamSession,
sendTransaction,
sendTargetHeliusSender,
signUnsignedTx,
} from "@lasersell/lasersell-sdk";
const apiKey = process.env.LASERSELL_API_KEY!;
const raw = await readFile("./keypair.json", "utf8");
const signer = Keypair.fromSecretKey(Uint8Array.from(JSON.parse(raw)));
const client = new StreamClient(apiKey);
const session = await StreamSession.connect(client, {
wallet_pubkeys: [signer.publicKey.toBase58()],
strategy: {
target_profit_pct: 5,
stop_loss_pct: 1.5,
},
deadline_timeout_sec: 45,
send_mode: "helius_sender",
tip_lamports: 1000,
});
while (true) {
const event = await session.recv();
if (event === null) break;
if (event.type === "exit_signal_with_tx") {
const signed = signUnsignedTx(event.message.unsigned_tx_b64, signer);
const sig = await sendTransaction(sendTargetHeliusSender(), signed);
console.log("Exit submitted:", sig);
}
}
import asyncio, json
from pathlib import Path
from solders.keypair import Keypair
from lasersell_sdk.stream.client import StreamClient, StreamConfigure
from lasersell_sdk.stream.session import StreamSession
from lasersell_sdk.tx import SendTargetHeliusSender, send_transaction, sign_unsigned_tx
async def main():
signer = Keypair.from_bytes(bytes(json.loads(Path("./keypair.json").read_text())))
client = StreamClient("YOUR_API_KEY")
session = await StreamSession.connect(
client,
StreamConfigure(
wallet_pubkeys=[str(signer.pubkey())],
strategy={"target_profit_pct": 5.0, "stop_loss_pct": 1.5},
deadline_timeout_sec=45,
send_mode="helius_sender",
tip_lamports=1000,
),
)
while True:
event = await session.recv()
if event is None:
break
if event.type == "exit_signal_with_tx":
msg = event.message
signed = sign_unsigned_tx(str(msg["unsigned_tx_b64"]), signer)
sig = await send_transaction(SendTargetHeliusSender(), signed)
print("Exit submitted:", sig)
asyncio.run(main())
use lasersell_sdk::stream::client::{StreamClient, StreamConfigure, strategy_config_from_optional};
use lasersell_sdk::stream::session::{StreamSession, StreamEvent};
use lasersell_sdk::stream::proto::ServerMessage;
use lasersell_sdk::tx::{SendTarget, sign_unsigned_tx, send_transaction};
use secrecy::SecretString;
use solana_sdk::signature::read_keypair_file;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let api_key = std::env::var("LASERSELL_API_KEY")?;
let keypair = read_keypair_file("./keypair.json")?;
let http = reqwest::Client::new();
let client = StreamClient::new(SecretString::new(api_key));
let configure = StreamConfigure {
wallet_pubkeys: vec![keypair.pubkey().to_string()],
strategy: strategy_config_from_optional(
Some(5.0), Some(1.5), None, None,
),
deadline_timeout_sec: 45,
send_mode: Some("helius_sender".to_string()),
tip_lamports: Some(1000),
};
let mut session = StreamSession::connect(&client, configure).await?;
while let Some(event) = session.recv().await {
if let StreamEvent::ExitSignalWithTx {
message: ServerMessage::ExitSignalWithTx {
unsigned_tx_b64, ..
},
..
} = event
{
let signed = sign_unsigned_tx(&unsigned_tx_b64, &keypair)?;
let sig = send_transaction(&http, &SendTarget::HeliusSender, &signed).await?;
println!("Exit submitted: {sig}");
}
}
Ok(())
}
package main
import (
"context"
"errors"
"fmt"
"io"
"log"
"github.com/gagliardetto/solana-go"
lasersell "github.com/lasersell/lasersell-sdk/go"
"github.com/lasersell/lasersell-sdk/go/stream"
)
func main() {
ctx := context.Background()
apiKey := "YOUR_API_KEY"
privateKey, err := solana.PrivateKeyFromSolanaKeygenFile("./keypair.json")
if err != nil {
log.Fatal(err)
}
client := stream.NewStreamClient(apiKey)
sendMode := "helius_sender"
tipLamports := uint64(1000)
session, err := stream.ConnectSession(ctx, client, stream.StreamConfigure{
WalletPubkeys: []string{privateKey.PublicKey().String()},
Strategy: stream.StrategyConfigMsg{
TargetProfitPct: 5.0,
StopLossPct: 1.5,
},
DeadlineTimeoutSec: 45,
SendMode: &sendMode,
TipLamports: &tipLamports,
})
if err != nil {
log.Fatal(err)
}
for {
event, err := session.Recv(ctx)
if errors.Is(err, io.EOF) {
break
}
if err != nil {
log.Fatal(err)
}
if msg, ok := event.Message.(stream.ExitSignalWithTxServerMessage); ok {
signedTx, err := lasersell.SignUnsignedTx(msg.UnsignedTxB64, privateKey)
if err != nil {
log.Printf("sign failed: %v", err)
continue
}
sig, err := lasersell.SendTransaction(ctx, nil, lasersell.SendTargetHeliusSender(), signedTx)
if err != nil {
log.Printf("send failed: %v", err)
continue
}
fmt.Println("Exit submitted:", sig)
}
}
}
Next Steps
- POST /v1/sell: Full request and response schema for sell transactions.
- Exit Intelligence Stream: Deep dive into the WebSocket stream.
- Transaction Signing: Understand the non custodial signing flow.

