← 返回 Skills 市场
1615
总下载
1
收藏
0
当前安装
1
版本数
在 OpenClaw 中安装
/install crewmind-bets
功能描述
Place bets in CrewMind Arena on AI models competing in each round and claim rewards if your chosen model wins after finalization.
使用说明 (SKILL.md)
CrewMind Arena Betting Skill
TL;DR: Place bets on LLM models competing in CrewMind Arena. Bet on which AI wins each round, claim rewards if your model wins.
Quick Start
npm install @solana/web3.js @coral-xyz/anchor dotenv
Program Info
| Parameter | Value |
|---|---|
| Program ID | F5eS61Nmt3iDw8RJvvK5DL4skdKUMA637MQtG5hbht3Z |
| Network | Solana Mainnet |
| Website | https://crewmind.xyz |
Ship Index Mapping
| Index | Model |
|---|---|
| 0 | OpenAI |
| 1 | DeepSeek |
| 2 | Grok |
| 3 | Gemini |
PDA Seeds
| Account | Seeds |
|---|---|
| Config | ["config"] |
| Round | ["round", config, round_id] |
| Bet | ["bet", round, user] |
| Vault | ["vault", round] |
Instruction Discriminators
| Instruction | Discriminator (bytes) |
|---|---|
place_bet |
[222, 62, 67, 220, 63, 166, 126, 33] |
claim |
[62, 198, 214, 193, 213, 159, 108, 210] |
Account Structures
Config Account (120 bytes)
Offset Size Field
─────────────────────────────────
0 8 discriminator
8 32 admin (Pubkey)
40 32 treasury (Pubkey)
72 8 next_round_id (u64)
80 32 active_round (Pubkey) ← use this!
112 8 active_round_id (u64)
Round Account (190 bytes)
Offset Size Field
─────────────────────────────────
0 8 discriminator
8 8 id (u64)
16 1 status (u8: 0=Open, 1=Finalized)
17 1 ship_count (u8)
18 1 winner_ship (u8, 255=unset)
19 1 swept (bool)
20 8 start_ts (i64)
28 8 end_ts (i64)
36 8 finalized_ts (i64)
44 8 min_bet (u64)
52 8 max_bet (u64)
60 2 participants (u16)
62 8 total_staked (u64)
70 32 totals_by_ship ([u64; 4])
102 64 weighted_by_ship ([u128; 4])
166 8 losing_pool (u64)
174 16 total_weighted_winners (u128)
Bet Account (96 bytes)
Offset Size Field
─────────────────────────────────
0 8 discriminator
8 1 initialized (bool)
9 32 round (Pubkey)
41 32 user (Pubkey)
73 1 ship (u8)
74 1 claimed (bool)
75 6 _pad
81 8 total_amount (u64)
89 16 total_weighted (u128)
Entrypoint: place_bet
Goal
Place a bet on a ship (AI model) in the active round.
Instruction
place_bet(ship: u8, amount: u64)
Accounts (in order)
| # | Account | Signer | Writable | Description |
|---|---|---|---|---|
| 0 | user | ✓ | ✓ | Your wallet |
| 1 | config | PDA ["config"] |
||
| 2 | round | ✓ | Active round pubkey from config | |
| 3 | bet | ✓ | PDA ["bet", round, user] |
|
| 4 | vault | ✓ | PDA ["vault", round] |
|
| 5 | system_program | 11111111111111111111111111111111 |
Constraints
ship \x3C ship_count(usually 4)min_bet \x3C= amount \x3C= max_betcurrent_time \x3C end_ts- Round status must be
Open(0)
Instruction Data Layout
Bytes 0-7: discriminator [222, 62, 67, 220, 63, 166, 126, 33]
Byte 8: ship (u8)
Bytes 9-16: amount (u64 LE)
Entrypoint: claim
Goal
Claim rewards after round finalization (if your ship won).
Instruction
claim() — no arguments
Accounts (in order)
| # | Account | Signer | Writable | Description |
|---|---|---|---|---|
| 0 | user | ✓ | ✓ | Your wallet |
| 1 | round | The finalized round | ||
| 2 | bet | ✓ | PDA ["bet", round, user] |
|
| 3 | vault | ✓ | PDA ["vault", round] |
|
| 4 | system_program | 11111111111111111111111111111111 |
Constraints
- Round status must be
Finalized(1) - Your bet's
ship == winner_ship claimed == false
Instruction Data Layout
Bytes 0-7: discriminator [62, 198, 214, 193, 213, 159, 108, 210]
Errors
| Code | Name | Description |
|---|---|---|
| 6004 | InvalidShip | Ship index >= ship_count |
| 6005 | RoundNotOpen | Round is finalized |
| 6006 | RoundEnded | Past end_ts |
| 6008 | RoundNotFinalized | Can't claim yet |
| 6009 | TooLate | Too late to bet |
| 6011 | InvalidBetAmount | Amount out of bounds |
| 6014 | AlreadyClaimed | Already claimed |
| 6015 | NotAWinner | Your ship didn't win |
Complete JavaScript Example
import { Connection, PublicKey, Keypair, Transaction, TransactionInstruction, SystemProgram } from '@solana/web3.js';
const PROGRAM_ID = new PublicKey('F5eS61Nmt3iDw8RJvvK5DL4skdKUMA637MQtG5hbht3Z');
const SHIPS = { openai: 0, deepseek: 1, grok: 2, gemini: 3 };
async function getActiveRound(connection) {
const [configPda] = PublicKey.findProgramAddressSync([Buffer.from('config')], PROGRAM_ID);
const configAccount = await connection.getAccountInfo(configPda);
if (!configAccount) throw new Error('Config not found');
const activeRound = new PublicKey(configAccount.data.slice(80, 112));
if (activeRound.equals(PublicKey.default)) throw new Error('No active round');
return { configPda, activeRound };
}
async function getRoundInfo(connection, roundPubkey) {
const acc = await connection.getAccountInfo(roundPubkey);
if (!acc) throw new Error('Round not found');
const d = acc.data;
return {
id: d.readBigUInt64LE(8),
status: d.readUInt8(16), // 0=Open, 1=Finalized
shipCount: d.readUInt8(17),
winnerShip: d.readUInt8(18), // 255 if not set
startTs: d.readBigInt64LE(20),
endTs: d.readBigInt64LE(28),
minBet: d.readBigUInt64LE(44),
maxBet: d.readBigUInt64LE(52),
};
}
async function placeBet(connection, wallet, shipName, amountSol) {
const ship = SHIPS[shipName.toLowerCase()];
const amountLamports = BigInt(Math.floor(amountSol * 1e9));
const { configPda, activeRound } = await getActiveRound(connection);
const roundInfo = await getRoundInfo(connection, activeRound);
// Validations
if (roundInfo.status !== 0) throw new Error('Round not open');
if (BigInt(Date.now() / 1000) >= roundInfo.endTs) throw new Error('Round ended');
if (amountLamports \x3C roundInfo.minBet || amountLamports > roundInfo.maxBet) {
throw new Error(`Amount must be between ${Number(roundInfo.minBet)/1e9} and ${Number(roundInfo.maxBet)/1e9} SOL`);
}
const [betPda] = PublicKey.findProgramAddressSync(
[Buffer.from('bet'), activeRound.toBuffer(), wallet.publicKey.toBuffer()], PROGRAM_ID
);
const [vaultPda] = PublicKey.findProgramAddressSync(
[Buffer.from('vault'), activeRound.toBuffer()], PROGRAM_ID
);
const data = Buffer.concat([
Buffer.from([222, 62, 67, 220, 63, 166, 126, 33]), // discriminator
Buffer.from([ship]), // ship u8
(() => { const b = Buffer.alloc(8); b.writeBigUInt64LE(amountLamports); return b; })()
]);
const ix = new TransactionInstruction({
keys: [
{ pubkey: wallet.publicKey, isSigner: true, isWritable: true },
{ pubkey: configPda, isSigner: false, isWritable: false },
{ pubkey: activeRound, isSigner: false, isWritable: true },
{ pubkey: betPda, isSigner: false, isWritable: true },
{ pubkey: vaultPda, isSigner: false, isWritable: true },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
],
programId: PROGRAM_ID,
data,
});
const tx = new Transaction().add(ix);
tx.feePayer = wallet.publicKey;
tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
tx.sign(wallet);
return await connection.sendRawTransaction(tx.serialize());
}
async function claim(connection, wallet, roundPubkey) {
const roundInfo = await getRoundInfo(connection, roundPubkey);
if (roundInfo.status !== 1) throw new Error('Round not finalized yet');
const [betPda] = PublicKey.findProgramAddressSync(
[Buffer.from('bet'), roundPubkey.toBuffer(), wallet.publicKey.toBuffer()], PROGRAM_ID
);
const [vaultPda] = PublicKey.findProgramAddressSync(
[Buffer.from('vault'), roundPubkey.toBuffer()], PROGRAM_ID
);
const data = Buffer.from([62, 198, 214, 193, 213, 159, 108, 210]); // claim discriminator
const ix = new TransactionInstruction({
keys: [
{ pubkey: wallet.publicKey, isSigner: true, isWritable: true },
{ pubkey: roundPubkey, isSigner: false, isWritable: false },
{ pubkey: betPda, isSigner: false, isWritable: true },
{ pubkey: vaultPda, isSigner: false, isWritable: true },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
],
programId: PROGRAM_ID,
data,
});
const tx = new Transaction().add(ix);
tx.feePayer = wallet.publicKey;
tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
tx.sign(wallet);
return await connection.sendRawTransaction(tx.serialize());
}
// Usage:
// const connection = new Connection('https://api.mainnet-beta.solana.com', 'confirmed');
// const wallet = Keypair.fromSecretKey(...);
// await placeBet(connection, wallet, 'deepseek', 0.01);
Workflow Summary
1. GET ACTIVE ROUND
└─> Read Config PDA → get active_round pubkey
2. CHECK ROUND STATUS
└─> Read Round account → verify status=0 (Open), check end_ts
3. PLACE BET
└─> Call place_bet(ship, amount)
└─> Creates Bet PDA, transfers SOL to Vault
4. WAIT FOR ROUND TO END
└─> Monitor: current_time > end_ts
5. WAIT FOR FINALIZATION
└─> Monitor: Round.status == 1 (Finalized)
└─> Check: Round.winner_ship
6. CLAIM (if won)
└─> Call claim() if your ship == winner_ship
└─> Receives: original_bet + share_of_losing_pool
Safety Rules
- Never bet more than
max_bet - Check
end_tsbefore betting (avoid TooLate error) - Only one bet per round per user (but can add to existing bet)
- Always verify round is
Openbefore betting - Always verify round is
Finalizedbefore claiming - Keep SOL for transaction fees (~0.002 SOL recommended buffer)
安全使用建议
This skill appears to be a documentation/JS client for placing bets on a Solana program and is internally consistent, but proceed cautiously. Before installing or running anything: 1) Verify the Program ID and contract on a trusted Solana explorer and the crewmind.xyz site (the skill could point to a malicious program). 2) Never paste private keys into .env files or into an agent UI — use a wallet adapter or hardware wallet to sign transactions when possible. 3) Confirm who will provide the signer: the skill metadata declares no credential, so you must supply a wallet; understand where that key is stored and who/what can access it. 4) If you will run the example code locally, inspect it fully (the SKILL.md is truncated) and run it first against devnet/testnet with tiny amounts. 5) Because there is no packaged code to audit, treat this as documentation only — the runtime behavior depends on code you or the agent executes. If you need higher assurance, request the program's source/IDL and verify on-chain deployment and audits before committing funds.
功能分析
Type: OpenClaw Skill
Name: crewmind-bets
Version: 1.0.0
The OpenClaw skill bundle describes and provides example JavaScript code for interacting with a Solana smart contract for betting on LLM model competitions. The `SKILL.md` file details the program, account structures, and entry points (`place_bet`, `claim`), along with a complete JavaScript example. The code uses standard Solana SDK functions to construct and send transactions to the Solana blockchain. There is no evidence of data exfiltration, malicious execution, persistence mechanisms, or prompt injection attempts against the agent. The `npm install` command lists standard development dependencies, and the JavaScript example correctly handles wallet interactions without attempting to access sensitive local data.
能力评估
Purpose & Capability
SKILL.md clearly documents placing bets and claiming rewards on a Solana program (program ID, PDAs, instruction layouts, account schemas and example JS). That aligns with a 'arena betting' purpose. However the skill metadata contains no description and declares no credentials even though the documented actions require a signing wallet.
Instruction Scope
The runtime instructions stay focused on on-chain interactions (derive PDAs, build and submit transactions, validate account fields). They do not instruct reading unrelated system files or exfiltrating data. The doc references npm packages and dotenv, which is expected for a JS client.
Install Mechanism
This is an instruction-only skill with no install spec or bundled code. The Quick Start suggests npm packages (@solana/web3.js, @coral-xyz/anchor, dotenv) — reasonable for a JS Solana client and not itself suspicious.
Credentials
The documented operations require a signing wallet (Keypair/wallet provider) and likely RPC configuration (dotenv), but the skill metadata declares no required env vars or primary credential. That omission is a proportionality/information gap: to actually place bets the agent or user must supply private keys or a wallet signer — exposing private keys in .env or to an agent is high risk. The SKILL.md does not instruct how to securely provide keys or which runtime will provide a signer.
Persistence & Privilege
The skill is not always-enabled and requests no persistent system-wide privileges or config changes. As an instruction-only guide it does not attempt to modify other skills or agent settings.
如何使用
- 确保已安装 OpenClaw(本地或 Docker 部署)
- 在对话框中输入安装命令:
/install crewmind-bets - 安装完成后,直接呼叫该 Skill 的名称或使用
/crewmind-bets触发 - 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v1.0.0
CrewMind Arena Betting Skill 1.0.0
- Initial release: bet on the outcome of LLM (AI) competitions in CrewMind Arena.
- Supports betting on OpenAI, DeepSeek, Grok, or Gemini models for each round.
- Claim rewards if your selected model wins after round finalization.
- Provides detailed Solana program info, JS usage examples, account structures, and instruction layouts.
- Outlines error codes and program constraints for robust user experience.
元数据
常见问题
CrewMind.xyz Arena Betting 是什么?
Place bets in CrewMind Arena on AI models competing in each round and claim rewards if your chosen model wins after finalization. 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 1615 次。
如何安装 CrewMind.xyz Arena Betting?
在 OpenClaw 或 Claude Code 对话框中运行命令「/install crewmind-bets」即可一键安装,无需额外配置。
CrewMind.xyz Arena Betting 是免费的吗?
是的,CrewMind.xyz Arena Betting 完全免费(开源免费),可自由下载、安装和使用。
CrewMind.xyz Arena Betting 支持哪些平台?
CrewMind.xyz Arena Betting 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。
谁开发了 CrewMind.xyz Arena Betting?
由 Vlad(@vladthecto)开发并维护,当前版本 v1.0.0。
推荐 Skills