Pump.fun Livestream
Diffusez une vidéo locale sur le lecteur livestream de Pump.fun pour une pièce Pump.fun existante. La skill est prête à l'emploi : vous fournissez l'adresse de mint de la pièce et un chemin vidéo local, l'orchestrateur gère l'authentification, le transcodage et la publication.
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" → utiliser
pump_say(audio TTS) - "write X / display X / show X on pump.fun stream" → utiliser
pump_caption(incrustation de texte visible) - "post X in pump.fun chat" → utiliser
pump_chat(panneau de chat)
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 ne gère pas sa propre pile vidéo — c'est un wrapper mince autour de LiveKit Cloud. La skill ne mine pas de pièce, ne fait pas de trading ni ne déplace de SOL ; elle n'opère que sur une pièce que l'agent possède déjà.
Prerequisites
1. The agent's coin mint
L'adresse de mint de la pièce pump.fun de l'agent doit être stockée dans le vault sous pumpfun_coin_mint. Pièce pump.fun existante d'EloPhanto :
elophanto vault set pumpfun_coin_mint BwUgJBQffm4HM49W7nsMphStJm4DbA5stuo4w7iwpump
2. Where to drop videos
L'espace de travail de l'agent dispose d'un dossier dédié pour les vidéos streamables :
<agent.workspace>/livestream_videos/
Pour EloPhanto : /Users/0xroyce/agents/elophanto/livestream_videos/
Déposez n'importe quel .mp4, .mov, .webm, etc. dans ce dossier, puis appelez l'outil avec juste le nom de fichier — pas besoin de taper le chemin complet :
{"action": "start", "video": "elephant-trailer.mp4"}
// → resolves to /Users/0xroyce/agents/elophanto/livestream_videos/elephant-trailer.mp4
Les chemins absolus fonctionnent toujours et contournent la recherche :
{"action": "start", "video": "/Users/0xroyce/Desktop/clip.mp4"}
3. System binaries
Deux binaires CLI doivent être sur PATH. Vérifiez avec :
which ffmpeg && ffmpeg -version | head -1
which lk && lk --version
Installez si manquants :
| OS | ffmpeg | lk (LiveKit CLI) |
|---|---|---|
| macOS | brew install ffmpeg |
brew install livekit-cli |
| Linux | apt-get install ffmpeg |
Télécharger depuis https://github.com/livekit/livekit-cli/releases (choisir le bon binaire lk_linux_*, chmod +x, déplacer vers /usr/local/bin/lk) |
4. Solana wallet (already in the vault)
La skill lit la paire de clés existante de l'agent à partir de solana_wallet_private_key (défini automatiquement à la création du wallet). Aucune configuration supplémentaire.
4. Vault password
Les scripts d'auth et d'orchestrateur ont tous deux besoin de VAULT_PASSWORD dans l'environnement pour déchiffrer le wallet. La session d'exécution de l'agent l'a déjà ; passez-le lors de l'invocation du script via shell_execute.
Workflow
From chat (preferred — uses the pump_livestream native tool)
L'agent appelle un outil unique avec l'une de ces actions :
{"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
L'outil lit les clés du vault directement (aucun aller-retour de var d'env) et s'exécute dans le processus Python en cours de l'agent. L'éditeur lk réel est généré en tant que sous-processus détaché afin que le chat retourne immédiatement ; sondez status pour suivre le stream.
From shell (debugging — needs VAULT_PASSWORD)
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
Cela va :
- Signer un message de connexion avec le wallet de l'agent, l'échanger contre un JWT pump.fun (mis en cache dans le vault sous
pumpfun_jwt). - POST
/livestreams/create-livestreamavec le mint (idempotent — 409 "already exists" est silencieusement toléré). - GET
/livestreams/livekit/token/hostpour un JWT LiveKit. - ffmpeg-transcode l'entrée en H.264 brut (
video.h264à côté). - Générer
lk room join --publish video.h264 --exit-after-publishen tant que sous-processus détaché. - Persister l'état du processus dans
~/.elophanto/livestream-state/<mint>.jsonafin que l'agent puisse fairestatus/stopplus tard.
Le script retourne immédiatement avec {status: "started", pid, ...}. Le stream réel s'exécute en arrière-plan jusqu'à la fin de la vidéo.
Status check
python skills/pumpfun-livestream/scripts/pump_livestream.py status <mint>
Retourne l'un de :
running— sous-processus éditeur vivant, stream en directexited— processus mort (vérifiez le champlog_filepour la sortie ffmpeg/lk)not_running— aucun enregistrement du tout
Stop a stream
python skills/pumpfun-livestream/scripts/pump_livestream.py stop <mint>
SIGTERMs l'éditeur (avec SIGKILL en secours après 3 s), supprime le .h264 transcodé (sauf si --keep-h264 a été défini au démarrage), et efface l'état.
Lower-level commands
Pour le débogage ou les flux partiels :
# 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 (défaut 30 ; inférieur = fichiers plus petits, moins de trames perdues) |
| LiveKit cluster | --livekit-url wss://... ou variable d'env LIVEKIT_URL. Par défaut wss://pump-prod-tg2x9b6r.livekit.cloud. À remplacer seulement si vous avez inspecté le frontend de pump.fun et confirmé une URL de cluster différente. |
| Keep transcoded file | --keep-h264 — utile pour la republication sans ré-encodage |
| Skip create | --skip-create — quand l'enregistrement du stream existe déjà et que vous voulez juste republier |
What's intentionally NOT included
- Audio. L'orchestrateur supprime l'audio (
-anen ffmpeg). La publication d'audio nécessite une seconde piste LiveKit et le codec doit être Opus (.ogg). Facile à ajouter plus tard : ré-exécuter ffmpeg pour produirevideo.opus, passer les deux fichiers àlk room join --publish(accepte les drapeaux--publishrépétés). - Live chat ingest. Le chat de Pump.fun est une surface API séparée (probablement un websocket sur le même hôte
frontend-api-v3.pump.fun). Pas de v1 — voir les notes de suivi ci-dessous. - Auto-restart on disconnect. Si l'éditeur LiveKit meurt mid-vidéo,
statusafficheraexitedet l'agent doit décider de redémarrer. Aucune boucle de superviseur. - Multi-coin / multi-stream concurrency. L'état est keyed par mint, donc en théorie deux mints différents peuvent streamer concurrence. Même mint deux fois = le second
startretourne{status: "already_running"}.
Live captions — pump_caption
Définir ou effacer une incrustation de texte à l'écran sur le stream du mode vocal. Le filtre drawtext de ffmpeg recharge le fichier à chaque image (~33 ms de latence) afin que la légende se mette à jour dès que l'agent l'écrit.
{"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
Associer avec le planificateur / heartbeat pour faire tourner les messages — prix tick, commerce récent, réponse FAQ, ligne de preuve déroulante. S'associe à pump_say pour que les spectateurs sans son puissent toujours lire ce que l'agent « dit ». Modo vocal uniquement — les streams en modo vidéo rendent le contenu du fichier mais ce n'est pas sur le chemin d'encodage.
Live chat — pump_chat
Le panneau de chat qui s'exécute à côté de la vidéo utilise le serveur Socket.IO livechat de Pump.fun à wss://livechat.pump.fun (chemin /socket.io/). Authentification : le même cookie JWT minted par /auth/login, passé à la fois dans l'en-tête Cookie et dans la charge utile Socket.IO auth.
L'agent appelle un outil unique depuis le chat :
{"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
Même vault, même wallet, même mint de pièce que pump_livestream — aucune configuration supplémentaire. Utilisez heartbeat ou tâches planifiées pour diffuser des messages « preuve » périodiquement ; ne bouchez pas dans des intervalles serrés. Marqué DESTRUCTIVE car les posts sont publics sous le nom de pièce de l'agent.
Common errors
| Error | Cause | Fix |
|---|---|---|
VAULT_PASSWORD env var required |
Script invoqué sans le mot de passe du vault de l'agent en env | Passer VAULT_PASSWORD=$VAULT_PASSWORD lors de l'appel via shell_execute |
Pump.fun login failed (401) |
Le format du message d'auth est rejeté | Inspecter l'onglet réseau du frontend web de pump.fun lors d'une véritable connexion ; affiner _build_message() dans pump_auth.py pour correspondre |
'ffmpeg' not found on PATH |
Binaire système manquant | Voir le tableau Prérequis ci-dessus |
'lk' not found on PATH |
Binaire système manquant | Voir le tableau Prérequis ci-dessus |
LiveKit token endpoint returned no token |
JWT incorrect ou enregistrement du stream non encore créé pour ce mint | Exécuter pump_auth.py login en premier ; puis pump_livestream.py create <mint> |
start succeeds but pump.fun shows no stream |
L'URL LiveKit par défaut ne correspond pas au cluster réel de pump.fun | Inspecter l'onglet réseau de pump.fun lors d'un stream manuel ; passer l'URL réelle via --livekit-url |
exited status with empty video on pump.fun |
ffmpeg a exécuté mais le codec/conteneur n'a pas été accepté par LiveKit | Vérifier le champ log_file de la sortie status ; habituellement un problème de codec |
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
Les deux scripts sont du Python pur, dépendent seulement de httpx, solders, base58 (déjà épinglés dans EloPhanto), et des binaires système ffmpeg + lk.
Verify
- Un appel RPC/SDK réel a été émis (mainnet, devnet ou validateur local) et la charge utile de réponse est capturée dans la transcription, pas seulement paraphrasée
- Chaque transaction a été simulée (
simulateTransactionou équivalent) avant toute étape de signature/envoi ; les journaux de simulation sont joints - Pour toute transaction signée/envoyée, la signature résultante est enregistrée et confirmée sur chain (statut retourné par
getSignatureStatusesou une URL d'explorateur) - Le slippage, les frais prioritaires et les limites d'unités de calcul ont été définis explicitement avec des valeurs numériques concrètes, non laissés aux défauts de la bibliothèque
- Les adresses de compte, les mints et les IDs de programme utilisés dans l'exécution correspondent aux adresses pumpfun-livestream documentées pour le cluster ciblé (aucun mélange mainnet/devnet)
- Le chemin d'échec a été exercé au moins une fois (solde insuffisant, oracle obsolète, blockhash expiré, etc.) et la gestion d'erreur de l'agent a produit un message lisible par l'homme