Skill Polymarket
Source : Skill Polymarket officiel depuis Polymarket/agent-skills. À tenir à jour avec le dépôt source. La section « EloPhanto Setup » ci-dessous est locale — tout le reste reflète le dépôt source.
EloPhanto Setup
Déclencheurs : « polymarket », « prediction market », « place a bet », « polygon », « CLOB », « trading bot for polymarket ».
1. Installer le SDK Python à la première utilisation
pip install py-clob-client
(À exécuter via shell_execute. Pas dans pyproject.toml par défaut — installé uniquement quand ce skill est réellement utilisé.)
2. Stocker les identifiants dans le vault (une seule fois)
vault_set polymarket_private_key VALUE # Clé privée EOA Polygon (portefeuille de financement)
vault_set polymarket_funder_address VALUE # Adresse proxy/safe depuis polymarket.com/settings (uniquement si signature_type != 0)
vault_set polymarket_signature_type 2 # 0=EOA, 1=POLY_PROXY, 2=GNOSIS_SAFE (le plus courant = 2)
3. Utiliser les identifiants en Python via vault_lookup
from py_clob_client.client import ClobClient
pk = vault_lookup("polymarket_private_key")
funder = vault_lookup("polymarket_funder_address")
sig_type = int(vault_lookup("polymarket_signature_type") or "2")
temp = ClobClient("https://clob.polymarket.com", key=pk, chain_id=137)
creds = temp.create_or_derive_api_creds()
client = ClobClient(
"https://clob.polymarket.com",
key=pk, chain_id=137,
creds=creds,
signature_type=sig_type,
funder=funder,
)
3a. Détecter automatiquement quel signature_type détient la garantie
La même polymarket_private_key peut avoir des fonds répartis sur plusieurs types de proxy (EOA, POLY_PROXY, GNOSIS_SAFE). L'interface web Polymarket affiche le portefeuille auquel vous êtes connecté ; les utilisateurs déposent régulièrement dans un (p. ex. POLY_PROXY) tandis que leur configuration vault pointe vers un autre (p. ex. GNOSIS_SAFE). Résultat : le SDK indique $0 USDC et l'ordre échoue avec « insufficient balance » ou order_version_mismatch pour des raisons qui semblent être des erreurs de code.
Testez toujours les trois avant de passer le premier ordre d'une session et utilisez celui qui est financé :
from py_clob_client.client import ClobClient
from py_clob_client.clob_types import BalanceAllowanceParams, AssetType
best_sig_type = None
best_balance_usdc = 0.0
for sig_type in (0, 1, 2):
try:
c = ClobClient(
"https://clob.polymarket.com",
key=pk, chain_id=137,
signature_type=sig_type,
funder=funder,
)
c.set_api_creds(c.create_or_derive_api_creds())
bal = c.get_balance_allowance(
BalanceAllowanceParams(
asset_type=AssetType.COLLATERAL, signature_type=sig_type
)
)
usdc = int(bal.get("balance", 0)) / 1_000_000
print(f"sig_type={sig_type}: ${usdc:.2f} USDC")
if usdc > best_balance_usdc:
best_balance_usdc, best_sig_type = usdc, sig_type
except Exception as e:
print(f"sig_type={sig_type}: probe failed ({e!r})")
if best_sig_type is None or best_balance_usdc == 0:
raise SystemExit("No funded Polymarket wallet found for this key.")
# Utilisez le sig_type financé pour le reste de la session.
client = ClobClient(
"https://clob.polymarket.com",
key=pk, chain_id=137,
signature_type=best_sig_type,
funder=funder,
)
client.set_api_creds(client.create_or_derive_api_creds())
Si le best_sig_type détecté diffère du paramètre vault, mettez à jour le vault pour que les futures sessions ne re-testent pas : vault_set polymarket_signature_type <N>.
4. Placer les ordres UNIQUEMENT via l'API. Jamais via le navigateur.
Règle stricte : tout placement d'ordre Polymarket doit se faire via py-clob-client. Ne pilotez jamais polymarket.com via les outils de navigateur pour passer une transaction. L'interface web utilise des flux Privy/wallet intégré qui ne sont pas compatibles avec le portefeuille funder stocké dans le vault — les mauvais clics placent de vrais ordres, et l'agent n'a aucun moyen de vérifier l'ordre avant de le soumettre. Si le SDK échoue, arrêtez et rapportez l'erreur exacte ; ne basculez pas vers l'interface comme secours.
5. Découvrir tick_size et neg_risk dynamiquement (ne les codez pas en dur)
create_order exige les deux options. Les deux sont par marché et les valeurs SDK / on-chain font autorité — deviner un mauvais tick_size (« 0,01 » vs « 0,001 ») rejette l'ordre avec une erreur confuse.
# Récupérer directement depuis le CLOB
tick_size = client.get_tick_size(token_id) # "0.001" / "0.01" / "0.1"
neg_risk = client.get_neg_risk(token_id) # bool
signed = client.create_order(
OrderArgs(token_id=token_id, price=price, size=size, side=BUY),
options={"tick_size": tick_size, "neg_risk": neg_risk}, # ← arg nommé, dict
)
resp = client.post_order(signed, OrderType.GTC)
Si get_neg_risk n'est pas disponible dans votre version installée de py-clob-client, lisez negRisk depuis les métadonnées du marché via gamma-api :
import requests
m = requests.get(
"https://gamma-api.polymarket.com/events",
params={"slug": EVENT_SLUG}, timeout=20,
).json()[0]["markets"]
neg_risk = next(mk for mk in m if mk["clobTokenIds"] and token_id in mk["clobTokenIds"])["negRisk"]
Le paramètre options est nommé uniquement dans les versions SDK plus récentes — le passer positivement lève TypeError. Utilisez toujours options=.
6. Garde-fous
- Toujours confirmer avec le propriétaire avant de placer des ordres impliquant de l'argent réel. Traitez l'exécution de transactions comme un niveau de permission
DESTRUCTIVE— présentez les paramètres d'ordre (token, côté, prix, taille, coût USDC) et attendez une approbation explicite. - Les opérations en lecture seule (orderbook, données de marché, positions) ne nécessitent aucune approbation.
- Les transactions Polymarket utilisent USDC.e sur Polygon. Assurez-vous que le portefeuille funder dispose d'USDC.e et d'une petite quantité de POL pour le gaz (uniquement si
signature_type=0; sans gaz via Gnosis Safe ne nécessite pas de POL). - Ne loggez jamais et ne répétez jamais
polymarket_private_key.
Quand utiliser ce skill
Utilisez ce skill quand l'utilisateur demande ou doit construire :
- Authentification API Polymarket (L1/L2, clés API, signature HMAC)
- Placement ou gestion d'ordres (limite, marché, GTC, GTD, FOK, FAK, batch, annulation)
- Lecture de données orderbook (prix, spreads, points médians, profondeur)
- Récupération de données de marché (événements, marchés, par slug, par tag, pagination)
- Souscriptions WebSocket (canal marché, canal utilisateur, sports)
- Opérations CTF (split, merge, redeem positions)
- Marchés à risque négatif (multi-résultat, conversion, risque négatif augmenté)
- Opérations de bridge (dépôts, retraits, multi-chaîne)
- Transactions sans gaz (client relayer, attribution d'ordre)
- Intégration du programme builder (attribution d'ordre, clés API, tiers)
- Utilisation du SDK Polymarket (TypeScript @polymarket/clob-client, Python py-clob-client)
Configuration API
| API | URL de base | Authentification | Objectif |
|---|---|---|---|
| CLOB | https://clob.polymarket.com |
L2 pour endpoints de trading | Orderbook, prix, soumission d'ordre |
| Gamma / Data | https://gamma-api.polymarket.com |
Aucune | Événements, marchés, recherche |
| Data API | https://data-api.polymarket.com |
Aucune | Transactions, positions, données utilisateur |
| WebSocket (Marché) | wss://ws-subscriptions-clob.polymarket.com/ws/market |
Aucune | Orderbook temps réel |
| WebSocket (Utilisateur) | wss://ws-subscriptions-clob.polymarket.com/ws/user |
Creds API dans le message | Mises à jour de transactions/ordres |
| WebSocket (Sports) | wss://sports-api.polymarket.com/ws |
Aucune | Scores en direct |
| Relayer | https://relayer-v2.polymarket.com/ |
Headers builder | Transactions sans gaz |
| Bridge | https://bridge.polymarket.com |
Aucune | Dépôts/retraits |
Adresses de contrats (Polygon)
| Contrat | Adresse |
|---|---|
| USDC (USDC.e) | 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 |
| CTF (Conditional Tokens) | 0x4D97DCd97eC945f40cF65F87097ACe5EA0476045 |
| CTF Exchange | 0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E |
| Neg Risk CTF Exchange | 0xC5d563A36AE78145C45a50134d48A1215220f80a |
| Neg Risk Adapter | 0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296 |
Configuration client
TypeScript
import { ClobClient, Side, OrderType } from "@polymarket/clob-client";
import { Wallet } from "ethers"; // v5.8.0
const HOST = "https://clob.polymarket.com";
const CHAIN_ID = 137;
const signer = new Wallet(process.env.PRIVATE_KEY);
// Étape 1 : L1 — dériver les identifiants API
const tempClient = new ClobClient(HOST, CHAIN_ID, signer);
const apiCreds = await tempClient.createOrDeriveApiKey();
// Étape 2 : L2 — initialiser le client de trading
const client = new ClobClient(
HOST,
CHAIN_ID,
signer,
apiCreds,
2, // signatureType: 0=EOA, 1=POLY_PROXY, 2=GNOSIS_SAFE
"FUNDER_ADDRESS" // adresse du portefeuille proxy depuis polymarket.com/settings
);
Python
from py_clob_client.client import ClobClient
import os
host = "https://clob.polymarket.com"
chain_id = 137
pk = os.getenv("PRIVATE_KEY")
# Étape 1 : L1 — dériver les identifiants API
temp_client = ClobClient(host, key=pk, chain_id=chain_id)
api_creds = temp_client.create_or_derive_api_creds()
# Étape 2 : L2 — initialiser le client de trading
client = ClobClient(
host,
key=pk,
chain_id=chain_id,
creds=api_creds,
signature_type=2, # 0=EOA, 1=POLY_PROXY, 2=GNOSIS_SAFE
funder="FUNDER_ADDRESS",
)
Référence rapide : Types d'ordres
| Type | Comportement | Cas d'usage |
|---|---|---|
| GTC | Reste sur le carnet jusqu'au remplissage ou annulation | Ordres limite par défaut |
| GTD | Actif jusqu'à expiration (secondes UTC). Min = now + 60 + N |
Auto-expire avant événements |
| FOK | Remplit entièrement immédiatement ou annule | Ordres marché tout ou rien |
| FAK | Remplit ce qui est disponible, annule le reste | Ordres marché partiellement remplissables |
- FOK/FAK BUY :
amount= montant en dollars à dépenser - FOK/FAK SELL :
amount= nombre de parts à vendre - Post-only : GTC/GTD uniquement — rejeté s'il croiserait le spread
Référence rapide : Types de signature
| Type | Valeur | Description |
|---|---|---|
| EOA | 0 |
Portefeuille Ethereum standard (MetaMask). Le funder est l'adresse EOA et devra avoir du POL pour le gaz. |
| POLY_PROXY | 1 |
Portefeuille proxy personnalisé pour les utilisateurs Magic Link email/Google qui ont exporté la clé privée depuis Polymarket.com. |
| GNOSIS_SAFE | 2 |
Portefeuille proxy multisig Gnosis Safe (le plus courant). À utiliser pour tout utilisateur nouveau ou récurrent. |
Motif de base : Placer un ordre
TypeScript
const response = await client.createAndPostOrder(
{
tokenID: "TOKEN_ID",
price: 0.50,
size: 10,
side: Side.BUY,
},
{
tickSize: "0.01", // depuis client.getTickSize(tokenID) ou objet marché
negRisk: false, // depuis client.getNegRisk(tokenID) ou objet marché
},
OrderType.GTC
);
console.log(response.orderID, response.status);
Python
from py_clob_client.clob_types import OrderArgs, OrderType
from py_clob_client.order_builder.constants import BUY
response = client.create_and_post_order(
OrderArgs(token_id="TOKEN_ID", price=0.50, size=10, side=BUY),
options={"tick_size": "0.01", "neg_risk": False},
order_type=OrderType.GTC,
)
print(response["orderID"], response["status"])
Motif de base : Lire l'orderbook
TypeScript
// Aucune authentification requise
const readClient = new ClobClient("https://clob.polymarket.com", 137);
const book = await readClient.getOrderBook("TOKEN_ID");
console.log("Best bid:", book.bids[0], "Best ask:", book.asks[0]);
const mid = await readClient.getMidpoint("TOKEN_ID");
const spread = await readClient.getSpread("TOKEN_ID");
Python
read_client = ClobClient("https://clob.polymarket.com", chain_id=137)
book = read_client.get_order_book("TOKEN_ID")
mid = read_client.get_midpoint("TOKEN_ID")
spread = read_client.get_spread("TOKEN_ID")
Motif de base : Souscrire via WebSocket
const ws = new WebSocket("wss://ws-subscriptions-clob.polymarket.com/ws/market");
ws.onopen = () => {
ws.send(JSON.stringify({
type: "market",
assets_ids: ["TOKEN_ID"],
custom_feature_enabled: true,
}));
// Envoyer PING tous les 10s pour garder la connexion active
setInterval(() => ws.send("PING"), 10_000);
};
ws.onmessage = (event) => {
if (event.data === "PONG") return;
const msg = JSON.parse(event.data);
// msg.event_type: "book" | "price_change" | "last_trade_price" | "tick_size_change" | "best_bid_ask" | "new_market" | "market_resolved"
};
Fichiers de référence (charger à la demande)
Lisez ces fichiers uniquement quand la tâche exige plus de détails sur un sujet spécifique :
- Authentication (L1/L2, builder headers, lifecycle des identifiants) : authentication.md
- Order patterns (GTC/GTD/FOK/FAK, tick sizes, cancel, heartbeat, errors) : order-patterns.md
- Market data (Gamma API, Data API, CLOB orderbook, subgraph) : market-data.md
- WebSocket (canaux market/user/sports, subscribe, heartbeat) : websocket.md
- CTF operations (split, merge, redeem, neg risk, token IDs) : ctf-operations.md
- Bridge (deposits, withdrawals, chaînes/tokens supportés, status) : bridge.md
- Gasless transactions (relayer client, wallet deployment, builder setup) : gasless.md
Vérifier
- Un appel RPC/SDK réel a été émis (mainnet, devnet ou validateur local) et le payload de réponse est capturé dans la transcription, pas juste paraphrasé
- Chaque transaction a été simulée (
simulateTransactionou équivalent) avant toute étape de signature/envoi ; les logs de simulation sont joints - Pour toute transaction signée/envoyée, la signature résultante est enregistrée et confirmée on-chain (status retourné par
getSignatureStatusesou URL d'explorateur) - Le slippage, la priority-fee et les limits de compute-unit ont été définis explicitement avec des valeurs numériques concrètes, pas laissés aux défauts de la bibliothèque
- Les adresses de compte, mints et IDs de programme utilisés dans la run correspondent aux adresses web3-polymarket documentées pour le cluster ciblé (pas de mélange mainnet/devnet)
- Le chemin d'erreur a été exercé au moins une fois (solde insuffisant, oracle périmé, blockhash expiré, etc.) et la gestion d'erreur de l'agent a produit un message lisible pour l'humain