pumpfun-livestream
$
npx mdskill add elophanto/EloPhanto/pumpfun-livestreamStream local videos to Pump.fun using Solana wallet auth.
- Agents broadcast local video files to Pump.fun's livestream UI.
- Integrates Pump.fun API, LiveKit CLI, and Python orchestrator.
- Authenticates via agent's Solana wallet for secure access.
- Delivers live video playback directly to Pump.fun's player.
SKILL.md
.github/skills/pumpfun-livestreamView on GitHub ↗
---
name: pumpfun-livestream
description: Stream a local video file to Pump.fun's livestream UI for the agent's coin. Wraps Pump.fun's livestream API (create, host-token) and LiveKit's CLI publisher behind a Python orchestrator that signs auth with the agent's existing Solana wallet.
homepage: https://pump.fun
---
# Pump.fun Livestream
Stream a local video to **Pump.fun's livestream player** for an existing
Pump.fun coin. The skill is plug-and-play: you provide the coin mint
address and a local video path, the orchestrator handles auth, transcoding,
and publishing.
## Triggers
- "stream this video to pump.fun"
- "loop voice on the pump.fun livestream"
- "go live on pump", "broadcast on pump"
- "pump.fun livestream", "pumpfun stream", "live on pump.fun"
- "say X on pump.fun stream" → use ``pump_say`` (TTS audio)
- "write X / display X / show X on pump.fun stream" → use
``pump_caption`` (visible text overlay)
- "post X in pump.fun chat" → use ``pump_chat`` (chat panel)
## How it works (architecture)
```
agent's Solana wallet ─sign─► /auth/login ─JWT─► all subsequent calls
│
▼
/livestreams/create-livestream (mint) ──► stream record
│
▼
/livestreams/livekit/token/host (mint, creator) ──► LiveKit JWT
│
▼
ffmpeg(local.mp4 → raw.h264) ──► lk room join --publish ──► LiveKit room
│
▼
pump.fun live page
```
Pump.fun does not run their own video stack — they're a thin wrapper
around **LiveKit Cloud**. The skill does NOT mint a coin, trade, or
move SOL; it only operates on a coin the agent already owns.
## Prerequisites
### 1. The agent's coin mint
The agent's pump.fun coin mint address must be stored in the vault as
`pumpfun_coin_mint`. EloPhanto's existing pump.fun coin:
```bash
elophanto vault set pumpfun_coin_mint BwUgJBQffm4HM49W7nsMphStJm4DbA5stuo4w7iwpump
```
### 2. Where to drop videos
The agent's workspace has a dedicated folder for streamable videos:
```
<agent.workspace>/livestream_videos/
```
For EloPhanto: `/Users/0xroyce/agents/elophanto/livestream_videos/`
Drop any `.mp4`, `.mov`, `.webm`, etc. into that folder, then call the
tool with just the **filename** — no need to type the full path:
```json
{"action": "start", "video": "elephant-trailer.mp4"}
// → resolves to /Users/0xroyce/agents/elophanto/livestream_videos/elephant-trailer.mp4
```
Absolute paths still work and bypass the lookup:
```json
{"action": "start", "video": "/Users/0xroyce/Desktop/clip.mp4"}
```
### 3. System binaries
Two CLI binaries must be on PATH. Verify with:
```bash
which ffmpeg && ffmpeg -version | head -1
which lk && lk --version
```
Install if missing:
| OS | ffmpeg | lk (LiveKit CLI) |
|---|---|---|
| macOS | `brew install ffmpeg` | `brew install livekit-cli` |
| Linux | `apt-get install ffmpeg` | Download from https://github.com/livekit/livekit-cli/releases (pick the right `lk_linux_*` binary, `chmod +x`, move to `/usr/local/bin/lk`) |
### 4. Solana wallet (already in the vault)
The skill reads the agent's existing keypair from `solana_wallet_private_key`
(set automatically when the wallet was created). No extra setup.
### 4. Vault password
Both auth and orchestrator scripts need `VAULT_PASSWORD` in the
environment to decrypt the wallet. The agent's running session already
has it; pass it through when invoking the script via `shell_execute`.
## Workflow
### From chat (preferred — uses the `pump_livestream` native tool)
The agent calls a single tool with one of these actions:
```json
{"action": "address"}
// → {wallet: "..."} — show which wallet would sign auth
{"action": "login"}
// → forces a fresh JWT exchange (debugging only — auth happens
// automatically on every other call)
{"action": "start", "video": "/abs/path/to/video.mp4"}
// → uses pumpfun_coin_mint from vault. Returns
// {status: "started", pid, started_at, log_file, ...}
{"action": "start", "mint": "BwUg...pump", "video": "...", "fps": 24}
// → explicit mint and frame rate
{"action": "start", "video": "trailer.mp4", "loop": true}
// → resolves to <workspace>/livestream_videos/trailer.mp4 and
// restarts the publisher every time the video ends. Stop with
// {"action": "stop"}. Optional "max_iterations": N caps the loop.
{"action": "status"}
// → {status: "running" | "exited" | "not_running", ...}
{"action": "stop"}
// → SIGTERMs the publisher, removes transcoded .h264, clears state
```
The tool reads vault keys directly (no env var roundtrip) and runs in
the agent's running Python process. The actual `lk` publisher is
spawned as a detached subprocess so the chat returns immediately;
poll `status` to track the stream.
### From shell (debugging — needs VAULT_PASSWORD)
```bash
cd /path/to/EloPhanto
VAULT_PASSWORD=$VAULT_PASSWORD python skills/pumpfun-livestream/scripts/pump_livestream.py \
start \
$(elophanto vault get pumpfun_coin_mint) \
/path/to/video.mp4
```
This will:
1. Sign a login message with the agent's wallet, exchange it for a
pump.fun JWT (cached in the vault as `pumpfun_jwt`).
2. POST `/livestreams/create-livestream` with the mint (idempotent —
409 "already exists" is silently tolerated).
3. GET `/livestreams/livekit/token/host` for a LiveKit JWT.
4. ffmpeg-transcode the input to raw H.264 (`video.h264` next to it).
5. Spawn `lk room join --publish video.h264 --exit-after-publish` as a
detached subprocess.
6. Persist process state to `~/.elophanto/livestream-state/<mint>.json`
so the agent can `status`/`stop` later.
The script returns immediately with `{status: "started", pid, ...}`.
The actual stream runs in the background until the video ends.
### Status check
```bash
python skills/pumpfun-livestream/scripts/pump_livestream.py status <mint>
```
Returns one of:
- `running` — publisher subprocess alive, stream is live
- `exited` — process died (check `log_file` field for ffmpeg/lk output)
- `not_running` — no record at all
### Stop a stream
```bash
python skills/pumpfun-livestream/scripts/pump_livestream.py stop <mint>
```
SIGTERMs the publisher (with a SIGKILL fallback after 3s), removes the
transcoded `.h264` (unless `--keep-h264` was set on start), and clears
state.
### Lower-level commands
For debugging or partial flows:
```bash
# Just check or refresh the cached pump.fun JWT
python skills/pumpfun-livestream/scripts/pump_auth.py token
# Force a fresh login
python skills/pumpfun-livestream/scripts/pump_auth.py login
# Just register the stream record (no publishing)
python skills/pumpfun-livestream/scripts/pump_livestream.py create <mint>
# Just transcode (no streaming)
python skills/pumpfun-livestream/scripts/pump_livestream.py transcode \
in.mp4 out.h264
# Just fetch a fresh host LiveKit token
python skills/pumpfun-livestream/scripts/pump_livestream.py token <mint>
```
## Tuning
| Concern | Knob |
|---|---|
| Frame rate | `--fps 30` (default 30; lower = smaller files, fewer dropped frames) |
| LiveKit cluster | `--livekit-url wss://...` or `LIVEKIT_URL` env. Defaults to `wss://pump-prod-tg2x9b6r.livekit.cloud`. Override only if you've inspected pump.fun's frontend and confirmed a different cluster URL. |
| Keep transcoded file | `--keep-h264` — useful for re-publishing without re-encoding |
| Skip create | `--skip-create` — when the stream record already exists and you just want to publish again |
## What's intentionally NOT included
- **Audio.** The orchestrator strips audio (`-an` in ffmpeg). Audio
publishing requires a second LiveKit track and the codec must be
Opus (`.ogg`). Easy to add later: re-run ffmpeg to produce
`video.opus`, pass both files to `lk room join --publish` (it
accepts repeated `--publish` flags).
- **Live chat ingest.** Pump.fun's chat is a separate API surface
(likely a websocket on the same `frontend-api-v3.pump.fun` host). Not
part of v1 — see follow-up notes below.
- **Auto-restart on disconnect.** If the LiveKit publisher dies
mid-video, `status` will show `exited` and the agent must decide
whether to restart. No supervisor loop.
- **Multi-coin / multi-stream concurrency.** State is keyed by mint, so
in theory two different mints can stream concurrently. Same mint
twice = the second `start` returns `{status: "already_running"}`.
## Live captions — `pump_caption`
Set or clear an on-screen text overlay on the voice-mode stream.
ffmpeg's drawtext filter reloads the file every frame (~33 ms
latency) so the caption updates as soon as the agent writes it.
```json
{"action": "set", "text": "$ELO live · supply locked · CA: BwUg…pump"}
{"action": "set", "text": "answering: yes, the agent runs the chat itself.\nproof: tx 0xabc…"}
{"action": "clear"}
{"action": "current"} // returns whatever's on screen right now
```
Pair with the scheduler / heartbeat to rotate messages — price
tick, recent trade, FAQ answer, scrolling proof line. Pairs with
`pump_say` so viewers with sound off can still read what the agent
is "saying". Voice mode only — video-mode streams render the file
contents but it's not on the encode path.
## Live chat — `pump_chat`
The chat panel that runs alongside the video uses Pump.fun's
**livechat Socket.IO server** at `wss://livechat.pump.fun` (path
`/socket.io/`). Authentication: the same JWT cookie minted by
`/auth/login`, passed in both the Cookie header and the Socket.IO
`auth` payload.
The agent calls a single tool from chat:
```json
{"action": "say", "text": "gm — agent live, supply locked, no presale"}
// → posts to the agent's coin chat. Returns {posted: true, id: "<msg-uuid>"}
{"action": "say", "text": "yep — local agent streaming itself", "reply_to_id": "<msg-uuid>"}
// → threaded reply to a viewer's question
{"action": "history", "limit": 50}
// → returns recent messages (id, username, text, timestamp) so the
// agent can react to viewer questions
```
Same vault, same wallet, same coin mint as `pump_livestream` — no
extra setup. Use heartbeat or scheduled tasks to drip "proof"
messages periodically; don't loop in tight intervals. Marked
`DESTRUCTIVE` since posts are public under the agent's coin name.
## Common errors
| Error | Cause | Fix |
|---|---|---|
| `VAULT_PASSWORD env var required` | Script invoked without the agent's vault password in env | Pass `VAULT_PASSWORD=$VAULT_PASSWORD` when calling via `shell_execute` |
| `Pump.fun login failed (401)` | Auth message format is rejected | Inspect pump.fun's web frontend network tab during a real login; tweak `_build_message()` in `pump_auth.py` to match |
| `'ffmpeg' not found on PATH` | Missing system binary | See Prerequisites table above |
| `'lk' not found on PATH` | Missing system binary | See Prerequisites table above |
| `LiveKit token endpoint returned no token` | Wrong JWT or stream record not yet created for that mint | Run `pump_auth.py login` first; then `pump_livestream.py create <mint>` |
| `start` succeeds but pump.fun shows no stream | Default LiveKit URL doesn't match pump.fun's actual cluster | Inspect pump.fun's network tab during a manual stream; pass real URL via `--livekit-url` |
| `exited` status with empty video on pump.fun | ffmpeg ran but the codec/container wasn't accepted by LiveKit | Check `log_file` from `status` output; usually a codec issue |
## Source layout
```
skills/pumpfun-livestream/
├── SKILL.md # this file — agent-facing playbook
└── scripts/
├── pump_auth.py # wallet → JWT, cached in vault
└── pump_livestream.py # create / token / transcode / start / stop / status
```
Both scripts are pure-Python, depend only on `httpx`, `solders`,
`base58` (already pinned in EloPhanto), and the system `ffmpeg` + `lk`
binaries.
## Verify
- A real RPC/SDK call was issued (mainnet, devnet, or local validator) and the response payload is captured in the transcript, not just paraphrased
- Every transaction was simulated (`simulateTransaction` or equivalent) before any signing/sending step; simulation logs are attached
- For any signed/sent transaction, the resulting signature is recorded and confirmed on chain (status returned by `getSignatureStatuses` or an explorer URL)
- Slippage, priority-fee, and compute-unit limits were set explicitly with concrete numeric values, not left to library defaults
- Account addresses, mints, and program IDs used in the run match the documented pumpfun-livestream addresses for the targeted cluster (no mainnet/devnet mix-up)
- Failure path was exercised at least once (insufficient balance, stale oracle, expired blockhash, etc.) and the agent's error handling produced a human-readable message
More from elophanto/EloPhanto
- 12-principles-of-animationAudit animation code against Disney's 12 principles adapted for web. Use when reviewing motion, implementing animations, or checking animation quality. Outputs file:line findings.
- accessibility-auditingAudit interfaces against WCAG 2.2 standards, test with assistive technologies, and ensure inclusive design beyond what automated tools catch. Adapted from msitarzewski/agency-agents.
- agency-phase-0-discoveryIntelligence and discovery phase — validate opportunity before committing resources. Adapted from msitarzewski/agency-agents.
- agency-phase-1-strategyStrategy and architecture phase — define what to build, how to structure it, and what success looks like. Adapted from msitarzewski/agency-agents.
- agency-phase-2-foundationFoundation and scaffolding phase — build technical and operational foundation before feature development. Adapted from msitarzewski/agency-agents.
- agency-phase-3-buildBuild and iterate phase — implement all features through continuous Dev-QA loops with orchestrated multi-agent sprints. Adapted from msitarzewski/agency-agents.
- agency-phase-4-hardeningQuality and hardening phase — the final quality gauntlet proving production readiness with evidence. Adapted from msitarzewski/agency-agents.
- agency-phase-5-launchLaunch and growth phase — coordinate go-to-market execution across all channels for maximum impact. Adapted from msitarzewski/agency-agents.
- agency-phase-6-operateOperate and evolve phase — sustained operations with continuous improvement for live products. Adapted from msitarzewski/agency-agents.
- agency-strategyNEXUS multi-agent orchestration strategy — the complete operational playbook for coordinating specialized AI agents across project phases. Adapted from msitarzewski/agency-agents.