Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ bun run ci

## Architecture

**Entry point:** `src/index.ts` — initializes config, registers 5 command groups with Commander.
**Entry point:** `src/index.ts` — initializes config, registers 6 command groups with Commander.

**Commands** (`src/commands/`): Static classes that register subcommands. Each delegates to library modules.

- `ConfigCommand` — `config list`, `config set`
- `KeysCommand` — `keys list/add/delete/edit/use/solana-import`
- `LendCommand` — `lend earn tokens/positions/deposit/withdraw`
- `PerpsCommand` — `perps positions/markets/open/set/close`
- `PredictionsCommand` — `predictions events/positions/open/close/history`
- `SpotCommand` — `spot tokens/quote/swap/portfolio/transfer/reclaim`
- `UpdateCommand` — `update` (self-update CLI to latest version)

Expand All @@ -51,13 +52,16 @@ bun run ci
- `UltraClient` — Jupiter Ultra swap API (quote + execute)
- `PerpsClient` — Jupiter Perps API v2 (positions, orders, TP/SL)
- `LendClient` — Jupiter Lend API (earn tokens, positions, earnings)
- `PredictionsClient` — Jupiter Predictions API v1 (events, positions, orders, history)

**Spot swap flow:** token search → Swap.execute → UltraClient.getOrder → Signer.signTransaction → UltraClient.postExecute

**Perps flow:** PerpsClient.post* → Signer.signTransaction → PerpsClient.postExecute

**Lend deposit/withdraw flow:** LendClient.getTokens → resolve jlToken → Swap.execute → LendClient.getPositions (updated state)

**Predictions flow:** PredictionsClient.postOrder → Signer.signTransaction → PredictionsClient.postExecute

## CLI Conventions

When adding new commands, both input (options/arguments) and output (JSON/table) must be consistent with existing commands so that both humans and AI agents can reliably use and parse them. Check `docs/` for the canonical command shapes.
Expand All @@ -71,7 +75,7 @@ When adding new commands, both input (options/arguments) and output (JSON/table)

### Output

- **Field naming:** Reuse established key names — e.g. `sizeUsd`, `priceUsd`, `pnlUsd`, `pnlPct`, `feeUsd`, `signature`, `positionPubkey`, `side`, `asset`, `leverage`. Check `docs/perps.md` and `docs/spot.md` for the canonical JSON shapes.
- **Field naming:** Reuse established key names — e.g. `sizeUsd`, `priceUsd`, `pnlUsd`, `pnlPct`, `feeUsd`, `signature`, `positionPubkey`, `side`, `asset`, `leverage`. Check `docs/perps.md`, `docs/spot.md`, and `docs/predictions.md` for the canonical JSON shapes.
- **Value types:** Dollar amounts are `number`, percentages are `number` (e.g. `5.97` means +5.97%), nullable fields use `null` (not `0` or `""`), transaction hashes use `signature`.
- **Table headers:** Match the JSON key semantics — e.g. a JSON field `signature` maps to table header "Tx Signature", `pnlUsd` maps to "PnL".
- **Formatters:** Use `Output.formatDollar()`, `Output.formatDollarChange()`, `Output.formatPercentageChange()` for consistent styling. Pass `{ decimals: N }` to `formatDollar` when explicit precision is needed.
Expand Down
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jup spot swap --from SOL --to USDC --amount 1
# Reclaim rent from empty token accounts
jup spot reclaim

# Open a 3x long SOL position with $10 USDC
# Open a 3x long SOL position with 10 USDC
jup perps open --asset SOL --side long --amount 10 --input USDC --leverage 3
# View your perps positions
jup perps positions
Expand All @@ -49,6 +49,13 @@ jup lend earn tokens
jup lend earn deposit --token USDC --amount 100
# View your lending positions
jup lend earn positions

