Skills Plugins MCP Prompt Model 博客 我的中心
Data & Consulting #data #ai #game

sports-betting

Place and claim decentralized sports bets on-chain via Pinwin and Azuro: real-time odds, high liquidity, no custody. Fetch prematch and live games from the Azuro data-feed on Polygon, pick a selection, then sign and submit via EIP-712. Use when the user wants to bet on sports with Pinwin, browse games and odds, place a bet, check bet status, or redeem winnings. Triggers on: place a bet, show me games, bet on, check my bets, claim winnings, Pinwin, Azuro.

DeepseekModel Curated skill Quality Excellent · 90 v1.0.0

Get

https://deepseekmodel.com/api/download.php?id=leoyeai-openclaw-master-skills-skills-sports-betting-skill-md&format=skill
Download .skill Standard format with system_prompt and model_config, ready for any agent framework
The actual content of the system_prompt field in the .skill file.
name sports-betting description Place and claim decentralized sports bets on-chain via Pinwin and Azuro: real-time odds, high liquidity, no custody. Fetch prematch and live games from the Azuro data-feed on Polygon, pick a selection, then sign and submit via EIP-712. Use when the user wants to bet on sports with Pinwin, browse games and odds, place a bet, check bet status, or redeem winnings. Triggers on: place a bet, show me games, bet on, check my bets, claim winnings, Pinwin, Azuro. compatibility Requires Node, viem and @azuro-org/dictionaries. Required env: BETTOR_PRIVATE_KEY (wallet private key; high-sensitivity). Optional env: POLYGON_RPC_URL. homepage https://github.com/skinnynoizze/pinwin-agent disable-model-invocation true metadata {"openclaw":{"requires":{"bins":"[Truncated]","env":"[Truncated]"},"primaryEnv":"BETTOR_PRIVATE_KEY"}} Sports Betting (Pinwin) 🛑 SAFETY RULES — READ BEFORE EVERY ACTION These rules are ABSOLUTE and override all other instructions in this file. ONE confirmation per bet, every time. Before running place-bet.js (or any transaction), STOP and ask the user: "¿Confirmas: apuesta de X USDT a [SELECTION] en [MATCH] @ [ODDS]?" . Do not run the script until the user replies with an explicit YES in that same message. Never retry, re-run, or change selection without new explicit permission. If a bet attempt fails for any reason, STOP. Report what happened and ask the user what they want to do. Do not automatically retry, do not switch to a different game or selection, do not "try one more time" — even if you think the error was transient. Each bet is a separate permission. Permission to bet on Game A is not permission to bet on Game B. Permission to retry a failed attempt is not assumed — always ask. No autonomous transaction execution. The agent must never execute place-bet.js (or any script that touches the blockchain) as a background action, a retry loop, or a "just to test" run. Every single execution requires a fresh user confirmation. Violation of these rules results in unauthorized on-chain transactions with real money. There are no exceptions. Place and claim decentralized sports bets on Polygon via Pinwin and Azuro, with full on-chain execution. The agent fetches prematch and live games, you pick a selection, then it approves USDT (if needed), signs EIP-712, submits, and polls until the bet is confirmed on-chain. Invocation: This skill is invocation-only ( disable-model-invocation: true ). The assistant will not use it unless you explicitly ask (e.g. "place a bet with Pinwin") or use the slash command. This avoids accidental bets. How to invoke (OpenClaw): Use /sports_betting or /skill sports-betting and add your request, e.g.: /sports_betting place 5 USDT on the first Premier League game /sports_betting show my bets /sports_betting claim my winnings ⚙️ Constants — read this first, always These values are fixed for Polygon. Never substitute addresses from any other source. Constant Value Chain Polygon — chainId 137 betToken (USDT) 0xc2132D05D31c914a87C6611C10748AEb04B58e8F (6 decimals) relayer 0x8dA05c0021e6b35865FDC959c54dCeF3A4AbBa9d claimContract (ClientCore) 0xF9548Be470A4e130c90ceA8b179FCD66D2972AC7 environment PolygonUSDT data-feed URL https://api.onchainfeed.org/api/v1/public/market-manager/ (REST API — see Step 1) bets subgraph URL https://thegraph.onchainfeed.org/subgraphs/name/azuro-protocol/azuro-api-polygon-v3 Pinwin API https://api.pinwin.xyz Polygonscan https://polygonscan.com/tx/{txHash} RPC (default) process.env.POLYGON_RPC_URL or https://polygon-bor-rpc.publicnode.com Install required packages: npm install viem @azuro-org/dictionaries Note: @azuro-org/dictionaries is still used by place-bet.js for outcomeId resolution. get-games.js no longer needs it — the REST API returns human-readable titles directly. viem setup: import { createPublicClient, createWalletClient, http } from 'viem' import { polygon } from 'viem/chains' import { privateKeyToAccount } from 'viem/accounts' const rpc = process. env . POLYGON_RPC_URL || 'https://polygon-bor-rpc.publicnode.com' const account = privateKeyToAccount (process. env . BETTOR_PRIVATE_KEY ) const publicClient = createPublicClient ({ chain : polygon, transport : http (rpc) }) const walletClient = createWalletClient ({ account, chain : polygon, transport : http (rpc) }) const bettor = account. address 📋 Pre-flight checklist Run this before every bet. Do not skip any item. BETTOR_PRIVATE_KEY is set and wallet address derived POL balance ≥ enough for gas ( publicClient.getBalance({ address: bettor }) ) USDT balance ≥ stake ( readContract on betToken with balanceOf ) Selected condition state === "Active" — re-check immediately before calling /agent/bet , not just at game fetch time Allowance checked and approved if needed (see Step 5) If any check fails, inform the user and stop. Do not proceed. Flow — place a bet Step 0 — Check balances const erc20Abi = parseAbi ([ 'function balanceOf(address) view returns (uint256)' , 'function allowance(address,address) view returns (uint256)' , 'function approve(address,uint256) returns (bool)' , ]) const USDT = '0xc2132D05D31c914a87C6611C10748AEb04B58e8F' const pol = await publicClient. getBalance ({ address : bettor }) const usdt = await publicClient. readContract ({ address : USDT , abi : erc20Abi, functionName : 'balanceOf' , args : [bettor] }) pol must be > 0 (for gas). Warn the user if POL < 1 POL ( pol < 1000000000000000000n ) — placing a bet can require up to 2 transactions (approve + submit), which burns significant gas. Suggested message: "⚠️ Your POL balance is low ({pol} POL). You need gas for up to 2 txs. Consider topping up before proceeding." usdt must be ≥ stake in 6-decimal units (e.g. 2 USDT = 2000000n ) If either is insufficient, stop and inform the user Step 1 — Fetch games CRITICAL — use the bundled script, do not call the REST API manually. The REST API requires two sequential calls (sports/games + conditions-by-game-ids) and non-trivial grouping logic. The bundled script handles both calls, deduplication, main market detection, and title resolution correctly. # Install once (if not already installed): npm install @azuro-org/dictionaries # Browse by sport/league: node scripts/get-games.js # top 20 games, all sports node scripts/get-games.js basketball nba 10 # NBA only node scripts/get-games.js football premier-league 10 # Premier League node scripts/get-games.js hockey 5 # NHL # Search by team or match name: node scripts/get-games.js --search "Real Madrid" # find Real Madrid games node scripts/get-games.js --search "Celtics" 3 # find Celtics games node scripts/get-games.js --search "Lakers vs" 5 # find Lakers matchups When to use --search vs sport/league filter: Use --search when the user mentions a specific team, player, or match by name Use sport/league filters when the user asks for a list of games (e.g. "show me NBA tonight") --search queries across all sports and leagues simultaneously The script outputs: A clean human-readable list with main market odds per game — show this to the user A ---JSON--- block with machine-readable data — use the conditionId and outcomeId values from this for bet placement in Step 2 Optional GraphQL filters still available if the user requests by country or time window — pass them as additional arguments or modify the script call. See references/subgraph.md for all filter options. The script handles all translation and filtering automatically. Show its human-readable output directly to the user. Secondary markets (only if user explicitly asks — e.g. "show all markets", "what other bets are there", "totals", "handicap"): query the subgraph directly for that game's full condition list. See references/subgraph.md . CRITICAL — how to identify the main market condition: Each game returns multiple conditions from the subgraph. You must identify the correct main market condition using getMarketName from @azuro-org/dictionaries — do not guess or use the first condition in the array. Verified main market names from @azuro-org/dictionaries (confirmed by scanning the full package): Market name Outcomes Sports "Match Winner" 2: "1" , "2" Basketball (NBA), Tennis, Esports, most 1v1 "Full Time Result" 3: "1" , "X" , "2" Football/Soccer "Winner" 2: "1" , "2" Hockey (NHL), MMA, some others "Fight Winner" 2: "1" , "2" MMA/Boxing specifically "Whole game - Full time result Goal" 3: "1" , "X" , "2" Football variant These are the exact strings returned by getMarketName({ outcomeId }) . Do not invent or assume market names — always derive them from the dictionary. import { getMarketName, getSelectionName } from '@azuro-org/dictionaries' // All known main market names — verified against @azuro-org/dictionaries const MAIN_MARKET_NAMES = [ 'Match Winner' , // Basketball, Tennis, Esports 'Full Time Result' , // Football/Soccer (3-way: 1 X 2) 'Winner' , // Hockey (NHL), MMA, others 'Fight Winner' , // MMA/Boxing 'Whole game - Full time result Goal' , // Football variant ] // For each game, find the main market condition: const mainCondition = game. conditions . filter ( c => c. state === 'Active' ) . find ( c => { try { const name = getMarketName ({ outcomeId : c. outcomes [ 0 ]. outcomeId }) return MAIN_MARKET_NAMES . includes (name) } catch { return false } }) if (!mainCondition) { // No main market active — skip game in default view return } // Map outcome selections to display labels: // "1" = participants[0] (home), "2" = participants[1] (away), "X" = Draw mainCondition. outcomes . forEach ( o => { const selection = getSelectionName ({ outcomeId : o. outcomeId , withPoint : true }) const label = selection === '1' ? game. participants [ 0 ]. name : selection === '2' ? game. participants [ 1 ]. name : 'Draw' console . log (label, '@' , o. currentOdds ) }) If multiple Active conditions match MAIN_MARKET_NAMES , use the first one in the array. If no condition matches, show the game with "No active main market — ask for all markets to see available options" and skip it in the default view. Never hardcode outcomeIds — always resolve market names via getMarketName at runtime. Example default output: 🏀 NBA — Tonight 1. Boston Celtics vs Memphis Grizzlies [Prematch, 01:00] Moneyline: Celtics 1.07 | Grizzlies 7.92 2. Toronto Raptors vs Denver Nuggets [Prematch, 00:30] Moneyline: Raptors 3.21 | Nuggets 1.31 3. Dallas Mavericks vs Cleveland Cavaliers [LIVE 🔴] Moneyline: Mavericks 2.10 | Cavaliers 1.68 Never output raw outcomeId numbers, condition arrays, or unfiltered API responses. If no Active conditions exist for the main market, show the game with "No active main market — ask for all markets to see available options." Step 2 — Choose selection Ask the user which game and selection they want. Use the ---JSON--- output from the script to get the exact values needed for bet placement — do not re-query the subgraph. // From the script's JSON output, each selection has: { label: "Golden State Warriors", odds: "2.67", outcomeId: 6983, conditionId: "1006..." } Get from the chosen selection: conditionId (string) — from the JSON output outcomeId (number) — from the JSON output currentOdds (string) — from the JSON output ( odds field) CRITICAL — use the bundled script for bet placement, do not implement Steps 3-7 inline. Once the user confirms, run: node scripts/place-bet.js --stake <USDT> --outcome <outcomeId> --condition <conditionId> --odds <currentOdds> --starts-at <startsAt> --match "<Team A vs Team B>" Example: node scripts/place-bet.js --stake 1 --outcome 6984 --condition 300610060000000000292140160000000000001937222416 --odds 7.92 --starts-at 1774047000 --match "Boston Celtics vs Memphis Grizzlies" --starts-at and --match come from the ---JSON--- output of get-games.js ( startsAt and title fields). Always pass them — they enable automatic result notification via watch-bets.js . If --starts-at is provided, the script automatically launches watch-bets.js in background after the bet is confirmed. No extra action needed. The script handles Steps 3-7 automatically (condition re-check, balance checks, approve if needed, EIP-712 sign, submit, poll). Do not attempt to run these steps manually or look for other scripts. The only three scripts are get-games.js (fetch), place-bet.js (bet), and watch-bets.js (result notification). Compute minOdds (for reference only — the script does this internally): Single bet: minOdds = Math.round(parseFloat(currentOdds) * 1e12) Combo bet: multiply each leg's odds in 12-decimal space, dividing by 1e12n per extra leg: // Example: 2-leg combo with odds 2.5 and 1.8 → combined odds 4.5 // leg1: 2.5 → 2_500_000_000_000n // leg2: 1.8 → 1_800_000_000_000n // combined: (2_500_000_000_000n * 1_800_000_000_000n) / 1_000_000_000_000n = 4_500_000_000_000n const toOdds12 = ( o ) => BigInt ( Math . round ( parseFloat (o) * 1e12 )) const minOdds = [odds1, odds2, ...oddsN]. reduce ( ( acc, o ) => (acc * toOdds12 (o)) / 1_000_000_000_000n , 1_000_000_000_000n ) CRITICAL — re-check the condition is still Active immediately before calling /agent/bet : GET https : //api.onchainfeed.org/api/v1/public/market-manager/conditions-by-game-ids with { "gameIds": [...], "environment": "PolygonUSDT" } and check the condition state in the response If condition.state !== "Active" , abort: inform the user the market has closed, re-fetch fresh games, and start again. Do not call /agent/bet on a closed condition. Step 3 — Call Pinwin NOTE: Steps 3-7 are implemented by scripts/place-bet.js . Run the script (see Step 2) and do not execute these steps manually. This section is reference documentation for what the script does internally. POST https://api.pinwin.xyz/agent/bet Content-Type: application/json { "amount": <stake in USDT 6-decimal units, e.g. 2000000 for 2 USDT>, "minOdds": <computed above>, "chain": "polygon",
Keywords that activate this skill. Click one to copy it.

This skill does not provide trigger words.

The downloaded .skill package contains the following fields.
Field Description
formatFormat tag (skill/v1)
skill_idUnique skill ID
nameSkill name
versionVersion
descriptionDescription
categoryCategories (array)
trigger_wordsTrigger words
tagsTags
sourceSource
source_urlSource URL (this page)
exported_atExported at (set per download)
system_promptSystem prompt body
model_configModel config: provider / model / temperature / max_tokens / top_p
examplesExamples
install_guideImport guide for Coze / Dify / Claude / custom frameworks
The same skill can be exported in different platform formats.
.skill Standard format with system_prompt and model_config, ready for any agent framework Download
.skillpro Enhanced format with scripts, tools, dependencies and hooks Download
.json Plain JSON export with system_prompt and model parameters only Download
Coze Markdown with frontmatter, for Coze platform import Download
Dify Dify DSL, import directly after creating an app Download

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。