Metadata-Version: 2.4
Name: lasersell-sdk
Version: 1.1.0
Summary: Python SDK for the LaserSell API
Author: LaserSell
License: MIT
Project-URL: Homepage, https://lasersell.io
Project-URL: Documentation, https://github.com/lasersell/lasersell-sdk/tree/main/python
Project-URL: Repository, https://github.com/lasersell/lasersell-sdk
Project-URL: Bug Tracker, https://github.com/lasersell/lasersell-sdk/issues
Keywords: solana,trading,defi,sdk,lasersell,cryptocurrency
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: websockets<16,>=12
Requires-Dist: solders>=0.21

# lasersell-sdk (Python)

Python SDK for the LaserSell API.

> **Full documentation:** [docs.lasersell.io/api/sdk/python](https://docs.lasersell.io/api/sdk/python)

Modules:

- `exit_api`: build unsigned [buy](https://docs.lasersell.io/api/exit-api/buy)/[sell](https://docs.lasersell.io/api/exit-api/sell) transactions.
- `stream`: [Exit Intelligence Stream](https://docs.lasersell.io/api/stream/overview) client, protocol types, and session helpers.
- `tx`: [sign/encode/send](https://docs.lasersell.io/api/transactions/signing) Solana transactions.
- `retry`: shared retry helpers.

> **Using AI to code?** Add the [LaserSell MCP server](https://docs.lasersell.io/ai-agents/mcp-server) to your editor so your AI assistant can search LaserSell documentation in real time.

## Install

```bash
pip install lasersell-sdk
```

From this repository:

```bash
cd lasersell-sdk/python
python -m pip install -e .
```

## Package layout

- `lasersell_sdk.exit_api`: build unsigned buy/sell transactions.
- `lasersell_sdk.stream.client`: websocket transport and command sender.
- `lasersell_sdk.stream.session`: higher-level stream session with position tracking.
- `lasersell_sdk.stream.proto`: protocol types and JSON encode/decode helpers.
- `lasersell_sdk.tx`: sign/encode/send Solana transactions.
- `lasersell_sdk.retry`: retry/backoff and timeout helpers.

## Build a sell transaction

```python
import asyncio

from lasersell_sdk.exit_api import BuildSellTxRequest, ExitApiClient, SellOutput


async def main() -> None:
    client = ExitApiClient.with_api_key("REPLACE_WITH_API_KEY")

    request = BuildSellTxRequest(
        mint="REPLACE_WITH_MINT",
        user_pubkey="REPLACE_WITH_WALLET_PUBKEY",
        amount_tokens=1_000_000,
        slippage_bps=2_000,
        output=SellOutput.SOL,
    )

    response = await client.build_sell_tx(request)
    print(response.tx)


asyncio.run(main())
```

Notes:

- `amount_tokens` is in token atomic units (smallest unit for the mint).
- `slippage_bps` is basis points (`100` = `1%`, `2000` = `20%`).
- Use `client.with_base_url("https://api-dev.example")` to target a custom base URL.

## Stream + auto-sell flow

> **Important:** Connect the stream **before** submitting a buy transaction. See [docs.lasersell.io/api/exit-api/buy](https://docs.lasersell.io/api/exit-api/buy) for details.

```python
import asyncio

from solders.keypair import Keypair

from lasersell_sdk.stream.client import (
    StreamClient,
    StreamConfigure,
    strategy_config_from_optional,
)
from lasersell_sdk.stream.session import StreamSession
from lasersell_sdk.tx import SendTargetHeliusSender, send_transaction, sign_unsigned_tx


async def main() -> None:
    signer = Keypair()
    client = StreamClient("REPLACE_WITH_API_KEY")
    session = await StreamSession.connect(
        client,
        StreamConfigure(
            wallet_pubkeys=["REPLACE_WITH_WALLET_PUBKEY"],
            strategy=strategy_config_from_optional(
                target_profit_pct=50.0,
                stop_loss_pct=10.0,
            ),
            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" and event.message.get("type") == "exit_signal_with_tx":
            signed_tx = sign_unsigned_tx(event.message["unsigned_tx_b64"], signer)
            signature = await send_transaction(SendTargetHeliusSender(), signed_tx)
            print(signature)


asyncio.run(main())
```

`deadline_timeout_sec` is enforced client-side by `StreamSession` timers and is not sent as part of wire strategy.
Use `session.update_strategy(...)` when changing strategy so local deadline timers stay in sync (pass `deadline_timeout_sec=` to change local deadline timing).
Use `single_wallet_stream_configure_optional(...)` / `strategy_config_from_optional(...)` to omit TP/SL fields; at least one of take profit, stop loss, trailing stop, or timeout must be enabled.

### Trailing stop

Lock in profits by tracking a high-water mark. When the position's profit drops by the configured percentage of entry cost from its peak, an exit is triggered.

```python
from lasersell_sdk.stream.client import strategy_config_from_optional

# 20% take profit, 10% stop loss, 5% trailing stop
strategy = strategy_config_from_optional(
    take_profit_pct=20.0,
    stop_loss_pct=10.0,
    trailing_stop_pct=5.0,
)
```

Example: with `trailing_stop_pct=5.0` and an entry of 100 SOL, if profit peaks at 30 SOL, an exit triggers when profit falls below 25 SOL.

### Sell on graduation

Automatically exit a position when its token graduates from a bonding curve to a full DEX (e.g. Pump.fun to PumpSwap). Enable by setting `sell_on_graduation` in the optional strategy config:

```python
from lasersell_sdk.stream.client import strategy_config_from_optional

strategy = strategy_config_from_optional(
    take_profit_pct=20.0,
    stop_loss_pct=10.0,
    sell_on_graduation=True,
)
```

When a graduation event is detected the server sells the position on the new market and reports `"graduation"` as the exit reason.

### Update wallets mid-session

Add or remove wallets without reconnecting:

```python
await session.sender().update_wallets(["WALLET_1_PUBKEY", "WALLET_2_PUBKEY"])
```

The server diffs the new list against the current set and registers/unregisters accordingly.

### Liquidity snapshots (Tier 1+)

Professional and Advanced tier subscribers receive real time [liquidity snapshots](https://docs.lasersell.io/api/stream/server-events#liquidity_snapshot) alongside PnL updates. Each snapshot contains slippage bands and a liquidity trend indicator. See the [full announcement](https://www.lasersell.io/blog/liquidity-snapshots-and-sdk-0-3). `StreamSession` caches the latest snapshot per position:

```python
bands = session.get_slippage_bands(position_id)
max_tokens = session.get_max_sell_at_slippage(position_id, 500)  # 5% slippage
trend = session.get_liquidity_trend(position_id)  # "growing" | "stable" | "draining"
```

### Partial sell

Build a sell transaction for a subset of a position's tokens using the `PositionHandle` from any `StreamEvent`:

```python
response = await client.build_partial_sell_tx(handle, amount_tokens, 500, SellOutput.SOL)
```

Combine with slippage bands to sell the maximum amount within your desired price impact.

### Exit ladder

Sell partial amounts at multiple profit thresholds:

```python
from lasersell_sdk.stream.client import StrategyConfigBuilder

strategy = (
    StrategyConfigBuilder()
    .stop_loss_pct(10.0)
    .take_profit_levels([
        {"profit_pct": 25, "sell_pct": 30, "trailing_stop_pct": 0},
        {"profit_pct": 50, "sell_pct": 50, "trailing_stop_pct": 3},
        {"profit_pct": 100, "sell_pct": 100, "trailing_stop_pct": 5},
    ])
    .build()
)
```

### Liquidity guard

Prevent exits into thin liquidity:

```python
strategy = (
    StrategyConfigBuilder()
    .target_profit_pct(50.0)
    .stop_loss_pct(10.0)
    .liquidity_guard(True)
    .build()
)
```

### Breakeven trail

A trailing stop that activates at breakeven:

```python
strategy = (
    StrategyConfigBuilder()
    .target_profit_pct(50.0)
    .stop_loss_pct(10.0)
    .breakeven_trail_pct(2.0)
    .build()
)
```

### Per-position strategy override

Override the global strategy for a single position:

```python
session.sender().update_position_strategy(position_id, {
    "target_profit_pct": 200.0,
    "stop_loss_pct": 5.0,
    "trailing_stop_pct": 10.0,
})
```

### Wallet registration

All wallets must be registered before connecting to the Exit Intelligence Stream:

```python
from lasersell_sdk.exit_api import prove_ownership

proof = prove_ownership(keypair)
await client.register_wallet(proof, label="My Wallet")

# Or use connect_with_wallets (registers + connects in one step)
session = await stream_client.connect_with_wallets([proof], strategy, deadline_timeout_sec=120)
```

### Watch wallets (copy trading)

Mirror trades from external wallets:

```python
session.sender().update_watch_wallets([
    {"pubkey": "WalletToWatch..."},
])
```

Notes:

- Use `client.with_endpoint("wss://stream-dev.example/v1/ws")` to target a custom stream endpoint.
- `unsigned_tx_b64` from stream events can be signed with `lasersell_sdk.tx.sign_unsigned_tx`.

## RPC endpoint

The SDK ships with the Solana public RPC as a default so you can get started immediately:

```python
from lasersell_sdk.tx import SendTargetRpc

target = SendTargetRpc()  # uses Solana public RPC
```

**A private RPC is highly recommended for production** — the public endpoint is rate-limited and unreliable under load. Free private RPC tiers are available from [Helius](https://www.helius.dev/) and [Chainstack](https://chainstack.com/), among others:

```python
target = SendTargetRpc(url="https://your-private-rpc.example.com")
```

## Examples

See `examples/README.md` for setup and script-by-script instructions.

Quick run commands (from `lasersell-sdk/python`):

```bash
python examples/build_buy.py
python examples/build_sell.py
python examples/build_and_send_sell.py
python examples/auto_sell.py
```

Scripts:

- `build_buy.py`
- `build_sell.py`
- `build_and_send_sell.py`
- `auto_sell.py`