# Browse prediction markets
jup predictions events --category crypto
# Open a prediction position with 10 USDC
jup predictions open --market <marketId> --side yes --amount 10
# View your prediction positions
jup predictions positions
```

## Docs
Expand All @@ -65,6 +72,7 @@ jup lend earn positions
- [Spot](docs/spot.md): Spot trading, transfers, token search and portfolio data
- [Perps](docs/perps.md): Perps trading (leveraged longs/shorts)
- [Lend](docs/lend.md): Lending and yield farming
- [Predictions](docs/predictions.md): Prediction markets

## Changelog

Expand Down
234 changes: 234 additions & 0 deletions docs/predictions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
# Prediction Markets

Requires: an active key for `open` and `close` commands. See [setup](setup.md).

## Commands

### Browse events

```bash
jup predictions events
jup predictions events --filter trending
jup predictions events --category crypto --sort volume
jup predictions events --category sports --sort recent
jup predictions events --search "bitcoin"
jup predictions events --id <eventId>
jup predictions events --limit 5 --offset 10
```

- `--filter`: `new`, `live`, `trending`
- `--sort`: `volume` (default), `recent`
- `--category`: `all` (default), `crypto`, `sports`, `politics`, `esports`, `culture`, `economics`, `tech`
- `--id` cannot be combined with `--search`, `--filter`, `--sort`, `--category`, or `--offset`
- `--search` cannot be combined with `--filter`, `--sort`, `--category`, or `--offset`

```js
// Example JSON response:
{
"events": [
{
"eventId": "abc123",
"title": "Will BTC hit $200k by end of 2026?",
"category": "crypto",
"isLive": true,
"volumeUsd": 125000.50,
"startsAt": "2026-01-01T00:00:00.000Z",
"endsAt": "2026-12-31T23:59:59.000Z",
"markets": [
{
"marketId": "mkt456",
"title": "Yes / No",
"status": "open",
"yesPriceUsd": 0.65, // 65% implied probability
"noPriceUsd": 0.35,
"result": null // "yes" or "no" when resolved
}
]
}
],
"next": 10 // pagination offset for next page; omitted when no more results
}
```

### View positions

```bash
jup predictions positions
jup predictions positions --key mykey
jup predictions positions --address <wallet-address>
jup predictions positions --position <pubkey>
```

- With no options, uses the active key's wallet
- `--position` looks up a single position by pubkey; cannot be combined with `--key` or `--address`

```js
// Example JSON response:
{
"count": 2,
"positions": [
{
"positionPubkey": "3qMZ...83tz",
"event": "Will BTC hit $200k by end of 2026?",
"market": "Yes / No",
"side": "yes",
"contracts": 10,
"costUsd": 6.50,
"valueUsd": 7.20,
"pnlUsd": 0.70,
"pnlPct": 10.77, // percentage; 10.77 means +10.77%
"claimable": false // true when market resolved in your favor
}
]
}
```

### Open a position

```bash
jup predictions open --market <marketId> --side yes --amount 10
jup predictions open --market <marketId> --side no --amount 5 --input USDC
jup predictions open --market <marketId> --side y --amount 10 --key mykey
```

- `--market`: market ID from `jup predictions events`
- `--side`: `yes`, `no`, `y`, `n`
- `--amount`: input token amount (human-readable)
- `--input`: input token symbol or mint (default: `USDC`)

```js
// Example JSON response:
{
"action": "open",
"marketId": "mkt456",
"side": "yes",
"contracts": 10,
"costUsd": 6.50,
"feeUsd": 0.07,
"positionAvgPriceUsd": 0.65,
"positionPayoutUsd": 10.00,
"positionPubkey": "3qMZ...83tz",
"signature": "2Goj...diEc"
}
```

### Close or claim a position

```bash
# Close a single position (sell back)
jup predictions close --position <pubkey>

# Claim a resolved position (market settled in your favor)
jup predictions close --position <pubkey>

# Close all positions
jup predictions close --position all
```

- The CLI auto-detects whether to sell or claim based on the market result
- Claimable positions (market resolved in your favor) are claimed for the full payout
- Open positions on live markets are sold at the current market price

```js
// Example JSON response (close):
{
"action": "close",
"event": "Will BTC hit $200k by end of 2026?",
"market": "Yes / No",
"side": "yes",
"positionPubkey": "3qMZ...83tz",
"contracts": 10,
"costUsd": 6.50,
"feeUsd": 0.07,
"signature": "5YhT...9AKU"
}

// Example JSON response (claim):
{
"action": "claim",
"event": "Will BTC hit $200k by end of 2026?",
"market": "Yes / No",
"side": "yes",
"positionPubkey": "3qMZ...83tz",
"contracts": 10,
"payoutUsd": 10.00,
"signature": "4xK2...9zH1"
}

// Example JSON response (close all):
{
"action": "close-all",
"results": [
{
"action": "close", // or "claim"
"positionPubkey": "3qMZ...83tz",
"signature": "5YhT...9AKU"
}
]
}
```

### View trade history

```bash
jup predictions history
jup predictions history --key mykey
jup predictions history --address <wallet-address>
jup predictions history --limit 5 --offset 10
```

- With no `--address` or `--key`, uses the active key's wallet
- `--limit` defaults to 10
- `--offset` is used for pagination; use the `next` value from the previous response to fetch the next page

```js
// Example JSON response:
{
"count": 15,
"history": [
{
"time": "2026-03-15T10:30:00.000Z",
"event": "Will BTC hit $200k by end of 2026?",
"market": "Yes / No",
"type": "OrderFilled", // event type
"side": "yes",
"action": "buy", // or "sell"
"contracts": 10,
"avgPriceUsd": 0.65,
"pnlUsd": 0.70, // null for buys
"payoutUsd": 0,
"positionPubkey": "3qMZ...83tz",
"signature": "2Goj...diEc"
}
],
"next": 10 // pagination offset for next page; omitted when no more results
}
```

## Workflows

### Browse events then open a position

```bash
jup predictions events --category crypto
# Find the market ID from the output
jup predictions open --market <marketId> --side yes --amount 10
```

### Check positions then close

```bash
jup predictions positions
# Copy the positionPubkey
jup predictions close --position <pubkey>
```

### Claim resolved positions

```bash
jup predictions positions
# Positions with "claimable: true" can be claimed
jup predictions close --position <pubkey>
# Or claim all at once
jup predictions close --position all
```
2 changes: 1 addition & 1 deletion llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ On failure, commands exit with non-zero code with an error message. In JSON mode
- [Spot](docs/spot.md): Spot trading, transfers, reclaim rent, token and portfolio data
- [Perps](docs/perps.md): Perps trading (leveraged longs/shorts)
- [Lend](docs/lend.md): Lending and yield farming
- Predictions: Create and trade prediction markets (coming soon)
- [Predictions](docs/predictions.md): Prediction markets
11 changes: 1 addition & 10 deletions src/clients/PerpsClient.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import ky from "ky";

import { Asset, resolveAsset } from "../lib/Asset.ts";
import { NumberConverter } from "../lib/NumberConverter.ts";
import { resolveAsset } from "../lib/Asset.ts";
import { ClientConfig } from "./ClientConfig.ts";

export type MarketStatsResponse = {
Expand Down Expand Up @@ -238,14 +237,6 @@ export class PerpsClient {
headers: ClientConfig.headers,
});

public static toUsdRaw(amount: string): string {
return NumberConverter.toChainAmount(amount, Asset.USDC.decimals);
}

public static fromUsdRaw(amount: string): string {
return NumberConverter.fromChainAmount(amount, Asset.USDC.decimals);
}

public static async getMarkets(): Promise<
({ asset: string } & MarketStatsResponse)[]
> {
Expand Down
Loading
Loading